From: John Marino Date: Tue, 31 Mar 2015 16:29:14 +0000 (+0200) Subject: Remove unused Binutils 2.22 source files X-Git-Tag: v4.2.0rc~421 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/7ee5cb2430beb68fee54ac99ddfb1bc56c6ca370 Remove unused Binutils 2.22 source files --- diff --git a/contrib/binutils-2.22/COPYING b/contrib/binutils-2.22/COPYING deleted file mode 100644 index 623b6258a1..0000000000 --- a/contrib/binutils-2.22/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - 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 Library 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 Library General -Public License instead of this License. diff --git a/contrib/binutils-2.22/COPYING.LIB b/contrib/binutils-2.22/COPYING.LIB deleted file mode 100644 index 778d0bb5b2..0000000000 --- a/contrib/binutils-2.22/COPYING.LIB +++ /dev/null @@ -1,482 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 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. - -[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 - - Appendix: 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 - 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 --git a/contrib/binutils-2.22/COPYING3 b/contrib/binutils-2.22/COPYING3 deleted file mode 100644 index 94a9ed024d..0000000000 --- a/contrib/binutils-2.22/COPYING3 +++ /dev/null @@ -1,674 +0,0 @@ - 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 --git a/contrib/binutils-2.22/COPYING3.LIB b/contrib/binutils-2.22/COPYING3.LIB deleted file mode 100644 index fc8a5de7ed..0000000000 --- a/contrib/binutils-2.22/COPYING3.LIB +++ /dev/null @@ -1,165 +0,0 @@ - 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 --git a/contrib/binutils-2.22/README b/contrib/binutils-2.22/README deleted file mode 100644 index eb0e436d86..0000000000 --- a/contrib/binutils-2.22/README +++ /dev/null @@ -1,47 +0,0 @@ - README for GNU development tools - -This directory contains various GNU compilers, assemblers, linkers, -debuggers, etc., plus their support routines, definitions, and documentation. - -If you are receiving this as part of a GDB release, see the file gdb/README. -If with a binutils release, see binutils/README; if with a libg++ release, -see libg++/README, etc. That'll give you info about this -package -- supported targets, how to use it, how to report bugs, etc. - -It is now possible to automatically configure and build a variety of -tools with one command. To build all of the tools contained herein, -run the ``configure'' script here, e.g.: - - ./configure - make - -To install them (by default in /usr/local/bin, /usr/local/lib, etc), -then do: - make install - -(If the configure script can't determine your type of computer, give it -the name as an argument, for instance ``./configure sun4''. You can -use the script ``config.sub'' to test whether a name is recognized; if -it is, config.sub translates it to a triplet specifying CPU, vendor, -and OS.) - -If you have more than one compiler on your system, it is often best to -explicitly set CC in the environment before running configure, and to -also set CC when running make. For example (assuming sh/bash/ksh): - - CC=gcc ./configure - make - -A similar example using csh: - - setenv CC gcc - ./configure - make - -Much of the code and documentation enclosed is copyright by -the Free Software Foundation, Inc. See the file COPYING or -COPYING.LIB in the various directories, for a description of the -GNU General Public License terms under which you can copy the files. - -REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info -on where and how to report problems. diff --git a/contrib/binutils-2.22/README.DELETED b/contrib/binutils-2.22/README.DELETED deleted file mode 100644 index 0420095a20..0000000000 --- a/contrib/binutils-2.22/README.DELETED +++ /dev/null @@ -1,1790 +0,0 @@ -ChangeLog -MAINTAINERS -Makefile.def -Makefile.in -Makefile.tpl -README-maintainer-mode -bfd/.gitignore -bfd/ChangeLog -bfd/ChangeLog-0001 -bfd/ChangeLog-0203 -bfd/ChangeLog-2004 -bfd/ChangeLog-2005 -bfd/ChangeLog-2006 -bfd/ChangeLog-2007 -bfd/ChangeLog-2008 -bfd/ChangeLog-2009 -bfd/ChangeLog-2010 -bfd/ChangeLog-9193 -bfd/ChangeLog-9495 -bfd/ChangeLog-9697 -bfd/ChangeLog-9899 -bfd/MAINTAINERS -bfd/Makefile.am -bfd/Makefile.in -bfd/PORTING -bfd/TODO -bfd/acinclude.m4 -bfd/aclocal.m4 -bfd/aix386-core.c -bfd/aix5ppc-core.c -bfd/aout-adobe.c -bfd/aout-arm.c -bfd/aout-cris.c -bfd/aout-ns32k.c -bfd/aout-sparcle.c -bfd/aout-target.h -bfd/aout-tic30.c -bfd/aout0.c -bfd/aout32.c -bfd/aout64.c -bfd/aoutf1.h -bfd/aoutx.h -bfd/armnetbsd.c -bfd/bfd-in.h -bfd/bfd.m4 -bfd/bout.c -bfd/cf-i386lynx.c -bfd/cf-sparclynx.c -bfd/cisco-core.c -bfd/coff-alpha.c -bfd/coff-apollo.c -bfd/coff-arm.c -bfd/coff-aux.c -bfd/coff-go32.c -bfd/coff-h8300.c -bfd/coff-h8500.c -bfd/coff-i386.c -bfd/coff-i860.c -bfd/coff-i960.c -bfd/coff-ia64.c -bfd/coff-m68k.c -bfd/coff-m88k.c -bfd/coff-mcore.c -bfd/coff-mips.c -bfd/coff-or32.c -bfd/coff-ppc.c -bfd/coff-rs6000.c -bfd/coff-sh.c -bfd/coff-sparc.c -bfd/coff-stgo32.c -bfd/coff-svm68k.c -bfd/coff-tic30.c -bfd/coff-tic4x.c -bfd/coff-tic54x.c -bfd/coff-tic80.c -bfd/coff-u68k.c -bfd/coff-w65.c -bfd/coff-we32k.c -bfd/coff-x86_64.c -bfd/coff-z80.c -bfd/coff-z8k.c -bfd/coff64-rs6000.c -bfd/coffcode.h -bfd/cofflink.c -bfd/coffswap.h -bfd/config.in -bfd/configure -bfd/configure.com -bfd/configure.host -bfd/configure.in -bfd/cpu-alpha.c -bfd/cpu-arc.c -bfd/cpu-arm.c -bfd/cpu-avr.c -bfd/cpu-bfin.c -bfd/cpu-cr16.c -bfd/cpu-cr16c.c -bfd/cpu-cris.c -bfd/cpu-crx.c -bfd/cpu-d10v.c -bfd/cpu-d30v.c -bfd/cpu-dlx.c -bfd/cpu-fr30.c -bfd/cpu-frv.c -bfd/cpu-h8300.c -bfd/cpu-h8500.c -bfd/cpu-hppa.c -bfd/cpu-i370.c -bfd/cpu-i860.c -bfd/cpu-i960.c -bfd/cpu-ia64-opc.c -bfd/cpu-ia64.c -bfd/cpu-ip2k.c -bfd/cpu-iq2000.c -bfd/cpu-k1om.c -bfd/cpu-lm32.c -bfd/cpu-m10200.c -bfd/cpu-m10300.c -bfd/cpu-m32c.c -bfd/cpu-m32r.c -bfd/cpu-m68hc11.c -bfd/cpu-m68hc12.c -bfd/cpu-m68k.c -bfd/cpu-m88k.c -bfd/cpu-mcore.c -bfd/cpu-mep.c -bfd/cpu-microblaze.c -bfd/cpu-mips.c -bfd/cpu-mmix.c -bfd/cpu-moxie.c -bfd/cpu-msp430.c -bfd/cpu-mt.c -bfd/cpu-ns32k.c -bfd/cpu-openrisc.c -bfd/cpu-or32.c -bfd/cpu-pdp11.c -bfd/cpu-pj.c -bfd/cpu-plugin.c -bfd/cpu-powerpc.c -bfd/cpu-rs6000.c -bfd/cpu-rx.c -bfd/cpu-s390.c -bfd/cpu-score.c -bfd/cpu-sh.c -bfd/cpu-sparc.c -bfd/cpu-spu.c -bfd/cpu-tic30.c -bfd/cpu-tic4x.c -bfd/cpu-tic54x.c -bfd/cpu-tic6x.c -bfd/cpu-tic80.c -bfd/cpu-tilegx.c -bfd/cpu-tilepro.c -bfd/cpu-v850.c -bfd/cpu-vax.c -bfd/cpu-w65.c -bfd/cpu-we32k.c -bfd/cpu-xc16x.c -bfd/cpu-xstormy16.c -bfd/cpu-xtensa.c -bfd/cpu-z80.c -bfd/cpu-z8k.c -bfd/demo64.c -bfd/dep-in.sed -bfd/doc/ChangeLog -bfd/doc/ChangeLog-9103 -bfd/doc/Makefile.am -bfd/doc/Makefile.in -bfd/doc/aoutx.texi -bfd/doc/archive.texi -bfd/doc/archures.texi -bfd/doc/bfd.info -bfd/doc/bfd.texinfo -bfd/doc/bfdint.texi -bfd/doc/bfdio.texi -bfd/doc/bfdt.texi -bfd/doc/bfdwin.texi -bfd/doc/cache.texi -bfd/doc/chew.c -bfd/doc/coffcode.texi -bfd/doc/core.texi -bfd/doc/doc.str -bfd/doc/elf.texi -bfd/doc/elfcode.texi -bfd/doc/fdl.texi -bfd/doc/format.texi -bfd/doc/hash.texi -bfd/doc/header.sed -bfd/doc/init.texi -bfd/doc/libbfd.texi -bfd/doc/linker.texi -bfd/doc/makefile.vms -bfd/doc/mmo.texi -bfd/doc/opncls.texi -bfd/doc/proto.str -bfd/doc/reloc.texi -bfd/doc/section.texi -bfd/doc/syms.texi -bfd/doc/targets.texi -bfd/ecoff.c -bfd/ecofflink.c -bfd/ecoffswap.h -bfd/elf-hppa.h -bfd/elf-m10200.c -bfd/elf-m10300.c -bfd/elf32-am33lin.c -bfd/elf32-arc.c -bfd/elf32-arm.c -bfd/elf32-avr.c -bfd/elf32-avr.h -bfd/elf32-bfin.c -bfd/elf32-cr16.c -bfd/elf32-cr16c.c -bfd/elf32-cris.c -bfd/elf32-crx.c -bfd/elf32-d10v.c -bfd/elf32-d30v.c -bfd/elf32-dlx.c -bfd/elf32-fr30.c -bfd/elf32-frv.c -bfd/elf32-h8300.c -bfd/elf32-hppa.c -bfd/elf32-hppa.h -bfd/elf32-i370.c -bfd/elf32-i860.c -bfd/elf32-i960.c -bfd/elf32-ip2k.c -bfd/elf32-iq2000.c -bfd/elf32-lm32.c -bfd/elf32-m32c.c -bfd/elf32-m32r.c -bfd/elf32-m68hc11.c -bfd/elf32-m68hc12.c -bfd/elf32-m68hc1x.c -bfd/elf32-m68hc1x.h -bfd/elf32-m68k.c -bfd/elf32-m88k.c -bfd/elf32-mcore.c -bfd/elf32-mep.c -bfd/elf32-microblaze.c -bfd/elf32-mips.c -bfd/elf32-moxie.c -bfd/elf32-msp430.c -bfd/elf32-mt.c -bfd/elf32-openrisc.c -bfd/elf32-or32.c -bfd/elf32-pj.c -bfd/elf32-ppc.c -bfd/elf32-ppc.h -bfd/elf32-rx.c -bfd/elf32-s390.c -bfd/elf32-score.c -bfd/elf32-score.h -bfd/elf32-score7.c -bfd/elf32-sh-relocs.h -bfd/elf32-sh-symbian.c -bfd/elf32-sh.c -bfd/elf32-sh64-com.c -bfd/elf32-sh64.c -bfd/elf32-sh64.h -bfd/elf32-sparc.c -bfd/elf32-spu.c -bfd/elf32-spu.h -bfd/elf32-tic6x.c -bfd/elf32-tic6x.h -bfd/elf32-tilegx.c -bfd/elf32-tilegx.h -bfd/elf32-tilepro.c -bfd/elf32-tilepro.h -bfd/elf32-v850.c -bfd/elf32-vax.c -bfd/elf32-xc16x.c -bfd/elf32-xstormy16.c -bfd/elf32-xtensa.c -bfd/elf64-alpha.c -bfd/elf64-hppa.c -bfd/elf64-hppa.h -bfd/elf64-mips.c -bfd/elf64-mmix.c -bfd/elf64-ppc.c -bfd/elf64-ppc.h -bfd/elf64-tilegx.c -bfd/elf64-tilegx.h -bfd/elf64-s390.c -bfd/elf64-sh64.c -bfd/elf64-sparc.c -bfd/elfn32-mips.c -bfd/elfnn-ia64.c -bfd/elfxx-ia64.c -bfd/elfxx-ia64.h -bfd/elfxx-mips.c -bfd/elfxx-mips.h -bfd/elfxx-sparc.c -bfd/elfxx-sparc.h -bfd/elfxx-tilegx.c -bfd/elfxx-tilegx.h -bfd/epoc-pe-arm.c -bfd/epoc-pei-arm.c -bfd/freebsd.h -bfd/gen-aout.c -bfd/go32stub.h -bfd/host-aout.c -bfd/hosts/ -bfd/hp300bsd.c -bfd/hp300hpux.c -bfd/hppabsd-core.c -bfd/hpux-core.c -bfd/i386aout.c -bfd/i386bsd.c -bfd/i386dynix.c -bfd/i386freebsd.c -bfd/i386linux.c -bfd/i386lynx.c -bfd/i386mach3.c -bfd/i386msdos.c -bfd/i386netbsd.c -bfd/i386os9k.c -bfd/ieee.c -bfd/irix-core.c -bfd/libbfd-in.h -bfd/libcoff-in.h -bfd/libhppa.h -bfd/libieee.h -bfd/libnlm.h -bfd/liboasys.h -bfd/libpei.h -bfd/libxcoff.h -bfd/lynx-core.c -bfd/m68k4knetbsd.c -bfd/m68klinux.c -bfd/m68knetbsd.c -bfd/m88kmach3.c -bfd/m88kopenbsd.c -bfd/mach-o-i386.c -bfd/mach-o-target.c -bfd/mach-o-x86-64.c -bfd/mach-o.c -bfd/mach-o.h -bfd/makefile.vms -bfd/mep-relocs.pl -bfd/mipsbsd.c -bfd/mmo.c -bfd/netbsd-core.c -bfd/netbsd.h -bfd/newsos3.c -bfd/nlm-target.h -bfd/nlm.c -bfd/nlm32-alpha.c -bfd/nlm32-i386.c -bfd/nlm32-ppc.c -bfd/nlm32-sparc.c -bfd/nlm32.c -bfd/nlm64.c -bfd/nlmcode.h -bfd/nlmswap.h -bfd/ns32k.h -bfd/ns32knetbsd.c -bfd/oasys.c -bfd/osf-core.c -bfd/pc532-mach.c -bfd/pdp11.c -bfd/pe-arm-wince.c -bfd/pe-arm.c -bfd/pe-i386.c -bfd/pe-mcore.c -bfd/pe-mips.c -bfd/pe-ppc.c -bfd/pe-sh.c -bfd/pe-x86_64.c -bfd/peXXigen.c -bfd/pef-traceback.h -bfd/pef.c -bfd/pef.h -bfd/pei-arm-wince.c -bfd/pei-arm.c -bfd/pei-i386.c -bfd/pei-ia64.c -bfd/pei-mcore.c -bfd/pei-mips.c -bfd/pei-ppc.c -bfd/pei-sh.c -bfd/pei-x86_64.c -bfd/peicode.h -bfd/plugin.c -bfd/po/ -bfd/ppcboot.c -bfd/ptrace-core.c -bfd/reloc16.c -bfd/riscix.c -bfd/rs6000-core.c -bfd/sco5-core.c -bfd/som.c -bfd/som.h -bfd/sparclinux.c -bfd/sparclynx.c -bfd/sparcnetbsd.c -bfd/stamp-h.in -bfd/sunos.c -bfd/ticoff.h -bfd/trad-core.c -bfd/vax1knetbsd.c -bfd/vaxbsd.c -bfd/vaxnetbsd.c -bfd/versados.c -bfd/vms-alpha.c -bfd/vms-lib.c -bfd/vms-misc.c -bfd/vms.h -bfd/warning.m4 -bfd/xcofflink.c -bfd/xsym.c -bfd/xsym.h -bfd/xtensa-isa.c -bfd/xtensa-modules.c -binutils/.gitignore -binutils/BRANCHES -binutils/ChangeLog -binutils/ChangeLog-0001 -binutils/ChangeLog-0203 -binutils/ChangeLog-2004 -binutils/ChangeLog-2005 -binutils/ChangeLog-2006 -binutils/ChangeLog-2007 -binutils/ChangeLog-2008 -binutils/ChangeLog-2009 -binutils/ChangeLog-2010 -binutils/ChangeLog-9197 -binutils/ChangeLog-9899 -binutils/MAINTAINERS -binutils/Makefile.am -binutils/Makefile.in -binutils/NEWS -binutils/aclocal.m4 -binutils/arlex.c -binutils/arparse.c -binutils/arparse.h -binutils/bin2c.c -binutils/coffdump.c -binutils/coffgrok.c -binutils/coffgrok.h -binutils/config.in -binutils/configure -binutils/configure.com -binutils/configure.in -binutils/configure.tgt -binutils/deflex.c -binutils/deflex.l -binutils/defparse.c -binutils/defparse.h -binutils/defparse.y -binutils/dep-in.sed -binutils/dlltool.c -binutils/dlltool.h -binutils/dllwrap.c -binutils/doc/binutils.info -binutils/doc/cxxfilt.man -binutils/doc/dlltool.1 -binutils/doc/nlmconv.1 -binutils/doc/windmc.1 -binutils/doc/windres.1 -binutils/embedspu.sh -binutils/emul_aix.c -binutils/makefile.vms -binutils/maybe-ranlib.c -binutils/maybe-strip.c -binutils/mclex.c -binutils/mcparse.c -binutils/mcparse.h -binutils/mcparse.y -binutils/nlmconv.c -binutils/nlmconv.h -binutils/nlmheader.c -binutils/nlmheader.h -binutils/nlmheader.y -binutils/po/ -binutils/ranlib.sh -binutils/rclex.c -binutils/rcparse.c -binutils/rcparse.h -binutils/rcparse.y -binutils/resbin.c -binutils/rescoff.c -binutils/resrc.c -binutils/resres.c -binutils/sanity.sh -binutils/srconv.c -binutils/stamp-h.in -binutils/sysdump.c -binutils/sysinfo.c -binutils/sysinfo.h -binutils/sysinfo.y -binutils/syslex.c -binutils/syslex.l -binutils/sysroff.info -binutils/testsuite/ -binutils/windint.h -binutils/windmc.c -binutils/windmc.h -binutils/windres.c -binutils/windres.h -binutils/winduni.c -binutils/winduni.h -compile -config-ml.in -config.guess -config.rpath -config.sub -config/ -configure -configure.ac -cpu/ -depcomp -elfcpp/ChangeLog -etc/ -gas/.gitignore -gas/CONTRIBUTORS -gas/ChangeLog -gas/ChangeLog-0001 -gas/ChangeLog-0203 -gas/ChangeLog-2004 -gas/ChangeLog-2005 -gas/ChangeLog-2006 -gas/ChangeLog-2007 -gas/ChangeLog-2008 -gas/ChangeLog-2009 -gas/ChangeLog-2010 -gas/ChangeLog-9295 -gas/ChangeLog-9697 -gas/ChangeLog-9899 -gas/MAINTAINERS -gas/Makefile.am -gas/Makefile.in -gas/NEWS -gas/acinclude.m4 -gas/aclocal.m4 -gas/bfin-lex.c -gas/bfin-parse.c -gas/bfin-parse.h -gas/cgen.c -gas/cgen.h -gas/config.in -gas/config/aout_gnu.h -gas/config/atof-vax.c -gas/config/bfin-aux.h -gas/config/bfin-defs.h -gas/config/bfin-lex.l -gas/config/bfin-parse.y -gas/config/e-crisaout.c -gas/config/e-criself.c -gas/config/e-i386aout.c -gas/config/e-i386coff.c -gas/config/e-i386elf.c -gas/config/e-mipsecoff.c -gas/config/e-mipself.c -gas/config/itbl-mips.h -gas/config/m68k-parse.h -gas/config/m68k-parse.y -gas/config/obj-aout.c -gas/config/obj-aout.h -gas/config/obj-coff-seh.c -gas/config/obj-coff-seh.h -gas/config/obj-coff.c -gas/config/obj-coff.h -gas/config/obj-ecoff.c -gas/config/obj-ecoff.h -gas/config/obj-evax.c -gas/config/obj-evax.h -gas/config/obj-fdpicelf.c -gas/config/obj-fdpicelf.h -gas/config/obj-macho.c -gas/config/obj-macho.h -gas/config/obj-multi.c -gas/config/obj-multi.h -gas/config/obj-som.c -gas/config/obj-som.h -gas/config/rx-defs.h -gas/config/rx-parse.y -gas/config/tc-alpha.c -gas/config/tc-alpha.h -gas/config/tc-arc.c -gas/config/tc-arc.h -gas/config/tc-arm.c -gas/config/tc-arm.h -gas/config/tc-avr.c -gas/config/tc-avr.h -gas/config/tc-bfin.c -gas/config/tc-bfin.h -gas/config/tc-cr16.c -gas/config/tc-cr16.h -gas/config/tc-cris.c -gas/config/tc-cris.h -gas/config/tc-crx.c -gas/config/tc-crx.h -gas/config/tc-d10v.c -gas/config/tc-d10v.h -gas/config/tc-d30v.c -gas/config/tc-d30v.h -gas/config/tc-dlx.c -gas/config/tc-dlx.h -gas/config/tc-fr30.c -gas/config/tc-fr30.h -gas/config/tc-frv.c -gas/config/tc-frv.h -gas/config/tc-generic.c -gas/config/tc-generic.h -gas/config/tc-h8300.c -gas/config/tc-h8300.h -gas/config/tc-hppa.c -gas/config/tc-hppa.h -gas/config/tc-i370.c -gas/config/tc-i370.h -gas/config/tc-i860.c -gas/config/tc-i860.h -gas/config/tc-i960.c -gas/config/tc-i960.h -gas/config/tc-ia64.c -gas/config/tc-ia64.h -gas/config/tc-ip2k.c -gas/config/tc-ip2k.h -gas/config/tc-iq2000.c -gas/config/tc-iq2000.h -gas/config/tc-lm32.c -gas/config/tc-lm32.h -gas/config/tc-m32c.c -gas/config/tc-m32c.h -gas/config/tc-m32r.c -gas/config/tc-m32r.h -gas/config/tc-m68851.h -gas/config/tc-m68hc11.c -gas/config/tc-m68hc11.h -gas/config/tc-m68k.c -gas/config/tc-m68k.h -gas/config/tc-mcore.c -gas/config/tc-mcore.h -gas/config/tc-mep.c -gas/config/tc-mep.h -gas/config/tc-microblaze.c -gas/config/tc-microblaze.h -gas/config/tc-mips.c -gas/config/tc-mips.h -gas/config/tc-mmix.c -gas/config/tc-mmix.h -gas/config/tc-mn10200.c -gas/config/tc-mn10200.h -gas/config/tc-mn10300.c -gas/config/tc-mn10300.h -gas/config/tc-moxie.c -gas/config/tc-moxie.h -gas/config/tc-msp430.c -gas/config/tc-msp430.h -gas/config/tc-mt.c -gas/config/tc-mt.h -gas/config/tc-ns32k.c -gas/config/tc-ns32k.h -gas/config/tc-openrisc.c -gas/config/tc-openrisc.h -gas/config/tc-or32.c -gas/config/tc-or32.h -gas/config/tc-pdp11.c -gas/config/tc-pdp11.h -gas/config/tc-pj.c -gas/config/tc-pj.h -gas/config/tc-ppc.c -gas/config/tc-ppc.h -gas/config/tc-rx.c -gas/config/tc-rx.h -gas/config/tc-s390.c -gas/config/tc-s390.h -gas/config/tc-score.c -gas/config/tc-score.h -gas/config/tc-score7.c -gas/config/tc-sh.c -gas/config/tc-sh.h -gas/config/tc-sh64.c -gas/config/tc-sh64.h -gas/config/tc-sparc.c -gas/config/tc-sparc.h -gas/config/tc-spu.c -gas/config/tc-spu.h -gas/config/tc-tic30.c -gas/config/tc-tic30.h -gas/config/tc-tic4x.c -gas/config/tc-tic4x.h -gas/config/tc-tic54x.c -gas/config/tc-tic54x.h -gas/config/tc-tic6x.c -gas/config/tc-tic6x.h -gas/config/tc-tilegx.c -gas/config/tc-tilegx.h -gas/config/tc-tilepro.c -gas/config/tc-tilepro.h -gas/config/tc-v850.c -gas/config/tc-v850.h -gas/config/tc-vax.c -gas/config/tc-vax.h -gas/config/tc-xc16x.c -gas/config/tc-xc16x.h -gas/config/tc-xstormy16.c -gas/config/tc-xstormy16.h -gas/config/tc-xtensa.c -gas/config/tc-xtensa.h -gas/config/tc-z80.c -gas/config/tc-z80.h -gas/config/tc-z8k.c -gas/config/tc-z8k.h -gas/config/te-386bsd.h -gas/config/te-aix5.h -gas/config/te-armeabi.h -gas/config/te-armlinuxeabi.h -gas/config/te-dynix.h -gas/config/te-epoc-pe.h -gas/config/te-freebsd.h -gas/config/te-generic.h -gas/config/te-gnu.h -gas/config/te-go32.h -gas/config/te-hppa.h -gas/config/te-hppa64.h -gas/config/te-hppalinux64.h -gas/config/te-hpux.h -gas/config/te-i386aix.h -gas/config/te-ia64aix.h -gas/config/te-interix.h -gas/config/te-irix.h -gas/config/te-linux.h -gas/config/te-lnews.h -gas/config/te-lynx.h -gas/config/te-mach.h -gas/config/te-macos.h -gas/config/te-nbsd.h -gas/config/te-nbsd532.h -gas/config/te-netware.h -gas/config/te-pc532mach.h -gas/config/te-pe.h -gas/config/te-pep.h -gas/config/te-psos.h -gas/config/te-riscix.h -gas/config/te-solaris.h -gas/config/te-sparcaout.h -gas/config/te-sun3.h -gas/config/te-svr4.h -gas/config/te-symbian.h -gas/config/te-tmips.h -gas/config/te-uclinux.h -gas/config/te-vms.c -gas/config/te-vms.h -gas/config/te-vxworks.h -gas/config/te-wince-pe.h -gas/config/vax-inst.h -gas/config/xtensa-istack.h -gas/config/xtensa-relax.c -gas/config/xtensa-relax.h -gas/configure -gas/configure.com -gas/configure.in -gas/configure.tgt -gas/debug.c -gas/dep-in.sed -gas/doc/all.texi -gas/doc/as.info -gas/doc/c-mt.texi -gas/doc/c-xc16x.texi -gas/doc/fdl.texi -gas/doc/h8.texi -gas/doc/internals.texi -gas/emul-target.h -gas/emul.h -gas/gdbinit.in -gas/itbl-lex.c -gas/itbl-lex.h -gas/itbl-lex.l -gas/itbl-ops.c -gas/itbl-ops.h -gas/itbl-parse.c -gas/itbl-parse.h -gas/itbl-parse.y -gas/m68k-parse.c -gas/makefile.vms -gas/po/ -gas/rx-parse.c -gas/rx-parse.h -gas/stamp-h.in -gas/testsuite/ -gold/ChangeLog -gold/Makefile.am -gold/Makefile.in -gold/NEWS -gold/TODO -gold/aclocal.m4 -gold/config.in -gold/configure -gold/configure.ac -gold/configure.tgt -gold/po/ -gold/pread.c -gold/testsuite/ -gold/yyscript.y -gprof/.gdbinit -gprof/.gitignore -gprof/ChangeLog -gprof/ChangeLog-2004 -gprof/ChangeLog-2005 -gprof/ChangeLog-2006 -gprof/ChangeLog-2007 -gprof/ChangeLog-2008 -gprof/ChangeLog-2009 -gprof/ChangeLog-2010 -gprof/ChangeLog-9203 -gprof/MAINTAINERS -gprof/Makefile.am -gprof/Makefile.in -gprof/TEST -gprof/TODO -gprof/aclocal.m4 -gprof/bb_exit_func.c -gprof/bbconv.pl -gprof/configure -gprof/configure.in -gprof/dep-in.sed -gprof/gconfig.in -gprof/po/ -gprof/stamp-h.in -include/ChangeLog -include/ChangeLog-9103 -include/MAINTAINERS -include/aout/ChangeLog -include/aout/adobe.h -include/aout/dynix3.h -include/aout/encap.h -include/aout/host.h -include/aout/hp.h -include/aout/hp300hpux.h -include/aout/hppa.h -include/aout/reloc.h -include/aout/sun4.h -include/bout.h -include/cgen/ -include/coff/ChangeLog -include/coff/ChangeLog-9103 -include/coff/alpha.h -include/coff/apollo.h -include/coff/arm.h -include/coff/aux-coff.h -include/coff/go32exe.h -include/coff/h8300.h -include/coff/h8500.h -include/coff/i860.h -include/coff/i960.h -include/coff/ia64.h -include/coff/m68k.h -include/coff/m88k.h -include/coff/mcore.h -include/coff/mips.h -include/coff/mipspe.h -include/coff/or32.h -include/coff/powerpc.h -include/coff/rs6000.h -include/coff/rs6k64.h -include/coff/sh.h -include/coff/sparc.h -include/coff/symconst.h -include/coff/ti.h -include/coff/tic30.h -include/coff/tic4x.h -include/coff/tic54x.h -include/coff/tic80.h -include/coff/w65.h -include/coff/we32k.h -include/coff/x86_64.h -include/coff/xcoff.h -include/coff/z80.h -include/coff/z8k.h -include/elf/ChangeLog -include/elf/ChangeLog-9103 -include/fibheap.h -include/fopen-bin.h -include/fopen-vms.h -include/gdb/ -include/gdbm.h -include/hp-symtab.h -include/nlm/ -include/oasys.h -include/opcode/ChangeLog -include/opcode/ChangeLog-9103 -include/opcode/alpha.h -include/opcode/arc.h -include/opcode/arm.h -include/opcode/avr.h -include/opcode/bfin.h -include/opcode/cgen.h -include/opcode/convex.h -include/opcode/cr16.h -include/opcode/cris.h -include/opcode/crx.h -include/opcode/d10v.h -include/opcode/d30v.h -include/opcode/dlx.h -include/opcode/h8300.h -include/opcode/hppa.h -include/opcode/i370.h -include/opcode/i860.h -include/opcode/i960.h -include/opcode/ia64.h -include/opcode/m68hc11.h -include/opcode/m68k.h -include/opcode/m88k.h -include/opcode/mips.h -include/opcode/mmix.h -include/opcode/mn10200.h -include/opcode/mn10300.h -include/opcode/moxie.h -include/opcode/msp430.h -include/opcode/np1.h -include/opcode/ns32k.h -include/opcode/or32.h -include/opcode/pdp11.h -include/opcode/pj.h -include/opcode/pn.h -include/opcode/ppc.h -include/opcode/pyr.h -include/opcode/rx.h -include/opcode/s390.h -include/opcode/score-datadep.h -include/opcode/score-inst.h -include/opcode/sparc.h -include/opcode/spu-insns.h -include/opcode/spu.h -include/opcode/tahoe.h -include/opcode/tic30.h -include/opcode/tic4x.h -include/opcode/tic54x.h -include/opcode/tic6x-control-registers.h -include/opcode/tic6x-insn-formats.h -include/opcode/tic6x-opcode-table.h -include/opcode/tic6x.h -include/opcode/tic80.h -include/opcode/tilegx.h -include/opcode/tilepro.h -include/opcode/v850.h -include/opcode/vax.h -include/os9k.h -include/partition.h -include/som/ -include/sort.h -include/splay-tree.h -include/vms/ -include/xregex.h -include/xregex2.h -include/xtensa-config.h -include/xtensa-isa-internal.h -include/xtensa-isa.h -install-sh -intl/ -ld/.gitignore -ld/ChangeLog -ld/ChangeLog-0001 -ld/ChangeLog-0203 -ld/ChangeLog-2004 -ld/ChangeLog-2005 -ld/ChangeLog-2006 -ld/ChangeLog-2007 -ld/ChangeLog-2008 -ld/ChangeLog-2009 -ld/ChangeLog-2010 -ld/ChangeLog-9197 -ld/ChangeLog-9899 -ld/MAINTAINERS -ld/Makefile.am -ld/Makefile.in -ld/NEWS -ld/TODO -ld/aclocal.m4 -ld/config.in -ld/configure -ld/configure.host -ld/configure.in -ld/configure.tgt -ld/deffile.h -ld/deffilep.c -ld/deffilep.h -ld/deffilep.y -ld/dep-in.sed -ld/elf-hints-local.h -ld/emulparams/aix5ppc.sh -ld/emulparams/aix5rs6.sh -ld/emulparams/aixppc.sh -ld/emulparams/aixrs6.sh -ld/emulparams/alpha.sh -ld/emulparams/alphavms.sh -ld/emulparams/arcelf.sh -ld/emulparams/arm_epoc_pe.sh -ld/emulparams/arm_wince_pe.sh -ld/emulparams/armaoutb.sh -ld/emulparams/armaoutl.sh -ld/emulparams/armcoff.sh -ld/emulparams/armelf.sh -ld/emulparams/armelf_fbsd.sh -ld/emulparams/armelf_linux.sh -ld/emulparams/armelf_linux_eabi.sh -ld/emulparams/armelf_nbsd.sh -ld/emulparams/armelf_vxworks.sh -ld/emulparams/armelfb.sh -ld/emulparams/armelfb_linux.sh -ld/emulparams/armelfb_linux_eabi.sh -ld/emulparams/armelfb_nbsd.sh -ld/emulparams/armnbsd.sh -ld/emulparams/armnto.sh -ld/emulparams/armpe.sh -ld/emulparams/armsymbian.sh -ld/emulparams/avr1.sh -ld/emulparams/avr2.sh -ld/emulparams/avr25.sh -ld/emulparams/avr3.sh -ld/emulparams/avr31.sh -ld/emulparams/avr35.sh -ld/emulparams/avr4.sh -ld/emulparams/avr5.sh -ld/emulparams/avr51.sh -ld/emulparams/avr6.sh -ld/emulparams/avrxmega1.sh -ld/emulparams/avrxmega2.sh -ld/emulparams/avrxmega3.sh -ld/emulparams/avrxmega4.sh -ld/emulparams/avrxmega5.sh -ld/emulparams/avrxmega6.sh -ld/emulparams/avrxmega7.sh -ld/emulparams/bfin.sh -ld/emulparams/coff_i860.sh -ld/emulparams/coff_sparc.sh -ld/emulparams/crisaout.sh -ld/emulparams/criself.sh -ld/emulparams/crislinux.sh -ld/emulparams/d10velf.sh -ld/emulparams/d30v_e.sh -ld/emulparams/d30v_o.sh -ld/emulparams/d30velf.sh -ld/emulparams/delta68.sh -ld/emulparams/elf32_dlx.sh -ld/emulparams/elf32_i860.sh -ld/emulparams/elf32_i960.sh -ld/emulparams/elf32_sparc.sh -ld/emulparams/elf32_sparc_sol2.sh -ld/emulparams/elf32_sparc_vxworks.sh -ld/emulparams/elf32_spu.sh -ld/emulparams/elf32_tic6x_be.sh -ld/emulparams/elf32_tic6x_elf_be.sh -ld/emulparams/elf32_tic6x_elf_le.sh -ld/emulparams/elf32_tic6x_le.sh -ld/emulparams/elf32_tic6x_linux_be.sh -ld/emulparams/elf32_tic6x_linux_le.sh -ld/emulparams/elf32_x86_64.sh -ld/emulparams/elf32am33lin.sh -ld/emulparams/elf32b4300.sh -ld/emulparams/elf32bfinfd.sh -ld/emulparams/elf32bmip.sh -ld/emulparams/elf32bmipn32-defs.sh -ld/emulparams/elf32bmipn32.sh -ld/emulparams/elf32bsmip.sh -ld/emulparams/elf32btsmip.sh -ld/emulparams/elf32btsmip_fbsd.sh -ld/emulparams/elf32btsmipn32.sh -ld/emulparams/elf32btsmipn32_fbsd.sh -ld/emulparams/elf32cr16.sh -ld/emulparams/elf32cr16c.sh -ld/emulparams/elf32crx.sh -ld/emulparams/elf32ebmip.sh -ld/emulparams/elf32ebmipvxworks.sh -ld/emulparams/elf32elmip.sh -ld/emulparams/elf32elmipvxworks.sh -ld/emulparams/elf32fr30.sh -ld/emulparams/elf32frv.sh -ld/emulparams/elf32frvfd.sh -ld/emulparams/elf32i370.sh -ld/emulparams/elf32ip2k.sh -ld/emulparams/elf32iq10.sh -ld/emulparams/elf32iq2000.sh -ld/emulparams/elf32l4300.sh -ld/emulparams/elf32lm32.sh -ld/emulparams/elf32lm32fd.sh -ld/emulparams/elf32lmip.sh -ld/emulparams/elf32lppc.sh -ld/emulparams/elf32lppcnto.sh -ld/emulparams/elf32lppcsim.sh -ld/emulparams/elf32lsmip.sh -ld/emulparams/elf32ltsmip.sh -ld/emulparams/elf32ltsmip_fbsd.sh -ld/emulparams/elf32ltsmipn32.sh -ld/emulparams/elf32ltsmipn32_fbsd.sh -ld/emulparams/elf32m32c.sh -ld/emulparams/elf32mb_linux.sh -ld/emulparams/elf32mcore.sh -ld/emulparams/elf32mep.sh -ld/emulparams/elf32microblaze.sh -ld/emulparams/elf32mipswindiss.sh -ld/emulparams/elf32moxie.sh -ld/emulparams/elf32mt.sh -ld/emulparams/elf32openrisc.sh -ld/emulparams/elf32ppc.sh -ld/emulparams/elf32ppc_fbsd.sh -ld/emulparams/elf32ppccommon.sh -ld/emulparams/elf32ppclinux.sh -ld/emulparams/elf32ppcnto.sh -ld/emulparams/elf32ppcsim.sh -ld/emulparams/elf32ppcvxworks.sh -ld/emulparams/elf32ppcwindiss.sh -ld/emulparams/elf32rx.sh -ld/emulparams/elf32tilegx.sh -ld/emulparams/elf32tilepro.sh -ld/emulparams/elf32vax.sh -ld/emulparams/elf32xc16x.sh -ld/emulparams/elf32xc16xl.sh -ld/emulparams/elf32xc16xs.sh -ld/emulparams/elf32xstormy16.sh -ld/emulparams/elf32xtensa.sh -ld/emulparams/elf64_aix.sh -ld/emulparams/elf64_ia64.sh -ld/emulparams/elf64_ia64_fbsd.sh -ld/emulparams/elf64_s390.sh -ld/emulparams/elf64_sparc.sh -ld/emulparams/elf64_sparc_fbsd.sh -ld/emulparams/elf64_sparc_sol2.sh -ld/emulparams/elf64alpha.sh -ld/emulparams/elf64alpha_fbsd.sh -ld/emulparams/elf64alpha_nbsd.sh -ld/emulparams/elf64bmip-defs.sh -ld/emulparams/elf64bmip.sh -ld/emulparams/elf64btsmip.sh -ld/emulparams/elf64btsmip_fbsd.sh -ld/emulparams/elf64hppa.sh -ld/emulparams/elf64lppc.sh -ld/emulparams/elf64ltsmip.sh -ld/emulparams/elf64ltsmip_fbsd.sh -ld/emulparams/elf64tilegx.sh -ld/emulparams/elf64mmix.sh -ld/emulparams/elf64ppc.sh -ld/emulparams/elf_fbsd.sh -ld/emulparams/elf_i386_be.sh -ld/emulparams/elf_i386_chaos.sh -ld/emulparams/elf_i386_fbsd.sh -ld/emulparams/elf_i386_ldso.sh -ld/emulparams/elf_i386_sol2.sh -ld/emulparams/elf_i386_vxworks.sh -ld/emulparams/elf_k1om.sh -ld/emulparams/elf_k1om_fbsd.sh -ld/emulparams/elf_l1om.sh -ld/emulparams/elf_l1om_fbsd.sh -ld/emulparams/elf_s390.sh -ld/emulparams/elf_x86_64_fbsd.sh -ld/emulparams/elf_x86_64_sol2.sh -ld/emulparams/gld960.sh -ld/emulparams/gld960coff.sh -ld/emulparams/h8300.sh -ld/emulparams/h8300elf.sh -ld/emulparams/h8300h.sh -ld/emulparams/h8300helf.sh -ld/emulparams/h8300hn.sh -ld/emulparams/h8300hnelf.sh -ld/emulparams/h8300s.sh -ld/emulparams/h8300self.sh -ld/emulparams/h8300sn.sh -ld/emulparams/h8300snelf.sh -ld/emulparams/h8300sx.sh -ld/emulparams/h8300sxelf.sh -ld/emulparams/h8300sxn.sh -ld/emulparams/h8300sxnelf.sh -ld/emulparams/h8500.sh -ld/emulparams/h8500b.sh -ld/emulparams/h8500c.sh -ld/emulparams/h8500m.sh -ld/emulparams/h8500s.sh -ld/emulparams/hp300bsd.sh -ld/emulparams/hp3hpux.sh -ld/emulparams/hppa64linux.sh -ld/emulparams/hppaelf.sh -ld/emulparams/hppalinux.sh -ld/emulparams/hppanbsd.sh -ld/emulparams/hppaobsd.sh -ld/emulparams/i386aout.sh -ld/emulparams/i386beos.sh -ld/emulparams/i386bsd.sh -ld/emulparams/i386coff.sh -ld/emulparams/i386go32.sh -ld/emulparams/i386linux.sh -ld/emulparams/i386lynx.sh -ld/emulparams/i386mach.sh -ld/emulparams/i386moss.sh -ld/emulparams/i386msdos.sh -ld/emulparams/i386nbsd.sh -ld/emulparams/i386nto.sh -ld/emulparams/i386nw.sh -ld/emulparams/i386pe.sh -ld/emulparams/i386pe_posix.sh -ld/emulparams/i386pep.sh -ld/emulparams/lnk960.sh -ld/emulparams/m32relf.sh -ld/emulparams/m32relf_linux.sh -ld/emulparams/m32rlelf.sh -ld/emulparams/m32rlelf_linux.sh -ld/emulparams/m68hc11elf.sh -ld/emulparams/m68hc11elfb.sh -ld/emulparams/m68hc12elf.sh -ld/emulparams/m68hc12elfb.sh -ld/emulparams/m68k4knbsd.sh -ld/emulparams/m68kaout.sh -ld/emulparams/m68kaux.sh -ld/emulparams/m68kcoff.sh -ld/emulparams/m68kelf.sh -ld/emulparams/m68kelfnbsd.sh -ld/emulparams/m68klinux.sh -ld/emulparams/m68knbsd.sh -ld/emulparams/m68kpsos.sh -ld/emulparams/m88kbcs.sh -ld/emulparams/mcorepe.sh -ld/emulparams/mipsbig.sh -ld/emulparams/mipsbsd.sh -ld/emulparams/mipsidt.sh -ld/emulparams/mipsidtl.sh -ld/emulparams/mipslit.sh -ld/emulparams/mipslnews.sh -ld/emulparams/mipspe.sh -ld/emulparams/mmo.sh -ld/emulparams/mn10200.sh -ld/emulparams/mn10300.sh -ld/emulparams/msp430all.sh -ld/emulparams/news.sh -ld/emulparams/ns32knbsd.sh -ld/emulparams/or32.sh -ld/emulparams/or32elf.sh -ld/emulparams/pc532macha.sh -ld/emulparams/pdp11.sh -ld/emulparams/pjelf.sh -ld/emulparams/pjlelf.sh -ld/emulparams/ppclynx.sh -ld/emulparams/ppcmacos.sh -ld/emulparams/ppcnw.sh -ld/emulparams/ppcpe.sh -ld/emulparams/riscix.sh -ld/emulparams/scoreelf.sh -ld/emulparams/sh.sh -ld/emulparams/shelf.sh -ld/emulparams/shelf32.sh -ld/emulparams/shelf32_linux.sh -ld/emulparams/shelf32_nbsd.sh -ld/emulparams/shelf64.sh -ld/emulparams/shelf64_nbsd.sh -ld/emulparams/shelf_fd.sh -ld/emulparams/shelf_linux.sh -ld/emulparams/shelf_nbsd.sh -ld/emulparams/shelf_nto.sh -ld/emulparams/shelf_uclinux.sh -ld/emulparams/shelf_vxworks.sh -ld/emulparams/shl.sh -ld/emulparams/shlelf.sh -ld/emulparams/shlelf32.sh -ld/emulparams/shlelf32_linux.sh -ld/emulparams/shlelf32_nbsd.sh -ld/emulparams/shlelf64.sh -ld/emulparams/shlelf64_nbsd.sh -ld/emulparams/shlelf_fd.sh -ld/emulparams/shlelf_linux.sh -ld/emulparams/shlelf_nbsd.sh -ld/emulparams/shlelf_nto.sh -ld/emulparams/shlelf_vxworks.sh -ld/emulparams/shlsymbian.sh -ld/emulparams/shpe.sh -ld/emulparams/solaris2.sh -ld/emulparams/sparcaout.sh -ld/emulparams/sparclinux.sh -ld/emulparams/sparcnbsd.sh -ld/emulparams/st2000.sh -ld/emulparams/sun3.sh -ld/emulparams/sun4.sh -ld/emulparams/tic30aout.sh -ld/emulparams/tic30coff.sh -ld/emulparams/tic3xcoff.sh -ld/emulparams/tic3xcoff_onchip.sh -ld/emulparams/tic4xcoff.sh -ld/emulparams/tic54xcoff.sh -ld/emulparams/tic80coff.sh -ld/emulparams/v850.sh -ld/emulparams/vanilla.sh -ld/emulparams/vax.sh -ld/emulparams/vaxnbsd.sh -ld/emulparams/vsta.sh -ld/emulparams/vxworks.sh -ld/emulparams/w65.sh -ld/emulparams/z80.sh -ld/emulparams/z8001.sh -ld/emulparams/z8002.sh -ld/emultempl/aix.em -ld/emultempl/alphaelf.em -ld/emultempl/armcoff.em -ld/emultempl/armelf.em -ld/emultempl/avrelf.em -ld/emultempl/beos.em -ld/emultempl/bfin.em -ld/emultempl/cr16elf.em -ld/emultempl/crxelf.em -ld/emultempl/genelf.em -ld/emultempl/generic.em -ld/emultempl/gld960.em -ld/emultempl/gld960c.em -ld/emultempl/hppaelf.em -ld/emultempl/ia64elf.em -ld/emultempl/irix.em -ld/emultempl/linux.em -ld/emultempl/lnk960.em -ld/emultempl/m68hc1xelf.em -ld/emultempl/m68kcoff.em -ld/emultempl/m68kelf.em -ld/emultempl/mipsecoff.em -ld/emultempl/mipself.em -ld/emultempl/mmix-elfnmmo.em -ld/emultempl/mmixelf.em -ld/emultempl/mmo.em -ld/emultempl/needrelax.em -ld/emultempl/netbsd.em -ld/emultempl/ostring.sed -ld/emultempl/pe.em -ld/emultempl/pep.em -ld/emultempl/ppc32elf.em -ld/emultempl/ppc64elf.em -ld/emultempl/rxelf.em -ld/emultempl/scoreelf.em -ld/emultempl/sh64elf.em -ld/emultempl/solaris2.em -ld/emultempl/spu_icache.S -ld/emultempl/spu_icache.o_c -ld/emultempl/spu_ovl.S -ld/emultempl/spu_ovl.o_c -ld/emultempl/spuelf.em -ld/emultempl/sunos.em -ld/emultempl/tic6xdsbt.em -ld/emultempl/ticoff.em -ld/emultempl/vanilla.em -ld/emultempl/vms.em -ld/emultempl/vxworks.em -ld/emultempl/xtensaelf.em -ld/emultempl/z80.em -ld/genscrba.sh -ld/h8-doc.texi -ld/ld.info -ld/ldgram.c -ld/ldgram.h -ld/ldint.texinfo -ld/ldlex.c -ld/pe-dll.c -ld/pe-dll.h -ld/pep-dll.c -ld/pep-dll.h -ld/po/ -ld/scripttempl/aix.sc -ld/scripttempl/alpha.sc -ld/scripttempl/alphavms.sc -ld/scripttempl/aout.sc -ld/scripttempl/armaout.sc -ld/scripttempl/armbpabi.sc -ld/scripttempl/armcoff.sc -ld/scripttempl/avr.sc -ld/scripttempl/crisaout.sc -ld/scripttempl/delta68.sc -ld/scripttempl/dlx.sc -ld/scripttempl/elf32cr16.sc -ld/scripttempl/elf32cr16c.sc -ld/scripttempl/elf32crx.sc -ld/scripttempl/elf32msp430.sc -ld/scripttempl/elf32msp430_3.sc -ld/scripttempl/elf32sh-symbian.sc -ld/scripttempl/elf32xc16x.sc -ld/scripttempl/elf32xc16xl.sc -ld/scripttempl/elf32xc16xs.sc -ld/scripttempl/elf64hppa.sc -ld/scripttempl/elf_chaos.sc -ld/scripttempl/elfd10v.sc -ld/scripttempl/elfd30v.sc -ld/scripttempl/elfi370.sc -ld/scripttempl/elfm68hc11.sc -ld/scripttempl/elfm68hc12.sc -ld/scripttempl/elfmicroblaze.sc -ld/scripttempl/elfxtensa.sc -ld/scripttempl/epocpe.sc -ld/scripttempl/h8300.sc -ld/scripttempl/h8300h.sc -ld/scripttempl/h8300hn.sc -ld/scripttempl/h8300s.sc -ld/scripttempl/h8300sn.sc -ld/scripttempl/h8300sx.sc -ld/scripttempl/h8300sxn.sc -ld/scripttempl/h8500.sc -ld/scripttempl/h8500b.sc -ld/scripttempl/h8500c.sc -ld/scripttempl/h8500m.sc -ld/scripttempl/h8500s.sc -ld/scripttempl/hppaelf.sc -ld/scripttempl/i386beos.sc -ld/scripttempl/i386coff.sc -ld/scripttempl/i386go32.sc -ld/scripttempl/i386msdos.sc -ld/scripttempl/i860coff.sc -ld/scripttempl/i960.sc -ld/scripttempl/ip2k.sc -ld/scripttempl/iq2000.sc -ld/scripttempl/m68kaux.sc -ld/scripttempl/m68kcoff.sc -ld/scripttempl/m88kbcs.sc -ld/scripttempl/mcorepe.sc -ld/scripttempl/mep.sc -ld/scripttempl/mips.sc -ld/scripttempl/mipsbsd.sc -ld/scripttempl/mmo.sc -ld/scripttempl/moxie.sc -ld/scripttempl/nw.sc -ld/scripttempl/or32.sc -ld/scripttempl/pe.sc -ld/scripttempl/pep.sc -ld/scripttempl/pj.sc -ld/scripttempl/ppcpe.sc -ld/scripttempl/psos.sc -ld/scripttempl/riscix.sc -ld/scripttempl/sh.sc -ld/scripttempl/sparccoff.sc -ld/scripttempl/st2000.sc -ld/scripttempl/tic30aout.sc -ld/scripttempl/tic30coff.sc -ld/scripttempl/tic4xcoff.sc -ld/scripttempl/tic54xcoff.sc -ld/scripttempl/tic80coff.sc -ld/scripttempl/v850.sc -ld/scripttempl/vanilla.sc -ld/scripttempl/w65.sc -ld/scripttempl/xstormy16.sc -ld/scripttempl/z80.sc -ld/scripttempl/z8000.sc -ld/stamp-h.in -ld/testplug.c -ld/testsuite/ -libiberty/.gitignore -libiberty/ChangeLog -libiberty/Makefile.in -libiberty/_doprnt.c -libiberty/aclocal.m4 -libiberty/alloca.c -libiberty/asprintf.c -libiberty/atexit.c -libiberty/basename.c -libiberty/bcmp.c -libiberty/bcopy.c -libiberty/bsearch.c -libiberty/bzero.c -libiberty/calloc.c -libiberty/clock.c -libiberty/config.h-vms -libiberty/config.in -libiberty/config/ -libiberty/configure -libiberty/configure.ac -libiberty/configure.com -libiberty/copying-lib.texi -libiberty/copysign.c -libiberty/fdmatch.c -libiberty/ffs.c -libiberty/fibheap.c -libiberty/fnmatch.c -libiberty/fnmatch.txh -libiberty/fopen_unlocked.c -libiberty/functions.texi -libiberty/gather-docs -libiberty/getcwd.c -libiberty/getpagesize.c -libiberty/gettimeofday.c -libiberty/index.c -libiberty/insque.c -libiberty/libiberty.texi -libiberty/maint-tool -libiberty/makefile.vms -libiberty/memchr.c -libiberty/memcmp.c -libiberty/memcpy.c -libiberty/memmem.c -libiberty/memmove.c -libiberty/memset.c -libiberty/mkstemps.c -libiberty/msdos.c -libiberty/obstacks.texi -libiberty/partition.c -libiberty/pex-common.c -libiberty/pex-common.h -libiberty/pex-djgpp.c -libiberty/pex-msdos.c -libiberty/pex-one.c -libiberty/pex-unix.c -libiberty/pex-win32.c -libiberty/pexecute.c -libiberty/pexecute.txh -libiberty/physmem.c -libiberty/putenv.c -libiberty/random.c -libiberty/regex.c -libiberty/rename.c -libiberty/rindex.c -libiberty/setenv.c -libiberty/sigsetmask.c -libiberty/snprintf.c -libiberty/sort.c -libiberty/spaces.c -libiberty/splay-tree.c -libiberty/stpncpy.c -libiberty/strcasecmp.c -libiberty/strchr.c -libiberty/strdup.c -libiberty/strerror.c -libiberty/strncasecmp.c -libiberty/strncmp.c -libiberty/strndup.c -libiberty/strrchr.c -libiberty/strsignal.c -libiberty/strstr.c -libiberty/strtod.c -libiberty/strtol.c -libiberty/strtoul.c -libiberty/strverscmp.c -libiberty/testsuite/ -libiberty/tmpnam.c -libiberty/vasprintf.c -libiberty/vfork.c -libiberty/vfprintf.c -libiberty/vprintf.c -libiberty/vsnprintf.c -libiberty/vsprintf.c -libiberty/waitpid.c -libiberty/xmemdup.c -libtool.m4 -ltgcc.m4 -ltmain.sh -ltoptions.m4 -ltsugar.m4 -ltversion.m4 -lt~obsolete.m4 -makefile.vms -md5.sum -missing -mkdep -mkinstalldirs -move-if-change -opcodes/.gitignore -opcodes/ChangeLog -opcodes/ChangeLog-0001 -opcodes/ChangeLog-0203 -opcodes/ChangeLog-2004 -opcodes/ChangeLog-2005 -opcodes/ChangeLog-2006 -opcodes/ChangeLog-2007 -opcodes/ChangeLog-2008 -opcodes/ChangeLog-2009 -opcodes/ChangeLog-2010 -opcodes/ChangeLog-9297 -opcodes/ChangeLog-9899 -opcodes/MAINTAINERS -opcodes/Makefile.am -opcodes/Makefile.in -opcodes/aclocal.m4 -opcodes/alpha-dis.c -opcodes/alpha-opc.c -opcodes/arc-dis.c -opcodes/arc-dis.h -opcodes/arc-ext.c -opcodes/arc-ext.h -opcodes/arc-opc.c -opcodes/arm-dis.c -opcodes/avr-dis.c -opcodes/bfin-dis.c -opcodes/cgen-asm.c -opcodes/cgen-asm.in -opcodes/cgen-bitset.c -opcodes/cgen-dis.c -opcodes/cgen-dis.in -opcodes/cgen-ibld.in -opcodes/cgen-opc.c -opcodes/cgen.sh -opcodes/config.in -opcodes/configure -opcodes/configure.com -opcodes/configure.in -opcodes/cr16-dis.c -opcodes/cr16-opc.c -opcodes/cris-dis.c -opcodes/cris-opc.c -opcodes/crx-dis.c -opcodes/crx-opc.c -opcodes/d10v-dis.c -opcodes/d10v-opc.c -opcodes/d30v-dis.c -opcodes/d30v-opc.c -opcodes/dep-in.sed -opcodes/dlx-dis.c -opcodes/fr30-asm.c -opcodes/fr30-desc.c -opcodes/fr30-desc.h -opcodes/fr30-dis.c -opcodes/fr30-ibld.c -opcodes/fr30-opc.c -opcodes/fr30-opc.h -opcodes/frv-asm.c -opcodes/frv-desc.c -opcodes/frv-desc.h -opcodes/frv-dis.c -opcodes/frv-ibld.c -opcodes/frv-opc.c -opcodes/frv-opc.h -opcodes/h8300-dis.c -opcodes/h8500-dis.c -opcodes/h8500-opc.h -opcodes/hppa-dis.c -opcodes/i370-dis.c -opcodes/i370-opc.c -opcodes/i386-gen.c -opcodes/i386-opc.tbl -opcodes/i386-reg.tbl -opcodes/i860-dis.c -opcodes/i960-dis.c -opcodes/ia64-asmtab.c -opcodes/ia64-asmtab.h -opcodes/ia64-dis.c -opcodes/ia64-gen.c -opcodes/ia64-ic.tbl -opcodes/ia64-opc-a.c -opcodes/ia64-opc-b.c -opcodes/ia64-opc-d.c -opcodes/ia64-opc-f.c -opcodes/ia64-opc-i.c -opcodes/ia64-opc-m.c -opcodes/ia64-opc-x.c -opcodes/ia64-opc.c -opcodes/ia64-opc.h -opcodes/ia64-raw.tbl -opcodes/ia64-war.tbl -opcodes/ia64-waw.tbl -opcodes/ip2k-asm.c -opcodes/ip2k-desc.c -opcodes/ip2k-desc.h -opcodes/ip2k-dis.c -opcodes/ip2k-ibld.c -opcodes/ip2k-opc.c -opcodes/ip2k-opc.h -opcodes/iq2000-asm.c -opcodes/iq2000-desc.c -opcodes/iq2000-desc.h -opcodes/iq2000-dis.c -opcodes/iq2000-ibld.c -opcodes/iq2000-opc.c -opcodes/iq2000-opc.h -opcodes/lm32-asm.c -opcodes/lm32-desc.c -opcodes/lm32-desc.h -opcodes/lm32-dis.c -opcodes/lm32-ibld.c -opcodes/lm32-opc.c -opcodes/lm32-opc.h -opcodes/lm32-opinst.c -opcodes/m10200-dis.c -opcodes/m10200-opc.c -opcodes/m10300-dis.c -opcodes/m10300-opc.c -opcodes/m32c-asm.c -opcodes/m32c-desc.c -opcodes/m32c-desc.h -opcodes/m32c-dis.c -opcodes/m32c-ibld.c -opcodes/m32c-opc.c -opcodes/m32c-opc.h -opcodes/m32r-asm.c -opcodes/m32r-desc.c -opcodes/m32r-desc.h -opcodes/m32r-dis.c -opcodes/m32r-ibld.c -opcodes/m32r-opc.c -opcodes/m32r-opc.h -opcodes/m32r-opinst.c -opcodes/m68hc11-dis.c -opcodes/m68hc11-opc.c -opcodes/m68k-dis.c -opcodes/m68k-opc.c -opcodes/m88k-dis.c -opcodes/makefile.vms -opcodes/mcore-dis.c -opcodes/mcore-opc.h -opcodes/mep-asm.c -opcodes/mep-desc.c -opcodes/mep-desc.h -opcodes/mep-dis.c -opcodes/mep-ibld.c -opcodes/mep-opc.c -opcodes/mep-opc.h -opcodes/microblaze-dis.c -opcodes/microblaze-dis.h -opcodes/microblaze-opc.h -opcodes/microblaze-opcm.h -opcodes/micromips-opc.c -opcodes/mips-dis.c -opcodes/mips-opc.c -opcodes/mips16-opc.c -opcodes/mmix-dis.c -opcodes/mmix-opc.c -opcodes/moxie-dis.c -opcodes/moxie-opc.c -opcodes/msp430-dis.c -opcodes/mt-asm.c -opcodes/mt-desc.c -opcodes/mt-desc.h -opcodes/mt-dis.c -opcodes/mt-ibld.c -opcodes/mt-opc.c -opcodes/mt-opc.h -opcodes/ns32k-dis.c -opcodes/opc2c.c -opcodes/openrisc-asm.c -opcodes/openrisc-desc.c -opcodes/openrisc-desc.h -opcodes/openrisc-dis.c -opcodes/openrisc-ibld.c -opcodes/openrisc-opc.c -opcodes/openrisc-opc.h -opcodes/or32-dis.c -opcodes/or32-opc.c -opcodes/pdp11-dis.c -opcodes/pdp11-opc.c -opcodes/pj-dis.c -opcodes/pj-opc.c -opcodes/po/ -opcodes/ppc-dis.c -opcodes/ppc-opc.c -opcodes/rx-decode.c -opcodes/rx-decode.opc -opcodes/rx-dis.c -opcodes/s390-dis.c -opcodes/s390-mkopc.c -opcodes/s390-opc.c -opcodes/s390-opc.txt -opcodes/score-dis.c -opcodes/score-opc.h -opcodes/score7-dis.c -opcodes/sh-dis.c -opcodes/sh-opc.h -opcodes/sh64-dis.c -opcodes/sh64-opc.c -opcodes/sh64-opc.h -opcodes/sparc-dis.c -opcodes/sparc-opc.c -opcodes/spu-dis.c -opcodes/spu-opc.c -opcodes/stamp-h.in -opcodes/tic30-dis.c -opcodes/tic4x-dis.c -opcodes/tic54x-dis.c -opcodes/tic54x-opc.c -opcodes/tic6x-dis.c -opcodes/tic80-dis.c -opcodes/tic80-opc.c -opcodes/tilegx-dis.c -opcodes/tilegx-opc.c -opcodes/tilepro-dis.c -opcodes/tilepro-opc.c -opcodes/v850-dis.c -opcodes/v850-opc.c -opcodes/vax-dis.c -opcodes/w65-dis.c -opcodes/w65-opc.h -opcodes/xc16x-asm.c -opcodes/xc16x-desc.c -opcodes/xc16x-desc.h -opcodes/xc16x-dis.c -opcodes/xc16x-ibld.c -opcodes/xc16x-opc.c -opcodes/xc16x-opc.h -opcodes/xstormy16-asm.c -opcodes/xstormy16-desc.c -opcodes/xstormy16-desc.h -opcodes/xstormy16-dis.c -opcodes/xstormy16-ibld.c -opcodes/xstormy16-opc.c -opcodes/xstormy16-opc.h -opcodes/xtensa-dis.c -opcodes/z80-dis.c -opcodes/z8k-dis.c -opcodes/z8k-opc.h -opcodes/z8kgen.c -setup.com -src-release -symlink-tree -texinfo/ -ylwrap diff --git a/contrib/binutils-2.22/README.DRAGONFLY b/contrib/binutils-2.22/README.DRAGONFLY deleted file mode 100644 index d077726efe..0000000000 --- a/contrib/binutils-2.22/README.DRAGONFLY +++ /dev/null @@ -1,18 +0,0 @@ - GNU BINUTILS 2.22 -===================== -Original source can be downloaded from: -http://ftp.gnu.org/gnu/binutils - -file = binutils-2.22.tar.bz2 -date = 21 November 2011 -size = 19973532 -sha1 = 65b304a0b9a53a686ce50a01173d1f40f8efe404 - -A list of files and directories removed is in README.DELETED - -Local modifications applied to following files: - bfd/bfdver.h (new) - gold/i386.cc - gold/options.cc - gold/x86_64.cc - ld/ldlex.l diff --git a/contrib/binutils-2.22/bfd/COPYING b/contrib/binutils-2.22/bfd/COPYING deleted file mode 100644 index 94a9ed024d..0000000000 --- a/contrib/binutils-2.22/bfd/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - 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 --git a/contrib/binutils-2.22/bfd/README b/contrib/binutils-2.22/bfd/README deleted file mode 100644 index fe6b6f33c1..0000000000 --- a/contrib/binutils-2.22/bfd/README +++ /dev/null @@ -1,49 +0,0 @@ -BFD is an object file library. It permits applications to use the -same routines to process object files regardless of their format. - -BFD is used by the GNU debugger, assembler, linker, and the binary -utilities. - -The documentation on using BFD is scanty and may be occasionally -incorrect. Pointers to documentation problems, or an entirely -rewritten manual, would be appreciated. - -There is some BFD internals documentation in doc/bfdint.texi which may -help programmers who want to modify BFD. - -BFD is normally built as part of another package. See the build -instructions for that package, probably in a README file in the -appropriate directory. - -BFD supports the following configure options: - - --target=TARGET - The default target for which to build the library. TARGET is - a configuration target triplet, such as sparc-sun-solaris. - --enable-targets=TARGET,TARGET,TARGET... - Additional targets the library should support. To include - support for all known targets, use --enable-targets=all. - --enable-64-bit-bfd - Include support for 64 bit targets. This is automatically - turned on if you explicitly request a 64 bit target, but not - for --enable-targets=all. This requires a compiler with a 64 - bit integer type, such as gcc. - --enable-shared - Build BFD as a shared library. - --with-mmap - Use mmap when accessing files. This is faster on some hosts, - but slower on others. It may not work on all hosts. - -Report bugs with BFD to bug-binutils@gnu.org. - -Patches are encouraged. When sending patches, always send the output -of diff -u or diff -c from the original file to the new file. Do not -send default diff output. Do not make the diff from the new file to -the original file. Remember that any patch must not break other -systems. Remember that BFD must support cross compilation from any -host to any target, so patches which use ``#ifdef HOST'' are not -acceptable. Please also read the ``Reporting Bugs'' section of the -gcc manual. - -Bug reports without patches will be remembered, but they may never get -fixed until somebody volunteers to fix them. diff --git a/contrib/binutils-2.22/bfd/archive.c b/contrib/binutils-2.22/bfd/archive.c deleted file mode 100644 index 3e333c7e89..0000000000 --- a/contrib/binutils-2.22/bfd/archive.c +++ /dev/null @@ -1,2634 +0,0 @@ -/* BFD back-end for archive files (libraries). - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* -@setfilename archive-info -SECTION - Archives - -DESCRIPTION - An archive (or library) is just another BFD. It has a symbol - table, although there's not much a user program will do with it. - - The big difference between an archive BFD and an ordinary BFD - is that the archive doesn't have sections. Instead it has a - chain of BFDs that are considered its contents. These BFDs can - be manipulated like any other. The BFDs contained in an - archive opened for reading will all be opened for reading. You - may put either input or output BFDs into an archive opened for - output; they will be handled correctly when the archive is closed. - - Use <> to step through - the contents of an archive opened for input. You don't - have to read the entire archive if you don't want - to! Read it until you find what you want. - - Archive contents of output BFDs are chained through the - <> pointer in a BFD. The first one is findable through - the <> slot of the archive. Set it with - <> (q.v.). A given BFD may be in only one - open output archive at a time. - - As expected, the BFD archive code is more general than the - archive code of any given environment. BFD archives may - contain files of different formats (e.g., a.out and coff) and - even different architectures. You may even place archives - recursively into archives! - - This can cause unexpected confusion, since some archive - formats are more expressive than others. For instance, Intel - COFF archives can preserve long filenames; SunOS a.out archives - cannot. If you move a file from the first to the second - format and back again, the filename may be truncated. - Likewise, different a.out environments have different - conventions as to how they truncate filenames, whether they - preserve directory names in filenames, etc. When - interoperating with native tools, be sure your files are - homogeneous. - - Beware: most of these formats do not react well to the - presence of spaces in filenames. We do the best we can, but - can't always handle this case due to restrictions in the format of - archives. Many Unix utilities are braindead in regards to - spaces and such in filenames anyway, so this shouldn't be much - of a restriction. - - Archives are supported in BFD in <>. - -SUBSECTION - Archive functions -*/ - -/* Assumes: - o - all archive elements start on an even boundary, newline padded; - o - all arch headers are char *; - o - all arch headers are the same size (across architectures). -*/ - -/* Some formats provide a way to cram a long filename into the short - (16 chars) space provided by a BSD archive. The trick is: make a - special "file" in the front of the archive, sort of like the SYMDEF - entry. If the filename is too long to fit, put it in the extended - name table, and use its index as the filename. To prevent - confusion prepend the index with a space. This means you can't - have filenames that start with a space, but then again, many Unix - utilities can't handle that anyway. - - This scheme unfortunately requires that you stand on your head in - order to write an archive since you need to put a magic file at the - front, and need to touch every entry to do so. C'est la vie. - - We support two variants of this idea: - The SVR4 format (extended name table is named "//"), - and an extended pseudo-BSD variant (extended name table is named - "ARFILENAMES/"). The origin of the latter format is uncertain. - - BSD 4.4 uses a third scheme: It writes a long filename - directly after the header. This allows 'ar q' to work. -*/ - -/* Summary of archive member names: - - Symbol table (must be first): - "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib. - "/ " - Symbol table, system 5 style. - - Long name table (must be before regular file members): - "// " - Long name table, System 5 R4 style. - "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4). - - Regular file members with short names: - "filename.o/ " - Regular file, System 5 style (embedded spaces ok). - "filename.o " - Regular file, Berkeley style (no embedded spaces). - - Regular files with long names (or embedded spaces, for BSD variants): - "/18 " - SVR4 style, name at offset 18 in name table. - "#1/23 " - Long name (or embedded spaces) 23 characters long, - BSD 4.4 style, full name follows header. - " 18 " - Long name 18 characters long, extended pseudo-BSD. - */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "libbfd.h" -#include "aout/ar.h" -#include "aout/ranlib.h" -#include "safe-ctype.h" -#include "hashtab.h" -#include "filenames.h" - -#ifndef errno -extern int errno; -#endif - -/* We keep a cache of archive filepointers to archive elements to - speed up searching the archive by filepos. We only add an entry to - the cache when we actually read one. We also don't sort the cache; - it's generally short enough to search linearly. - Note that the pointers here point to the front of the ar_hdr, not - to the front of the contents! */ -struct ar_cache { - file_ptr ptr; - bfd *arbfd; -}; - -#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char) -#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen) - -#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) -#define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata (bfd)->arch_header) - -/* True iff NAME designated a BSD 4.4 extended name. */ - -#define is_bsd44_extended_name(NAME) \ - (NAME[0] == '#' && NAME[1] == '1' && NAME[2] == '/' && ISDIGIT (NAME[3])) - -void -_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val) -{ - static char buf[20]; - size_t len; - snprintf (buf, sizeof (buf), fmt, val); - len = strlen (buf); - if (len < n) - { - memcpy (p, buf, len); - memset (p + len, ' ', n - len); - } - else - memcpy (p, buf, n); -} - -bfd_boolean -_bfd_generic_mkarchive (bfd *abfd) -{ - bfd_size_type amt = sizeof (struct artdata); - - abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt); - if (bfd_ardata (abfd) == NULL) - return FALSE; - - /* Already cleared by bfd_zalloc above. - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->extended_names_size = 0; - bfd_ardata (abfd)->tdata = NULL; */ - - return TRUE; -} - -/* -FUNCTION - bfd_get_next_mapent - -SYNOPSIS - symindex bfd_get_next_mapent - (bfd *abfd, symindex previous, carsym **sym); - -DESCRIPTION - Step through archive @var{abfd}'s symbol table (if it - has one). Successively update @var{sym} with the next symbol's - information, returning that symbol's (internal) index into the - symbol table. - - Supply <> as the @var{previous} entry to get - the first one; returns <> when you've already - got the last one. - - A <> is a canonical archive symbol. The only - user-visible element is its name, a null-terminated string. -*/ - -symindex -bfd_get_next_mapent (bfd *abfd, symindex prev, carsym **entry) -{ - if (!bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return BFD_NO_MORE_SYMBOLS; - } - - if (prev == BFD_NO_MORE_SYMBOLS) - prev = 0; - else - ++prev; - if (prev >= bfd_ardata (abfd)->symdef_count) - return BFD_NO_MORE_SYMBOLS; - - *entry = (bfd_ardata (abfd)->symdefs + prev); - return prev; -} - -/* To be called by backends only. */ - -bfd * -_bfd_create_empty_archive_element_shell (bfd *obfd) -{ - return _bfd_new_bfd_contained_in (obfd); -} - -/* -FUNCTION - bfd_set_archive_head - -SYNOPSIS - bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); - -DESCRIPTION - Set the head of the chain of - BFDs contained in the archive @var{output} to @var{new_head}. -*/ - -bfd_boolean -bfd_set_archive_head (bfd *output_archive, bfd *new_head) -{ - output_archive->archive_head = new_head; - return TRUE; -} - -bfd * -_bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos) -{ - htab_t hash_table = bfd_ardata (arch_bfd)->cache; - struct ar_cache m; - m.ptr = filepos; - - if (hash_table) - { - struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m); - if (!entry) - return NULL; - else - return entry->arbfd; - } - else - return NULL; -} - -static hashval_t -hash_file_ptr (const PTR p) -{ - return (hashval_t) (((struct ar_cache *) p)->ptr); -} - -/* Returns non-zero if P1 and P2 are equal. */ - -static int -eq_file_ptr (const PTR p1, const PTR p2) -{ - struct ar_cache *arc1 = (struct ar_cache *) p1; - struct ar_cache *arc2 = (struct ar_cache *) p2; - return arc1->ptr == arc2->ptr; -} - -/* The calloc function doesn't always take size_t (e.g. on VMS) - so wrap it to avoid a compile time warning. */ - -static void * -_bfd_calloc_wrapper (size_t a, size_t b) -{ - return calloc (a, b); -} - -/* Kind of stupid to call cons for each one, but we don't do too many. */ - -bfd_boolean -_bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt) -{ - struct ar_cache *cache; - htab_t hash_table = bfd_ardata (arch_bfd)->cache; - - /* If the hash table hasn't been created, create it. */ - if (hash_table == NULL) - { - hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr, - NULL, _bfd_calloc_wrapper, free); - if (hash_table == NULL) - return FALSE; - bfd_ardata (arch_bfd)->cache = hash_table; - } - - /* Insert new_elt into the hash table by filepos. */ - cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache)); - cache->ptr = filepos; - cache->arbfd = new_elt; - *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache; - - return TRUE; -} - -static bfd * -_bfd_find_nested_archive (bfd *arch_bfd, const char *filename) -{ - bfd *abfd; - const char *target; - - for (abfd = arch_bfd->nested_archives; - abfd != NULL; - abfd = abfd->archive_next) - { - if (filename_cmp (filename, abfd->filename) == 0) - return abfd; - } - target = NULL; - if (!arch_bfd->target_defaulted) - target = arch_bfd->xvec->name; - abfd = bfd_openr (filename, target); - if (abfd) - { - abfd->archive_next = arch_bfd->nested_archives; - arch_bfd->nested_archives = abfd; - } - return abfd; -} - -/* The name begins with space. Hence the rest of the name is an index into - the string table. */ - -static char * -get_extended_arelt_filename (bfd *arch, const char *name, file_ptr *originp) -{ - unsigned long table_index = 0; - const char *endp; - - /* Should extract string so that I can guarantee not to overflow into - the next region, but I'm too lazy. */ - errno = 0; - /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */ - table_index = strtol (name + 1, (char **) &endp, 10); - if (errno != 0 || table_index >= bfd_ardata (arch)->extended_names_size) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - /* In a thin archive, a member of an archive-within-an-archive - will have the offset in the inner archive encoded here. */ - if (bfd_is_thin_archive (arch) && endp != NULL && *endp == ':') - { - file_ptr origin = strtol (endp + 1, NULL, 10); - - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - *originp = origin; - } - else - *originp = 0; - - return bfd_ardata (arch)->extended_names + table_index; -} - -/* This functions reads an arch header and returns an areltdata pointer, or - NULL on error. - - Presumes the file pointer is already in the right place (ie pointing - to the ar_hdr in the file). Moves the file pointer; on success it - should be pointing to the front of the file contents; on failure it - could have been moved arbitrarily. */ - -void * -_bfd_generic_read_ar_hdr (bfd *abfd) -{ - return _bfd_generic_read_ar_hdr_mag (abfd, NULL); -} - -/* Alpha ECOFF uses an optional different ARFMAG value, so we have a - variant of _bfd_generic_read_ar_hdr which accepts a magic string. */ - -void * -_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag) -{ - struct ar_hdr hdr; - char *hdrp = (char *) &hdr; - size_t parsed_size; - struct areltdata *ared; - char *filename = NULL; - bfd_size_type namelen = 0; - bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr); - char *allocptr = 0; - file_ptr origin = 0; - unsigned int extra_size = 0; - - if (bfd_bread (hdrp, sizeof (struct ar_hdr), abfd) != sizeof (struct ar_hdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0 - && (mag == NULL - || strncmp (hdr.ar_fmag, mag, 2) != 0)) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - errno = 0; - parsed_size = strtol (hdr.ar_size, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - /* Extract the filename from the archive - there are two ways to - specify an extended name table, either the first char of the - name is a space, or it's a slash. */ - if ((hdr.ar_name[0] == '/' - || (hdr.ar_name[0] == ' ' - && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL)) - && bfd_ardata (abfd)->extended_names != NULL) - { - filename = get_extended_arelt_filename (abfd, hdr.ar_name, &origin); - if (filename == NULL) - return NULL; - } - /* BSD4.4-style long filename. */ - else if (is_bsd44_extended_name (hdr.ar_name)) - { - /* BSD-4.4 extended name */ - namelen = atoi (&hdr.ar_name[3]); - allocsize += namelen + 1; - parsed_size -= namelen; - extra_size = namelen; - - allocptr = (char *) bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - return NULL; - filename = (allocptr - + sizeof (struct areltdata) - + sizeof (struct ar_hdr)); - if (bfd_bread (filename, namelen, abfd) != namelen) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - filename[namelen] = '\0'; - } - else - { - /* We judge the end of the name by looking for '/' or ' '. - Note: The SYSV format (terminated by '/') allows embedded - spaces, so only look for ' ' if we don't find '/'. */ - - char *e; - e = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd)); - if (e == NULL) - { - e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)); - if (e == NULL) - e = (char *) memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd)); - } - - if (e != NULL) - namelen = e - hdr.ar_name; - else - { - /* If we didn't find a termination character, then the name - must be the entire field. */ - namelen = ar_maxnamelen (abfd); - } - - allocsize += namelen + 1; - } - - if (!allocptr) - { - allocptr = (char *) bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - return NULL; - } - - ared = (struct areltdata *) allocptr; - - ared->arch_header = allocptr + sizeof (struct areltdata); - memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr)); - ared->parsed_size = parsed_size; - ared->extra_size = extra_size; - ared->origin = origin; - - if (filename != NULL) - ared->filename = filename; - else - { - ared->filename = allocptr + (sizeof (struct areltdata) + - sizeof (struct ar_hdr)); - if (namelen) - memcpy (ared->filename, hdr.ar_name, namelen); - ared->filename[namelen] = '\0'; - } - - return ared; -} - -/* Append the relative pathname for a member of the thin archive - to the pathname of the directory containing the archive. */ - -char * -_bfd_append_relative_path (bfd *arch, char *elt_name) -{ - const char *arch_name = arch->filename; - const char *base_name = lbasename (arch_name); - size_t prefix_len; - char *filename; - - if (base_name == arch_name) - return elt_name; - - prefix_len = base_name - arch_name; - filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1); - if (filename == NULL) - return NULL; - - strncpy (filename, arch_name, prefix_len); - strcpy (filename + prefix_len, elt_name); - return filename; -} - -/* This is an internal function; it's mainly used when indexing - through the archive symbol table, but also used to get the next - element, since it handles the bookkeeping so nicely for us. */ - -bfd * -_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) -{ - struct areltdata *new_areldata; - bfd *n_nfd; - char *filename; - - if (archive->my_archive) - { - filepos += archive->origin; - archive = archive->my_archive; - } - - n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); - if (n_nfd) - return n_nfd; - - if (0 > bfd_seek (archive, filepos, SEEK_SET)) - return NULL; - - if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL) - return NULL; - - filename = new_areldata->filename; - - if (bfd_is_thin_archive (archive)) - { - const char *target; - - /* This is a proxy entry for an external file. */ - if (! IS_ABSOLUTE_PATH (filename)) - { - filename = _bfd_append_relative_path (archive, filename); - if (filename == NULL) - return NULL; - } - - if (new_areldata->origin > 0) - { - /* This proxy entry refers to an element of a nested archive. - Locate the member of that archive and return a bfd for it. */ - bfd *ext_arch = _bfd_find_nested_archive (archive, filename); - - if (ext_arch == NULL - || ! bfd_check_format (ext_arch, bfd_archive)) - { - bfd_release (archive, new_areldata); - return NULL; - } - n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin); - if (n_nfd == NULL) - { - bfd_release (archive, new_areldata); - return NULL; - } - n_nfd->proxy_origin = bfd_tell (archive); - return n_nfd; - } - /* It's not an element of a nested archive; - open the external file as a bfd. */ - target = NULL; - if (!archive->target_defaulted) - target = archive->xvec->name; - n_nfd = bfd_openr (filename, target); - if (n_nfd == NULL) - bfd_set_error (bfd_error_malformed_archive); - } - else - { - n_nfd = _bfd_create_empty_archive_element_shell (archive); - } - - if (n_nfd == NULL) - { - bfd_release (archive, new_areldata); - return NULL; - } - - n_nfd->proxy_origin = bfd_tell (archive); - - if (bfd_is_thin_archive (archive)) - { - n_nfd->origin = 0; - } - else - { - n_nfd->origin = n_nfd->proxy_origin; - n_nfd->filename = filename; - } - - n_nfd->arelt_data = new_areldata; - - /* Copy BFD_COMPRESS and BFD_DECOMPRESS flags. */ - n_nfd->flags |= archive->flags & (BFD_COMPRESS | BFD_DECOMPRESS); - - if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd)) - return n_nfd; - - bfd_release (archive, new_areldata); - return NULL; -} - -/* Return the BFD which is referenced by the symbol in ABFD indexed by - SYM_INDEX. SYM_INDEX should have been returned by bfd_get_next_mapent. */ - -bfd * -_bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index) -{ - carsym *entry; - - entry = bfd_ardata (abfd)->symdefs + sym_index; - return _bfd_get_elt_at_filepos (abfd, entry->file_offset); -} - -/* -FUNCTION - bfd_openr_next_archived_file - -SYNOPSIS - bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); - -DESCRIPTION - Provided a BFD, @var{archive}, containing an archive and NULL, open - an input BFD on the first contained element and returns that. - Subsequent calls should pass - the archive and the previous return value to return a created - BFD to the next contained element. NULL is returned when there - are no more. -*/ - -bfd * -bfd_openr_next_archived_file (bfd *archive, bfd *last_file) -{ - if ((bfd_get_format (archive) != bfd_archive) - || (archive->direction == write_direction)) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - return BFD_SEND (archive, - openr_next_archived_file, (archive, last_file)); -} - -bfd * -bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file) -{ - file_ptr filestart; - - if (!last_file) - filestart = bfd_ardata (archive)->first_file_filepos; - else - { - unsigned int size = arelt_size (last_file); - - filestart = last_file->proxy_origin; - if (! bfd_is_thin_archive (archive)) - filestart += size; - if (archive->my_archive) - filestart -= archive->origin; - /* Pad to an even boundary... - Note that last_file->origin can be odd in the case of - BSD-4.4-style element with a long odd size. */ - filestart += filestart % 2; - } - - return _bfd_get_elt_at_filepos (archive, filestart); -} - -const bfd_target * -bfd_generic_archive_p (bfd *abfd) -{ - struct artdata *tdata_hold; - char armag[SARMAG + 1]; - bfd_size_type amt; - - if (bfd_bread (armag, SARMAG, abfd) != SARMAG) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - bfd_is_thin_archive (abfd) = (strncmp (armag, ARMAGT, SARMAG) == 0); - - if (strncmp (armag, ARMAG, SARMAG) != 0 - && strncmp (armag, ARMAGB, SARMAG) != 0 - && ! bfd_is_thin_archive (abfd)) - return NULL; - - tdata_hold = bfd_ardata (abfd); - - amt = sizeof (struct artdata); - bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt); - if (bfd_ardata (abfd) == NULL) - { - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - /* Cleared by bfd_zalloc above. - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->extended_names_size = 0; - bfd_ardata (abfd)->tdata = NULL; */ - - if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)) - || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - bfd_release (abfd, bfd_ardata (abfd)); - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - - if (abfd->target_defaulted && bfd_has_map (abfd)) - { - bfd *first; - - /* This archive has a map, so we may presume that the contents - are object files. Make sure that if the first file in the - archive can be recognized as an object file, it is for this - target. If not, assume that this is the wrong format. If - the first file is not an object file, somebody is doing - something weird, and we permit it so that ar -t will work. - - This is done because any normal format will recognize any - normal archive, regardless of the format of the object files. - We do accept an empty archive. */ - - first = bfd_openr_next_archived_file (abfd, NULL); - if (first != NULL) - { - first->target_defaulted = FALSE; - if (bfd_check_format (first, bfd_object) - && first->xvec != abfd->xvec) - { - bfd_set_error (bfd_error_wrong_object_format); - bfd_ardata (abfd) = tdata_hold; - return NULL; - } - /* And we ought to close `first' here too. */ - } - } - - return abfd->xvec; -} - -/* Some constants for a 32 bit BSD archive structure. We do not - support 64 bit archives presently; so far as I know, none actually - exist. Supporting them would require changing these constants, and - changing some H_GET_32 to H_GET_64. */ - -/* The size of an external symdef structure. */ -#define BSD_SYMDEF_SIZE 8 - -/* The offset from the start of a symdef structure to the file offset. */ -#define BSD_SYMDEF_OFFSET_SIZE 4 - -/* The size of the symdef count. */ -#define BSD_SYMDEF_COUNT_SIZE 4 - -/* The size of the string count. */ -#define BSD_STRING_COUNT_SIZE 4 - -/* Read a BSD-style archive symbol table. Returns FALSE on error, - TRUE otherwise. */ - -static bfd_boolean -do_slurp_bsd_armap (bfd *abfd) -{ - struct areltdata *mapdata; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - bfd_size_type parsed_size, amt; - carsym *set; - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return FALSE; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, mapdata); /* Don't need it any more. */ - - raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); - if (raw_armap == NULL) - return FALSE; - - if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - byebye: - bfd_release (abfd, raw_armap); - return FALSE; - } - - ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; - - if (ardata->symdef_count * BSD_SYMDEF_SIZE > - parsed_size - BSD_SYMDEF_COUNT_SIZE) - { - /* Probably we're using the wrong byte ordering. */ - bfd_set_error (bfd_error_wrong_format); - goto byebye; - } - - ardata->cache = 0; - rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE; - stringbase = ((char *) rbase - + ardata->symdef_count * BSD_SYMDEF_SIZE - + BSD_STRING_COUNT_SIZE); - amt = ardata->symdef_count * sizeof (carsym); - ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt); - if (!ardata->symdefs) - return FALSE; - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = H_GET_32 (abfd, rbase) + stringbase; - set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to. */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an objalloc anyway... */ - bfd_has_map (abfd) = TRUE; - return TRUE; -} - -/* Read a COFF archive symbol table. Returns FALSE on error, TRUE - otherwise. */ - -static bfd_boolean -do_slurp_coff_armap (bfd *abfd) -{ - struct areltdata *mapdata; - int *raw_armap, *rawptr; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - bfd_size_type stringsize; - unsigned int parsed_size; - carsym *carsyms; - bfd_size_type nsymz; /* Number of symbols in armap. */ - bfd_vma (*swap) (const void *); - char int_buf[sizeof (long)]; - bfd_size_type carsym_size, ptrsize; - unsigned int i; - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return FALSE; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, mapdata); /* Don't need it any more. */ - - if (bfd_bread (int_buf, 4, abfd) != 4) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return FALSE; - } - /* It seems that all numeric information in a coff archive is always - in big endian format, nomatter the host or target. */ - swap = bfd_getb32; - nsymz = bfd_getb32 (int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - - /* ... except that some archive formats are broken, and it may be our - fault - the i960 little endian coff sometimes has big and sometimes - little, because our tools changed. Here's a horrible hack to clean - up the crap. */ - - if (stringsize > 0xfffff - && bfd_get_arch (abfd) == bfd_arch_i960 - && bfd_get_flavour (abfd) == bfd_target_coff_flavour) - { - /* This looks dangerous, let's do it the other way around. */ - nsymz = bfd_getl32 (int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - swap = bfd_getl32; - } - - /* The coff armap must be read sequentially. So we construct a - bsd-style one in core all at once, for simplicity. */ - - if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym)) - return FALSE; - - carsym_size = (nsymz * sizeof (carsym)); - ptrsize = (4 * nsymz); - - if (carsym_size + stringsize + 1 <= carsym_size) - return FALSE; - - ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, - carsym_size + stringsize + 1); - if (ardata->symdefs == NULL) - return FALSE; - carsyms = ardata->symdefs; - stringbase = ((char *) ardata->symdefs) + carsym_size; - - /* Allocate and read in the raw offsets. */ - raw_armap = (int *) bfd_alloc (abfd, ptrsize); - if (raw_armap == NULL) - goto release_symdefs; - if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize - || (bfd_bread (stringbase, stringsize, abfd) != stringsize)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - goto release_raw_armap; - } - - /* OK, build the carsyms. */ - for (i = 0; i < nsymz; i++) - { - rawptr = raw_armap + i; - carsyms->file_offset = swap ((bfd_byte *) rawptr); - carsyms->name = stringbase; - stringbase += strlen (stringbase) + 1; - carsyms++; - } - *stringbase = 0; - - ardata->symdef_count = nsymz; - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to. */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - - bfd_has_map (abfd) = TRUE; - bfd_release (abfd, raw_armap); - - /* Check for a second archive header (as used by PE). */ - { - struct areltdata *tmp; - - bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET); - tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (tmp != NULL) - { - if (tmp->arch_header[0] == '/' - && tmp->arch_header[1] == ' ') - { - ardata->first_file_filepos += - (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1; - } - bfd_release (abfd, tmp); - } - } - - return TRUE; - -release_raw_armap: - bfd_release (abfd, raw_armap); -release_symdefs: - bfd_release (abfd, (ardata)->symdefs); - return FALSE; -} - -/* This routine can handle either coff-style or bsd-style armaps - (archive symbol table). Returns FALSE on error, TRUE otherwise */ - -bfd_boolean -bfd_slurp_armap (bfd *abfd) -{ - char nextname[17]; - int i = bfd_bread (nextname, 16, abfd); - - if (i == 0) - return TRUE; - if (i != 16) - return FALSE; - - if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) - return FALSE; - - if (CONST_STRNEQ (nextname, "__.SYMDEF ") - || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */ - return do_slurp_bsd_armap (abfd); - else if (CONST_STRNEQ (nextname, "/ ")) - return do_slurp_coff_armap (abfd); - else if (CONST_STRNEQ (nextname, "/SYM64/ ")) - { - /* 64bit ELF (Irix 6) archive. */ -#ifdef BFD64 - extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *); - return bfd_elf64_archive_slurp_armap (abfd); -#else - bfd_set_error (bfd_error_wrong_format); - return FALSE; -#endif - } - else if (CONST_STRNEQ (nextname, "#1/20 ")) - { - /* Mach-O has a special name for armap when the map is sorted by name. - However because this name has a space it is slightly more difficult - to check it. */ - struct ar_hdr hdr; - char extname[21]; - - if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr)) - return FALSE; - /* Read the extended name. We know its length. */ - if (bfd_bread (extname, 20, abfd) != 20) - return FALSE; - if (bfd_seek (abfd, (file_ptr) -(sizeof (hdr) + 20), SEEK_CUR) != 0) - return FALSE; - if (CONST_STRNEQ (extname, "__.SYMDEF SORTED") - || CONST_STRNEQ (extname, "__.SYMDEF")) - return do_slurp_bsd_armap (abfd); - } - - bfd_has_map (abfd) = FALSE; - return TRUE; -} - -/* Returns FALSE on error, TRUE otherwise. */ -/* Flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the - header is in a slightly different order and the map name is '/'. - This flavour is used by hp300hpux. */ - -#define HPUX_SYMDEF_COUNT_SIZE 2 - -bfd_boolean -bfd_slurp_bsd_armap_f2 (bfd *abfd) -{ - struct areltdata *mapdata; - char nextname[17]; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int stringsize; - unsigned int left; - bfd_size_type amt; - carsym *set; - int i = bfd_bread (nextname, 16, abfd); - - if (i == 0) - return TRUE; - if (i != 16) - return FALSE; - - /* The archive has at least 16 bytes in it. */ - if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) - return FALSE; - - if (CONST_STRNEQ (nextname, "__.SYMDEF ") - || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */ - return do_slurp_bsd_armap (abfd); - - if (! CONST_STRNEQ (nextname, "/ ")) - { - bfd_has_map (abfd) = FALSE; - return TRUE; - } - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return FALSE; - - if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE) - { - wrong_format: - bfd_set_error (bfd_error_wrong_format); - byebye: - bfd_release (abfd, mapdata); - return FALSE; - } - left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE; - - amt = mapdata->parsed_size; - raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt); - if (raw_armap == NULL) - goto byebye; - - if (bfd_bread (raw_armap, amt, abfd) != amt) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - goto byebye; - } - - ardata->symdef_count = H_GET_16 (abfd, raw_armap); - - ardata->cache = 0; - - stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE); - if (stringsize > left) - goto wrong_format; - left -= stringsize; - - /* Skip sym count and string sz. */ - stringbase = ((char *) raw_armap - + HPUX_SYMDEF_COUNT_SIZE - + BSD_STRING_COUNT_SIZE); - rbase = (bfd_byte *) stringbase + stringsize; - amt = ardata->symdef_count * BSD_SYMDEF_SIZE; - if (amt > left) - goto wrong_format; - - ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt); - if (!ardata->symdefs) - return FALSE; - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = H_GET_32 (abfd, rbase) + stringbase; - set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to. */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an objalloc anyway... */ - bfd_has_map (abfd) = TRUE; - return TRUE; -} - -/** Extended name table. - - Normally archives support only 14-character filenames. - - Intel has extended the format: longer names are stored in a special - element (the first in the archive, or second if there is an armap); - the name in the ar_hdr is replaced by . Index is the P.R. of an int (decimal). Data General have - extended the format by using the prefix // for the special element. */ - -/* Returns FALSE on error, TRUE otherwise. */ - -bfd_boolean -_bfd_slurp_extended_name_table (bfd *abfd) -{ - char nextname[17]; - struct areltdata *namedata; - bfd_size_type amt; - - /* FIXME: Formatting sucks here, and in case of failure of BFD_READ, - we probably don't want to return TRUE. */ - if (bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET) != 0) - return FALSE; - - if (bfd_bread (nextname, 16, abfd) == 16) - { - if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) - return FALSE; - - if (! CONST_STRNEQ (nextname, "ARFILENAMES/ ") - && ! CONST_STRNEQ (nextname, "// ")) - { - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->extended_names_size = 0; - return TRUE; - } - - namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (namedata == NULL) - return FALSE; - - amt = namedata->parsed_size; - if (amt + 1 == 0) - goto byebye; - - bfd_ardata (abfd)->extended_names_size = amt; - bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1); - if (bfd_ardata (abfd)->extended_names == NULL) - { - byebye: - bfd_release (abfd, namedata); - return FALSE; - } - - if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (bfd_ardata (abfd)->extended_names)); - bfd_ardata (abfd)->extended_names = NULL; - goto byebye; - } - - /* Since the archive is supposed to be printable if it contains - text, the entries in the list are newline-padded, not null - padded. In SVR4-style archives, the names also have a - trailing '/'. DOS/NT created archive often have \ in them - We'll fix all problems here.. */ - { - char *ext_names = bfd_ardata (abfd)->extended_names; - char *temp = ext_names; - char *limit = temp + namedata->parsed_size; - for (; temp < limit; ++temp) - { - if (*temp == ARFMAG[1]) - temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0'; - if (*temp == '\\') - *temp = '/'; - } - *limit = '\0'; - } - - /* Pad to an even boundary if you have to. */ - bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd); - bfd_ardata (abfd)->first_file_filepos += - (bfd_ardata (abfd)->first_file_filepos) % 2; - - /* FIXME, we can't release namedata here because it was allocated - below extended_names on the objalloc... */ - } - return TRUE; -} - -#ifdef VMS - -/* Return a copy of the stuff in the filename between any :]> and a - semicolon. */ - -static const char * -normalize (bfd *abfd, const char *file) -{ - const char *first; - const char *last; - char *copy; - - first = file + strlen (file) - 1; - last = first + 1; - - while (first != file) - { - if (*first == ';') - last = first; - if (*first == ':' || *first == ']' || *first == '>') - { - first++; - break; - } - first--; - } - - copy = bfd_alloc (abfd, last - first + 1); - if (copy == NULL) - return NULL; - - memcpy (copy, first, last - first); - copy[last - first] = 0; - - return copy; -} - -#else -static const char * -normalize (bfd *abfd ATTRIBUTE_UNUSED, const char *file) -{ - return lbasename (file); -} -#endif - -/* Adjust a relative path name based on the reference path. - For example: - - Relative path Reference path Result - ------------- -------------- ------ - bar.o lib.a bar.o - foo/bar.o lib.a foo/bar.o - bar.o foo/lib.a ../bar.o - foo/bar.o baz/lib.a ../foo/bar.o - bar.o ../lib.a /bar.o - ; ../bar.o ../lib.a bar.o - ; ../bar.o lib.a ../bar.o - foo/bar.o ../lib.a /foo/bar.o - bar.o ../../lib.a //bar.o - bar.o foo/baz/lib.a ../../bar.o - - Note - the semicolons above are there to prevent the BFD chew - utility from interpreting those lines as prototypes to put into - the autogenerated bfd.h header... - - Note - the string is returned in a static buffer. */ - -static const char * -adjust_relative_path (const char * path, const char * ref_path) -{ - static char *pathbuf = NULL; - static unsigned int pathbuf_len = 0; - const char *pathp; - const char *refp; - char * lpath; - char * rpath; - unsigned int len; - unsigned int dir_up = 0; - unsigned int dir_down = 0; - char *newp; - char * pwd = getpwd (); - const char * down; - - /* Remove symlinks, '.' and '..' from the paths, if possible. */ - lpath = lrealpath (path); - pathp = lpath == NULL ? path : lpath; - - rpath = lrealpath (ref_path); - refp = rpath == NULL ? ref_path : rpath; - - /* Remove common leading path elements. */ - for (;;) - { - const char *e1 = pathp; - const char *e2 = refp; - - while (*e1 && ! IS_DIR_SEPARATOR (*e1)) - ++e1; - while (*e2 && ! IS_DIR_SEPARATOR (*e2)) - ++e2; - if (*e1 == '\0' || *e2 == '\0' || e1 - pathp != e2 - refp - || filename_ncmp (pathp, refp, e1 - pathp) != 0) - break; - pathp = e1 + 1; - refp = e2 + 1; - } - - len = strlen (pathp) + 1; - /* For each leading path element in the reference path, - insert "../" into the path. */ - for (; *refp; ++refp) - if (IS_DIR_SEPARATOR (*refp)) - { - /* PR 12710: If the path element is "../" then instead of - inserting "../" we need to insert the name of the directory - at the current level. */ - if (refp > ref_path + 1 - && refp[-1] == '.' - && refp[-2] == '.') - dir_down ++; - else - dir_up ++; - } - - /* If the lrealpath calls above succeeded then we should never - see dir_up and dir_down both being non-zero. */ - - len += 3 * dir_up; - - if (dir_down) - { - down = pwd + strlen (pwd) - 1; - - while (dir_down && down > pwd) - { - if (IS_DIR_SEPARATOR (*down)) - --dir_down; - } - BFD_ASSERT (dir_down == 0); - len += strlen (down) + 1; - } - else - down = NULL; - - if (len > pathbuf_len) - { - if (pathbuf != NULL) - free (pathbuf); - pathbuf_len = 0; - pathbuf = (char *) bfd_malloc (len); - if (pathbuf == NULL) - goto out; - pathbuf_len = len; - } - - newp = pathbuf; - while (dir_up-- > 0) - { - /* FIXME: Support Windows style path separators as well. */ - strcpy (newp, "../"); - newp += 3; - } - - if (down) - sprintf (newp, "%s/%s", down, pathp); - else - strcpy (newp, pathp); - - out: - free (lpath); - free (rpath); - return pathbuf; -} - -/* Build a BFD style extended name table. */ - -bfd_boolean -_bfd_archive_bsd_construct_extended_name_table (bfd *abfd, - char **tabloc, - bfd_size_type *tablen, - const char **name) -{ - *name = "ARFILENAMES/"; - return _bfd_construct_extended_name_table (abfd, FALSE, tabloc, tablen); -} - -/* Build an SVR4 style extended name table. */ - -bfd_boolean -_bfd_archive_coff_construct_extended_name_table (bfd *abfd, - char **tabloc, - bfd_size_type *tablen, - const char **name) -{ - *name = "//"; - return _bfd_construct_extended_name_table (abfd, TRUE, tabloc, tablen); -} - -/* Follows archive_head and produces an extended name table if - necessary. Returns (in tabloc) a pointer to an extended name - table, and in tablen the length of the table. If it makes an entry - it clobbers the filename so that the element may be written without - further massage. Returns TRUE if it ran successfully, FALSE if - something went wrong. A successful return may still involve a - zero-length tablen! */ - -bfd_boolean -_bfd_construct_extended_name_table (bfd *abfd, - bfd_boolean trailing_slash, - char **tabloc, - bfd_size_type *tablen) -{ - unsigned int maxname = ar_maxnamelen (abfd); - bfd_size_type total_namelen = 0; - bfd *current; - char *strptr; - const char *last_filename; - long last_stroff; - - *tablen = 0; - last_filename = NULL; - - /* Figure out how long the table should be. */ - for (current = abfd->archive_head; - current != NULL; - current = current->archive_next) - { - const char *normal; - unsigned int thislen; - - if (bfd_is_thin_archive (abfd)) - { - const char *filename = current->filename; - - /* If the element being added is a member of another archive - (i.e., we are flattening), use the containing archive's name. */ - if (current->my_archive - && ! bfd_is_thin_archive (current->my_archive)) - filename = current->my_archive->filename; - - /* If the path is the same as the previous path seen, - reuse it. This can happen when flattening a thin - archive that contains other archives. */ - if (last_filename && filename_cmp (last_filename, filename) == 0) - continue; - - last_filename = filename; - - /* If the path is relative, adjust it relative to - the containing archive. */ - if (! IS_ABSOLUTE_PATH (filename) - && ! IS_ABSOLUTE_PATH (abfd->filename)) - normal = adjust_relative_path (filename, abfd->filename); - else - normal = filename; - - /* In a thin archive, always store the full pathname - in the extended name table. */ - total_namelen += strlen (normal) + 1; - if (trailing_slash) - /* Leave room for trailing slash. */ - ++total_namelen; - - continue; - } - - normal = normalize (current, current->filename); - if (normal == NULL) - return FALSE; - - thislen = strlen (normal); - - if (thislen > maxname - && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) - thislen = maxname; - - if (thislen > maxname) - { - /* Add one to leave room for \n. */ - total_namelen += thislen + 1; - if (trailing_slash) - { - /* Leave room for trailing slash. */ - ++total_namelen; - } - } - else - { - struct ar_hdr *hdr = arch_hdr (current); - if (filename_ncmp (normal, hdr->ar_name, thislen) != 0 - || (thislen < sizeof hdr->ar_name - && hdr->ar_name[thislen] != ar_padchar (current))) - { - /* Must have been using extended format even though it - didn't need to. Fix it to use normal format. */ - memcpy (hdr->ar_name, normal, thislen); - if (thislen < maxname - || (thislen == maxname && thislen < sizeof hdr->ar_name)) - hdr->ar_name[thislen] = ar_padchar (current); - } - } - } - - if (total_namelen == 0) - return TRUE; - - *tabloc = (char *) bfd_zalloc (abfd, total_namelen); - if (*tabloc == NULL) - return FALSE; - - *tablen = total_namelen; - strptr = *tabloc; - - last_filename = NULL; - last_stroff = 0; - - for (current = abfd->archive_head; - current != NULL; - current = current->archive_next) - { - const char *normal; - unsigned int thislen; - long stroff; - const char *filename = current->filename; - - if (bfd_is_thin_archive (abfd)) - { - /* If the element being added is a member of another archive - (i.e., we are flattening), use the containing archive's name. */ - if (current->my_archive - && ! bfd_is_thin_archive (current->my_archive)) - filename = current->my_archive->filename; - /* If the path is the same as the previous path seen, - reuse it. This can happen when flattening a thin - archive that contains other archives. - If the path is relative, adjust it relative to - the containing archive. */ - if (last_filename && filename_cmp (last_filename, filename) == 0) - normal = last_filename; - else if (! IS_ABSOLUTE_PATH (filename) - && ! IS_ABSOLUTE_PATH (abfd->filename)) - normal = adjust_relative_path (filename, abfd->filename); - else - normal = filename; - } - else - { - normal = normalize (current, filename); - if (normal == NULL) - return FALSE; - } - - thislen = strlen (normal); - if (thislen > maxname || bfd_is_thin_archive (abfd)) - { - /* Works for now; may need to be re-engineered if we - encounter an oddball archive format and want to - generalise this hack. */ - struct ar_hdr *hdr = arch_hdr (current); - if (normal == last_filename) - stroff = last_stroff; - else - { - strcpy (strptr, normal); - if (! trailing_slash) - strptr[thislen] = ARFMAG[1]; - else - { - strptr[thislen] = '/'; - strptr[thislen + 1] = ARFMAG[1]; - } - stroff = strptr - *tabloc; - last_stroff = stroff; - } - hdr->ar_name[0] = ar_padchar (current); - if (bfd_is_thin_archive (abfd) && current->origin > 0) - { - int len = snprintf (hdr->ar_name + 1, maxname - 1, "%-ld:", - stroff); - _bfd_ar_spacepad (hdr->ar_name + 1 + len, maxname - 1 - len, - "%-ld", - current->origin - sizeof (struct ar_hdr)); - } - else - _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", stroff); - if (normal != last_filename) - { - strptr += thislen + 1; - if (trailing_slash) - ++strptr; - last_filename = filename; - } - } - } - - return TRUE; -} - -/* Do not construct an extended name table but transforms name field into - its extended form. */ - -bfd_boolean -_bfd_archive_bsd44_construct_extended_name_table (bfd *abfd, - char **tabloc, - bfd_size_type *tablen, - const char **name) -{ - unsigned int maxname = ar_maxnamelen (abfd); - bfd *current; - - *tablen = 0; - *tabloc = NULL; - *name = NULL; - - for (current = abfd->archive_head; - current != NULL; - current = current->archive_next) - { - const char *normal = normalize (current, current->filename); - int has_space = 0; - unsigned int len; - - if (normal == NULL) - return FALSE; - - for (len = 0; normal[len]; len++) - if (normal[len] == ' ') - has_space = 1; - - if (len > maxname || has_space) - { - struct ar_hdr *hdr = arch_hdr (current); - - len = (len + 3) & ~3; - arch_eltdata (current)->extra_size = len; - _bfd_ar_spacepad (hdr->ar_name, maxname, "#1/%lu", len); - } - } - - return TRUE; -} - -/* Write an archive header. */ - -bfd_boolean -_bfd_generic_write_ar_hdr (bfd *archive, bfd *abfd) -{ - struct ar_hdr *hdr = arch_hdr (abfd); - - if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) - return FALSE; - return TRUE; -} - -/* Write an archive header using BSD4.4 convention. */ - -bfd_boolean -_bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd) -{ - struct ar_hdr *hdr = arch_hdr (abfd); - - if (is_bsd44_extended_name (hdr->ar_name)) - { - /* This is a BSD 4.4 extended name. */ - const char *fullname = normalize (abfd, abfd->filename); - unsigned int len = strlen (fullname); - unsigned int padded_len = (len + 3) & ~3; - - BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size); - - _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld", - arch_eltdata (abfd)->parsed_size + padded_len); - - if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) - return FALSE; - - if (bfd_bwrite (fullname, len, archive) != len) - return FALSE; - if (len & 3) - { - static const char pad[3] = { 0, 0, 0 }; - - len = 4 - (len & 3); - if (bfd_bwrite (pad, len, archive) != len) - return FALSE; - } - } - else - { - if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr)) - return FALSE; - } - return TRUE; -} - -/* A couple of functions for creating ar_hdrs. */ - -#ifdef HPUX_LARGE_AR_IDS -/* Function to encode large UID/GID values according to HP. */ - -static void -hpux_uid_gid_encode (char str[6], long int id) -{ - int cnt; - - str[5] = '@' + (id & 3); - id >>= 2; - - for (cnt = 4; cnt >= 0; --cnt, id >>= 6) - str[cnt] = ' ' + (id & 0x3f); -} -#endif /* HPUX_LARGE_AR_IDS */ - -#ifndef HAVE_GETUID -#define getuid() 0 -#endif - -#ifndef HAVE_GETGID -#define getgid() 0 -#endif - -/* Takes a filename, returns an arelt_data for it, or NULL if it can't - make one. The filename must refer to a filename in the filesystem. - The filename field of the ar_hdr will NOT be initialized. If member - is set, and it's an in-memory bfd, we fake it. */ - -static struct areltdata * -bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member) -{ - struct stat status; - struct areltdata *ared; - struct ar_hdr *hdr; - bfd_size_type amt; - - if (member && (member->flags & BFD_IN_MEMORY) != 0) - { - /* Assume we just "made" the member, and fake it. */ - struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream; - time (&status.st_mtime); - status.st_uid = getuid (); - status.st_gid = getgid (); - status.st_mode = 0644; - status.st_size = bim->size; - } - else if (stat (filename, &status) != 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* If the caller requested that the BFD generate deterministic output, - fake values for modification time, UID, GID, and file mode. */ - if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0) - { - status.st_mtime = 0; - status.st_uid = 0; - status.st_gid = 0; - status.st_mode = 0644; - } - - amt = sizeof (struct ar_hdr) + sizeof (struct areltdata); - ared = (struct areltdata *) bfd_zalloc (abfd, amt); - if (ared == NULL) - return NULL; - hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata)); - - /* ar headers are space padded, not null padded! */ - memset (hdr, ' ', sizeof (struct ar_hdr)); - - _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld", - status.st_mtime); -#ifdef HPUX_LARGE_AR_IDS - /* HP has a very "special" way to handle UID/GID's with numeric values - > 99999. */ - if (status.st_uid > 99999) - hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid); - else -#endif - _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld", - status.st_uid); -#ifdef HPUX_LARGE_AR_IDS - /* HP has a very "special" way to handle UID/GID's with numeric values - > 99999. */ - if (status.st_gid > 99999) - hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid); - else -#endif - _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld", - status.st_gid); - _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo", - status.st_mode); - _bfd_ar_spacepad (hdr->ar_size, sizeof (hdr->ar_size), "%-10ld", - status.st_size); - memcpy (hdr->ar_fmag, ARFMAG, 2); - ared->parsed_size = status.st_size; - ared->arch_header = (char *) hdr; - - return ared; -} - -/* Analogous to stat call. */ - -int -bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf) -{ - struct ar_hdr *hdr; - char *aloser; - - if (abfd->arelt_data == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - hdr = arch_hdr (abfd); - -#define foo(arelt, stelt, size) \ - buf->stelt = strtol (hdr->arelt, &aloser, size); \ - if (aloser == hdr->arelt) \ - return -1; - - /* Some platforms support special notations for large IDs. */ -#ifdef HPUX_LARGE_AR_IDS -# define foo2(arelt, stelt, size) \ - if (hdr->arelt[5] == ' ') \ - { \ - foo (arelt, stelt, size); \ - } \ - else \ - { \ - int cnt; \ - for (buf->stelt = cnt = 0; cnt < 5; ++cnt) \ - { \ - if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f) \ - return -1; \ - buf->stelt <<= 6; \ - buf->stelt += hdr->arelt[cnt] - ' '; \ - } \ - if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3) \ - return -1; \ - buf->stelt <<= 2; \ - buf->stelt += hdr->arelt[5] - '@'; \ - } -#else -# define foo2(arelt, stelt, size) foo (arelt, stelt, size) -#endif - - foo (ar_date, st_mtime, 10); - foo2 (ar_uid, st_uid, 10); - foo2 (ar_gid, st_gid, 10); - foo (ar_mode, st_mode, 8); - - buf->st_size = arch_eltdata (abfd)->parsed_size; - - return 0; -} - -void -bfd_dont_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) -{ - /* FIXME: This interacts unpleasantly with ar's quick-append option. - Fortunately ic960 users will never use that option. Fixing this - is very hard; fortunately I know how to do it and will do so once - intel's release is out the door. */ - - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - size_t length; - const char *filename; - size_t maxlen = ar_maxnamelen (abfd); - - if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) - { - bfd_bsd_truncate_arname (abfd, pathname, arhdr); - return; - } - - filename = normalize (abfd, pathname); - if (filename == NULL) - { - /* FIXME */ - abort (); - } - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - - /* Add the padding character if there is room for it. */ - if (length < maxlen - || (length == maxlen && length < sizeof hdr->ar_name)) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -void -bfd_bsd_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - size_t length; - const char *filename = lbasename (pathname); - size_t maxlen = ar_maxnamelen (abfd); - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { - /* pathname: meet procrustes */ - memcpy (hdr->ar_name, filename, maxlen); - length = maxlen; - } - - if (length < maxlen) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* Store name into ar header. Truncates the name to fit. - 1> strip pathname to be just the basename. - 2> if it's short enuf to fit, stuff it in. - 3> If it doesn't end with .o, truncate it to fit - 4> truncate it before the .o, append .o, stuff THAT in. */ - -/* This is what gnu ar does. It's better but incompatible with the - bsd ar. */ - -void -bfd_gnu_truncate_arname (bfd *abfd, const char *pathname, char *arhdr) -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - size_t length; - const char *filename = lbasename (pathname); - size_t maxlen = ar_maxnamelen (abfd); - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { - /* pathname: meet procrustes. */ - memcpy (hdr->ar_name, filename, maxlen); - if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) - { - hdr->ar_name[maxlen - 2] = '.'; - hdr->ar_name[maxlen - 1] = 'o'; - } - length = maxlen; - } - - if (length < 16) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* The BFD is open for write and has its format set to bfd_archive. */ - -bfd_boolean -_bfd_write_archive_contents (bfd *arch) -{ - bfd *current; - char *etable = NULL; - bfd_size_type elength = 0; - const char *ename = NULL; - bfd_boolean makemap = bfd_has_map (arch); - /* If no .o's, don't bother to make a map. */ - bfd_boolean hasobjects = FALSE; - bfd_size_type wrote; - int tries; - char *armag; - - /* Verify the viability of all entries; if any of them live in the - filesystem (as opposed to living in an archive open for input) - then construct a fresh ar_hdr for them. */ - for (current = arch->archive_head; - current != NULL; - current = current->archive_next) - { - /* This check is checking the bfds for the objects we're reading - from (which are usually either an object file or archive on - disk), not the archive entries we're writing to. We don't - actually create bfds for the archive members, we just copy - them byte-wise when we write out the archive. */ - if (bfd_write_p (current)) - { - bfd_set_error (bfd_error_invalid_operation); - goto input_err; - } - if (!current->arelt_data) - { - current->arelt_data = - bfd_ar_hdr_from_filesystem (arch, current->filename, current); - if (!current->arelt_data) - goto input_err; - - /* Put in the file name. */ - BFD_SEND (arch, _bfd_truncate_arname, - (arch, current->filename, (char *) arch_hdr (current))); - } - - if (makemap && ! hasobjects) - { /* Don't bother if we won't make a map! */ - if ((bfd_check_format (current, bfd_object))) - hasobjects = TRUE; - } - } - - if (!BFD_SEND (arch, _bfd_construct_extended_name_table, - (arch, &etable, &elength, &ename))) - return FALSE; - - if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0) - return FALSE; - armag = ARMAG; - if (bfd_is_thin_archive (arch)) - armag = ARMAGT; - wrote = bfd_bwrite (armag, SARMAG, arch); - if (wrote != SARMAG) - return FALSE; - - if (makemap && hasobjects) - { - if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength)) - return FALSE; - } - - if (elength != 0) - { - struct ar_hdr hdr; - - memset (&hdr, ' ', sizeof (struct ar_hdr)); - memcpy (hdr.ar_name, ename, strlen (ename)); - /* Round size up to even number in archive header. */ - _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", - (elength + 1) & ~(bfd_size_type) 1); - memcpy (hdr.ar_fmag, ARFMAG, 2); - if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - || bfd_bwrite (etable, elength, arch) != elength) - return FALSE; - if ((elength % 2) == 1) - { - if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1) - return FALSE; - } - } - - for (current = arch->archive_head; - current != NULL; - current = current->archive_next) - { - char buffer[DEFAULT_BUFFERSIZE]; - unsigned int remaining = arelt_size (current); - - /* Write ar header. */ - if (!_bfd_write_ar_hdr (arch, current)) - return FALSE; - if (bfd_is_thin_archive (arch)) - continue; - if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) - goto input_err; - - while (remaining) - { - unsigned int amt = DEFAULT_BUFFERSIZE; - - if (amt > remaining) - amt = remaining; - errno = 0; - if (bfd_bread (buffer, amt, current) != amt) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_file_truncated); - goto input_err; - } - if (bfd_bwrite (buffer, amt, arch) != amt) - return FALSE; - remaining -= amt; - } - - if ((arelt_size (current) % 2) == 1) - { - if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1) - return FALSE; - } - } - - if (makemap && hasobjects) - { - /* Verify the timestamp in the archive file. If it would not be - accepted by the linker, rewrite it until it would be. If - anything odd happens, break out and just return. (The - Berkeley linker checks the timestamp and refuses to read the - table-of-contents if it is >60 seconds less than the file's - modified-time. That painful hack requires this painful hack. */ - tries = 1; - do - { - if (bfd_update_armap_timestamp (arch)) - break; - (*_bfd_error_handler) - (_("Warning: writing archive was slow: rewriting timestamp\n")); - } - while (++tries < 6); - } - - return TRUE; - - input_err: - bfd_set_error (bfd_error_on_input, current, bfd_get_error ()); - return FALSE; -} - -/* Note that the namidx for the first symbol is 0. */ - -bfd_boolean -_bfd_compute_and_write_armap (bfd *arch, unsigned int elength) -{ - char *first_name = NULL; - bfd *current; - file_ptr elt_no = 0; - struct orl *map = NULL; - unsigned int orl_max = 1024; /* Fine initial default. */ - unsigned int orl_count = 0; - int stridx = 0; - asymbol **syms = NULL; - long syms_max = 0; - bfd_boolean ret; - bfd_size_type amt; - - /* Dunno if this is the best place for this info... */ - if (elength != 0) - elength += sizeof (struct ar_hdr); - elength += elength % 2; - - amt = orl_max * sizeof (struct orl); - map = (struct orl *) bfd_malloc (amt); - if (map == NULL) - goto error_return; - - /* We put the symbol names on the arch objalloc, and then discard - them when done. */ - first_name = (char *) bfd_alloc (arch, 1); - if (first_name == NULL) - goto error_return; - - /* Drop all the files called __.SYMDEF, we're going to make our own. */ - while (arch->archive_head - && strcmp (arch->archive_head->filename, "__.SYMDEF") == 0) - arch->archive_head = arch->archive_head->archive_next; - - /* Map over each element. */ - for (current = arch->archive_head; - current != NULL; - current = current->archive_next, elt_no++) - { - if (bfd_check_format (current, bfd_object) - && (bfd_get_file_flags (current) & HAS_SYMS) != 0) - { - long storage; - long symcount; - long src_count; - - storage = bfd_get_symtab_upper_bound (current); - if (storage < 0) - goto error_return; - - if (storage != 0) - { - if (storage > syms_max) - { - if (syms_max > 0) - free (syms); - syms_max = storage; - syms = (asymbol **) bfd_malloc (syms_max); - if (syms == NULL) - goto error_return; - } - symcount = bfd_canonicalize_symtab (current, syms); - if (symcount < 0) - goto error_return; - - /* Now map over all the symbols, picking out the ones we - want. */ - for (src_count = 0; src_count < symcount; src_count++) - { - flagword flags = (syms[src_count])->flags; - asection *sec = syms[src_count]->section; - - if ((flags & BSF_GLOBAL - || flags & BSF_WEAK - || flags & BSF_INDIRECT - || flags & BSF_GNU_UNIQUE - || bfd_is_com_section (sec)) - && ! bfd_is_und_section (sec)) - { - bfd_size_type namelen; - struct orl *new_map; - - /* This symbol will go into the archive header. */ - if (orl_count == orl_max) - { - orl_max *= 2; - amt = orl_max * sizeof (struct orl); - new_map = (struct orl *) bfd_realloc (map, amt); - if (new_map == NULL) - goto error_return; - - map = new_map; - } - - namelen = strlen (syms[src_count]->name); - amt = sizeof (char *); - map[orl_count].name = (char **) bfd_alloc (arch, amt); - if (map[orl_count].name == NULL) - goto error_return; - *(map[orl_count].name) = (char *) bfd_alloc (arch, - namelen + 1); - if (*(map[orl_count].name) == NULL) - goto error_return; - strcpy (*(map[orl_count].name), syms[src_count]->name); - map[orl_count].u.abfd = current; - map[orl_count].namidx = stridx; - - stridx += namelen + 1; - ++orl_count; - } - } - } - - /* Now ask the BFD to free up any cached information, so we - don't fill all of memory with symbol tables. */ - if (! bfd_free_cached_info (current)) - goto error_return; - } - } - - /* OK, now we have collected all the data, let's write them out. */ - ret = BFD_SEND (arch, write_armap, - (arch, elength, map, orl_count, stridx)); - - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return ret; - - error_return: - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return FALSE; -} - -bfd_boolean -bsd_write_armap (bfd *arch, - unsigned int elength, - struct orl *map, - unsigned int orl_count, - int stridx) -{ - int padit = stridx & 1; - unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE; - unsigned int stringsize = stridx + padit; - /* Include 8 bytes to store ranlibsize and stringsize in output. */ - unsigned int mapsize = ranlibsize + stringsize + 8; - file_ptr firstreal; - bfd *current = arch->archive_head; - bfd *last_elt = current; /* Last element arch seen. */ - bfd_byte temp[4]; - unsigned int count; - struct ar_hdr hdr; - long uid, gid; - - firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; - - /* If deterministic, we use 0 as the timestamp in the map. - Some linkers may require that the archive filesystem modification - time is less than (or near to) the archive map timestamp. Those - linkers should not be used with deterministic mode. (GNU ld and - Gold do not have this restriction.) */ - bfd_ardata (arch)->armap_timestamp = 0; - uid = 0; - gid = 0; - if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0) - { - struct stat statbuf; - - if (stat (arch->filename, &statbuf) == 0) - bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime - + ARMAP_TIME_OFFSET); - uid = getuid(); - gid = getgid(); - } - - memset (&hdr, ' ', sizeof (struct ar_hdr)); - memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG)); - bfd_ardata (arch)->armap_datepos = (SARMAG - + offsetof (struct ar_hdr, ar_date[0])); - _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", - bfd_ardata (arch)->armap_timestamp); - _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid); - _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid); - _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize); - memcpy (hdr.ar_fmag, ARFMAG, 2); - if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return FALSE; - H_PUT_32 (arch, ranlibsize, temp); - if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp)) - return FALSE; - - for (count = 0; count < orl_count; count++) - { - bfd_byte buf[BSD_SYMDEF_SIZE]; - - if (map[count].u.abfd != last_elt) - { - do - { - struct areltdata *ared = arch_eltdata (current); - - firstreal += (ared->parsed_size + ared->extra_size - + sizeof (struct ar_hdr)); - firstreal += firstreal % 2; - current = current->archive_next; - } - while (current != map[count].u.abfd); - } - - last_elt = current; - H_PUT_32 (arch, map[count].namidx, buf); - H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE); - if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch) - != BSD_SYMDEF_SIZE) - return FALSE; - } - - /* Now write the strings themselves. */ - H_PUT_32 (arch, stringsize, temp); - if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp)) - return FALSE; - for (count = 0; count < orl_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_bwrite (*map[count].name, len, arch) != len) - return FALSE; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for sun's ar we use a null. */ - if (padit) - { - if (bfd_bwrite ("", 1, arch) != 1) - return FALSE; - } - - return TRUE; -} - -/* At the end of archive file handling, update the timestamp in the - file, so the linker will accept it. - - Return TRUE if the timestamp was OK, or an unusual problem happened. - Return FALSE if we updated the timestamp. */ - -bfd_boolean -_bfd_archive_bsd_update_armap_timestamp (bfd *arch) -{ - struct stat archstat; - struct ar_hdr hdr; - - /* If creating deterministic archives, just leave the timestamp as-is. */ - if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0) - return TRUE; - - /* Flush writes, get last-write timestamp from file, and compare it - to the timestamp IN the file. */ - bfd_flush (arch); - if (bfd_stat (arch, &archstat) == -1) - { - bfd_perror (_("Reading archive file mod timestamp")); - - /* Can't read mod time for some reason. */ - return TRUE; - } - if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp) - /* OK by the linker's rules. */ - return TRUE; - - /* Update the timestamp. */ - bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET; - - /* Prepare an ASCII version suitable for writing. */ - memset (hdr.ar_date, ' ', sizeof (hdr.ar_date)); - _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", - bfd_ardata (arch)->armap_timestamp); - - /* Write it into the file. */ - bfd_ardata (arch)->armap_datepos = (SARMAG - + offsetof (struct ar_hdr, ar_date[0])); - if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0 - || (bfd_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch) - != sizeof (hdr.ar_date))) - { - bfd_perror (_("Writing updated armap timestamp")); - - /* Some error while writing. */ - return TRUE; - } - - /* We updated the timestamp successfully. */ - return FALSE; -} - -/* A coff armap looks like : - lARMAG - struct ar_hdr with name = '/' - number of symbols - offset of file for symbol 0 - offset of file for symbol 1 - - offset of file for symbol n-1 - symbol name 0 - symbol name 1 - - symbol name n-1 */ - -bfd_boolean -coff_write_armap (bfd *arch, - unsigned int elength, - struct orl *map, - unsigned int symbol_count, - int stridx) -{ - /* The size of the ranlib is the number of exported symbols in the - archive * the number of bytes in an int, + an int for the count. */ - unsigned int ranlibsize = (symbol_count * 4) + 4; - unsigned int stringsize = stridx; - unsigned int mapsize = stringsize + ranlibsize; - unsigned int archive_member_file_ptr; - bfd *current = arch->archive_head; - unsigned int count; - struct ar_hdr hdr; - int padit = mapsize & 1; - - if (padit) - mapsize++; - - /* Work out where the first object file will go in the archive. */ - archive_member_file_ptr = (mapsize - + elength - + sizeof (struct ar_hdr) - + SARMAG); - - memset (&hdr, ' ', sizeof (struct ar_hdr)); - hdr.ar_name[0] = '/'; - _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", - mapsize); - _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", - ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0 - ? time (NULL) : 0)); - /* This, at least, is what Intel coff sets the values to. */ - _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0); - _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0); - _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0); - memcpy (hdr.ar_fmag, ARFMAG, 2); - - /* Write the ar header for this item and the number of symbols. */ - if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return FALSE; - - if (!bfd_write_bigendian_4byte_int (arch, symbol_count)) - return FALSE; - - /* Two passes, first write the file offsets for each symbol - - remembering that each offset is on a two byte boundary. */ - - /* Write out the file offset for the file associated with each - symbol, and remember to keep the offsets padded out. */ - - current = arch->archive_head; - count = 0; - while (current != NULL && count < symbol_count) - { - /* For each symbol which is used defined in this object, write - out the object file's address in the archive. */ - - while (count < symbol_count && map[count].u.abfd == current) - { - if (!bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr)) - return FALSE; - count++; - } - archive_member_file_ptr += sizeof (struct ar_hdr); - if (! bfd_is_thin_archive (arch)) - { - /* Add size of this archive entry. */ - archive_member_file_ptr += arelt_size (current); - /* Remember about the even alignment. */ - archive_member_file_ptr += archive_member_file_ptr % 2; - } - current = current->archive_next; - } - - /* Now write the strings themselves. */ - for (count = 0; count < symbol_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_bwrite (*map[count].name, len, arch) != len) - return FALSE; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for arc960 we use a null. */ - if (padit) - { - if (bfd_bwrite ("", 1, arch) != 1) - return FALSE; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/archive64.c b/contrib/binutils-2.22/bfd/archive64.c deleted file mode 100644 index bbc4c3f72f..0000000000 --- a/contrib/binutils-2.22/bfd/archive64.c +++ /dev/null @@ -1,239 +0,0 @@ -/* MIPS-specific support for 64-bit ELF - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, - 2010 Free Software Foundation, Inc. - Ian Lance Taylor, Cygnus Support - Linker support added by Mark Mitchell, CodeSourcery, LLC. - - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* This file supports the 64-bit (MIPS) ELF archives. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "aout/ar.h" - -/* Irix 6 defines a 64bit archive map format, so that they can - have archives more than 4 GB in size. */ - -bfd_boolean bfd_elf64_archive_slurp_armap (bfd *); -bfd_boolean bfd_elf64_archive_write_armap - (bfd *, unsigned int, struct orl *, unsigned int, int); - -/* Read an Irix 6 armap. */ - -bfd_boolean -bfd_elf64_archive_slurp_armap (bfd *abfd) -{ - struct artdata *ardata = bfd_ardata (abfd); - char nextname[17]; - bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize; - struct areltdata *mapdata; - bfd_byte int_buf[8]; - char *stringbase; - bfd_byte *raw_armap = NULL; - carsym *carsyms; - bfd_size_type amt; - - ardata->symdefs = NULL; - - /* Get the name of the first element. */ - i = bfd_bread (nextname, 16, abfd); - if (i == 0) - return TRUE; - if (i != 16) - return FALSE; - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) - return FALSE; - - /* Archives with traditional armaps are still permitted. */ - if (CONST_STRNEQ (nextname, "/ ")) - return bfd_slurp_armap (abfd); - - if (! CONST_STRNEQ (nextname, "/SYM64/ ")) - { - bfd_has_map (abfd) = FALSE; - return TRUE; - } - - mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); - if (mapdata == NULL) - return FALSE; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, mapdata); - - if (bfd_bread (int_buf, 8, abfd) != 8) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return FALSE; - } - - nsymz = bfd_getb64 (int_buf); - stringsize = parsed_size - 8 * nsymz - 8; - - carsym_size = nsymz * sizeof (carsym); - ptrsize = 8 * nsymz; - - amt = carsym_size + stringsize + 1; - ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt); - if (ardata->symdefs == NULL) - return FALSE; - carsyms = ardata->symdefs; - stringbase = ((char *) ardata->symdefs) + carsym_size; - - raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize); - if (raw_armap == NULL) - goto release_symdefs; - - if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize - || bfd_bread (stringbase, stringsize, abfd) != stringsize) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - goto release_raw_armap; - } - - for (i = 0; i < nsymz; i++) - { - carsyms->file_offset = bfd_getb64 (raw_armap + i * 8); - carsyms->name = stringbase; - stringbase += strlen (stringbase) + 1; - ++carsyms; - } - *stringbase = '\0'; - - ardata->symdef_count = nsymz; - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to. */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - - bfd_has_map (abfd) = TRUE; - bfd_release (abfd, raw_armap); - - return TRUE; - -release_raw_armap: - bfd_release (abfd, raw_armap); -release_symdefs: - bfd_release (abfd, ardata->symdefs); - return FALSE; -} - -/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be - able to handle ordinary ELF armaps, but at least on Irix 6.2 the - linker crashes. */ - -bfd_boolean -bfd_elf64_archive_write_armap (bfd *arch, - unsigned int elength, - struct orl *map, - unsigned int symbol_count, - int stridx) -{ - unsigned int ranlibsize = (symbol_count * 8) + 8; - unsigned int stringsize = stridx; - unsigned int mapsize = stringsize + ranlibsize; - file_ptr archive_member_file_ptr; - bfd *current = arch->archive_head; - unsigned int count; - struct ar_hdr hdr; - int padding; - bfd_byte buf[8]; - - padding = BFD_ALIGN (mapsize, 8) - mapsize; - mapsize += padding; - - /* work out where the first object file will go in the archive */ - archive_member_file_ptr = (mapsize - + elength - + sizeof (struct ar_hdr) - + SARMAG); - - memset (&hdr, ' ', sizeof (struct ar_hdr)); - memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/")); - _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", - mapsize); - _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld", - time (NULL)); - /* This, at least, is what Intel coff sets the values to.: */ - _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0); - _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0); - _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0); - memcpy (hdr.ar_fmag, ARFMAG, 2); - - /* Write the ar header for this item and the number of symbols */ - - if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return FALSE; - - bfd_putb64 ((bfd_vma) symbol_count, buf); - if (bfd_bwrite (buf, 8, arch) != 8) - return FALSE; - - /* Two passes, first write the file offsets for each symbol - - remembering that each offset is on a two byte boundary. */ - - /* Write out the file offset for the file associated with each - symbol, and remember to keep the offsets padded out. */ - count = 0; - for (current = arch->archive_head; - current != NULL && count < symbol_count; - current = current->archive_next) - { - /* For each symbol which is used defined in this object, write out - the object file's address in the archive */ - - for (; - count < symbol_count && map[count].u.abfd == current; - count++) - { - bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf); - if (bfd_bwrite (buf, 8, arch) != 8) - return FALSE; - } - /* Add size of this archive entry */ - archive_member_file_ptr += (arelt_size (current) - + sizeof (struct ar_hdr)); - /* remember about the even alignment */ - archive_member_file_ptr += archive_member_file_ptr % 2; - } - - /* now write the strings themselves */ - for (count = 0; count < symbol_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_bwrite (*map[count].name, len, arch) != len) - return FALSE; - } - - /* The spec says that this should be padded to an 8 byte boundary. - However, the Irix 6.2 tools do not appear to do this. */ - while (padding != 0) - { - if (bfd_bwrite ("", 1, arch) != 1) - return FALSE; - --padding; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/archures.c b/contrib/binutils-2.22/bfd/archures.c deleted file mode 100644 index 44850e75dc..0000000000 --- a/contrib/binutils-2.22/bfd/archures.c +++ /dev/null @@ -1,1300 +0,0 @@ -/* BFD library support routines for architectures. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Hacked by John Gilmore and Steve Chamberlain of Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "safe-ctype.h" - -/* - -SECTION - Architectures - - BFD keeps one atom in a BFD describing the - architecture of the data attached to the BFD: a pointer to a - <>. - - Pointers to structures can be requested independently of a BFD - so that an architecture's information can be interrogated - without access to an open BFD. - - The architecture information is provided by each architecture package. - The set of default architectures is selected by the macro - <>. This is normally set up in the - @file{config/@var{target}.mt} file of your choice. If the name is not - defined, then all the architectures supported are included. - - When BFD starts up, all the architectures are called with an - initialize method. It is up to the architecture back end to - insert as many items into the list of architectures as it wants to; - generally this would be one for each machine and one for the - default case (an item with a machine field of 0). - - BFD's idea of an architecture is implemented in @file{archures.c}. -*/ - -/* - -SUBSECTION - bfd_architecture - -DESCRIPTION - This enum gives the object file's CPU architecture, in a - global sense---i.e., what processor family does it belong to? - Another field indicates which processor within - the family is in use. The machine gives a number which - distinguishes different versions of the architecture, - containing, for example, 2 and 3 for Intel i960 KA and i960 KB, - and 68020 and 68030 for Motorola 68020 and 68030. - -.enum bfd_architecture -.{ -. bfd_arch_unknown, {* File arch not known. *} -. bfd_arch_obscure, {* Arch known, not one of these. *} -. bfd_arch_m68k, {* Motorola 68xxx *} -.#define bfd_mach_m68000 1 -.#define bfd_mach_m68008 2 -.#define bfd_mach_m68010 3 -.#define bfd_mach_m68020 4 -.#define bfd_mach_m68030 5 -.#define bfd_mach_m68040 6 -.#define bfd_mach_m68060 7 -.#define bfd_mach_cpu32 8 -.#define bfd_mach_fido 9 -.#define bfd_mach_mcf_isa_a_nodiv 10 -.#define bfd_mach_mcf_isa_a 11 -.#define bfd_mach_mcf_isa_a_mac 12 -.#define bfd_mach_mcf_isa_a_emac 13 -.#define bfd_mach_mcf_isa_aplus 14 -.#define bfd_mach_mcf_isa_aplus_mac 15 -.#define bfd_mach_mcf_isa_aplus_emac 16 -.#define bfd_mach_mcf_isa_b_nousp 17 -.#define bfd_mach_mcf_isa_b_nousp_mac 18 -.#define bfd_mach_mcf_isa_b_nousp_emac 19 -.#define bfd_mach_mcf_isa_b 20 -.#define bfd_mach_mcf_isa_b_mac 21 -.#define bfd_mach_mcf_isa_b_emac 22 -.#define bfd_mach_mcf_isa_b_float 23 -.#define bfd_mach_mcf_isa_b_float_mac 24 -.#define bfd_mach_mcf_isa_b_float_emac 25 -.#define bfd_mach_mcf_isa_c 26 -.#define bfd_mach_mcf_isa_c_mac 27 -.#define bfd_mach_mcf_isa_c_emac 28 -.#define bfd_mach_mcf_isa_c_nodiv 29 -.#define bfd_mach_mcf_isa_c_nodiv_mac 30 -.#define bfd_mach_mcf_isa_c_nodiv_emac 31 -. bfd_arch_vax, {* DEC Vax *} -. bfd_arch_i960, {* Intel 960 *} -. {* The order of the following is important. -. lower number indicates a machine type that -. only accepts a subset of the instructions -. available to machines with higher numbers. -. The exception is the "ca", which is -. incompatible with all other machines except -. "core". *} -. -.#define bfd_mach_i960_core 1 -.#define bfd_mach_i960_ka_sa 2 -.#define bfd_mach_i960_kb_sb 3 -.#define bfd_mach_i960_mc 4 -.#define bfd_mach_i960_xa 5 -.#define bfd_mach_i960_ca 6 -.#define bfd_mach_i960_jx 7 -.#define bfd_mach_i960_hx 8 -. -. bfd_arch_or32, {* OpenRISC 32 *} -. -. bfd_arch_sparc, {* SPARC *} -.#define bfd_mach_sparc 1 -.{* The difference between v8plus and v9 is that v9 is a true 64 bit env. *} -.#define bfd_mach_sparc_sparclet 2 -.#define bfd_mach_sparc_sparclite 3 -.#define bfd_mach_sparc_v8plus 4 -.#define bfd_mach_sparc_v8plusa 5 {* with ultrasparc add'ns. *} -.#define bfd_mach_sparc_sparclite_le 6 -.#define bfd_mach_sparc_v9 7 -.#define bfd_mach_sparc_v9a 8 {* with ultrasparc add'ns. *} -.#define bfd_mach_sparc_v8plusb 9 {* with cheetah add'ns. *} -.#define bfd_mach_sparc_v9b 10 {* with cheetah add'ns. *} -.{* Nonzero if MACH has the v9 instruction set. *} -.#define bfd_mach_sparc_v9_p(mach) \ -. ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ -. && (mach) != bfd_mach_sparc_sparclite_le) -.{* Nonzero if MACH is a 64 bit sparc architecture. *} -.#define bfd_mach_sparc_64bit_p(mach) \ -. ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) -. bfd_arch_spu, {* PowerPC SPU *} -.#define bfd_mach_spu 256 -. bfd_arch_mips, {* MIPS Rxxxx *} -.#define bfd_mach_mips3000 3000 -.#define bfd_mach_mips3900 3900 -.#define bfd_mach_mips4000 4000 -.#define bfd_mach_mips4010 4010 -.#define bfd_mach_mips4100 4100 -.#define bfd_mach_mips4111 4111 -.#define bfd_mach_mips4120 4120 -.#define bfd_mach_mips4300 4300 -.#define bfd_mach_mips4400 4400 -.#define bfd_mach_mips4600 4600 -.#define bfd_mach_mips4650 4650 -.#define bfd_mach_mips5000 5000 -.#define bfd_mach_mips5400 5400 -.#define bfd_mach_mips5500 5500 -.#define bfd_mach_mips6000 6000 -.#define bfd_mach_mips7000 7000 -.#define bfd_mach_mips8000 8000 -.#define bfd_mach_mips9000 9000 -.#define bfd_mach_mips10000 10000 -.#define bfd_mach_mips12000 12000 -.#define bfd_mach_mips14000 14000 -.#define bfd_mach_mips16000 16000 -.#define bfd_mach_mips16 16 -.#define bfd_mach_mips5 5 -.#define bfd_mach_mips_loongson_2e 3001 -.#define bfd_mach_mips_loongson_2f 3002 -.#define bfd_mach_mips_loongson_3a 3003 -.#define bfd_mach_mips_sb1 12310201 {* octal 'SB', 01 *} -.#define bfd_mach_mips_octeon 6501 -.#define bfd_mach_mips_xlr 887682 {* decimal 'XLR' *} -.#define bfd_mach_mipsisa32 32 -.#define bfd_mach_mipsisa32r2 33 -.#define bfd_mach_mipsisa64 64 -.#define bfd_mach_mipsisa64r2 65 -.#define bfd_mach_mips_micromips 96 -. bfd_arch_i386, {* Intel 386 *} -.#define bfd_mach_i386_intel_syntax (1 << 0) -.#define bfd_mach_i386_i8086 (1 << 1) -.#define bfd_mach_i386_i386 (1 << 2) -.#define bfd_mach_x86_64 (1 << 3) -.#define bfd_mach_x64_32 (1 << 4) -.#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax) -.#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax) -.#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax) -. bfd_arch_l1om, {* Intel L1OM *} -.#define bfd_mach_l1om (1 << 5) -.#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax) -. bfd_arch_k1om, {* Intel K1OM *} -.#define bfd_mach_k1om (1 << 6) -.#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax) -. bfd_arch_we32k, {* AT&T WE32xxx *} -. bfd_arch_tahoe, {* CCI/Harris Tahoe *} -. bfd_arch_i860, {* Intel 860 *} -. bfd_arch_i370, {* IBM 360/370 Mainframes *} -. bfd_arch_romp, {* IBM ROMP PC/RT *} -. bfd_arch_convex, {* Convex *} -. bfd_arch_m88k, {* Motorola 88xxx *} -. bfd_arch_m98k, {* Motorola 98xxx *} -. bfd_arch_pyramid, {* Pyramid Technology *} -. bfd_arch_h8300, {* Renesas H8/300 (formerly Hitachi H8/300) *} -.#define bfd_mach_h8300 1 -.#define bfd_mach_h8300h 2 -.#define bfd_mach_h8300s 3 -.#define bfd_mach_h8300hn 4 -.#define bfd_mach_h8300sn 5 -.#define bfd_mach_h8300sx 6 -.#define bfd_mach_h8300sxn 7 -. bfd_arch_pdp11, {* DEC PDP-11 *} -. bfd_arch_plugin, -. bfd_arch_powerpc, {* PowerPC *} -.#define bfd_mach_ppc 32 -.#define bfd_mach_ppc64 64 -.#define bfd_mach_ppc_403 403 -.#define bfd_mach_ppc_403gc 4030 -.#define bfd_mach_ppc_405 405 -.#define bfd_mach_ppc_505 505 -.#define bfd_mach_ppc_601 601 -.#define bfd_mach_ppc_602 602 -.#define bfd_mach_ppc_603 603 -.#define bfd_mach_ppc_ec603e 6031 -.#define bfd_mach_ppc_604 604 -.#define bfd_mach_ppc_620 620 -.#define bfd_mach_ppc_630 630 -.#define bfd_mach_ppc_750 750 -.#define bfd_mach_ppc_860 860 -.#define bfd_mach_ppc_a35 35 -.#define bfd_mach_ppc_rs64ii 642 -.#define bfd_mach_ppc_rs64iii 643 -.#define bfd_mach_ppc_7400 7400 -.#define bfd_mach_ppc_e500 500 -.#define bfd_mach_ppc_e500mc 5001 -.#define bfd_mach_ppc_e500mc64 5005 -.#define bfd_mach_ppc_titan 83 -. bfd_arch_rs6000, {* IBM RS/6000 *} -.#define bfd_mach_rs6k 6000 -.#define bfd_mach_rs6k_rs1 6001 -.#define bfd_mach_rs6k_rsc 6003 -.#define bfd_mach_rs6k_rs2 6002 -. bfd_arch_hppa, {* HP PA RISC *} -.#define bfd_mach_hppa10 10 -.#define bfd_mach_hppa11 11 -.#define bfd_mach_hppa20 20 -.#define bfd_mach_hppa20w 25 -. bfd_arch_d10v, {* Mitsubishi D10V *} -.#define bfd_mach_d10v 1 -.#define bfd_mach_d10v_ts2 2 -.#define bfd_mach_d10v_ts3 3 -. bfd_arch_d30v, {* Mitsubishi D30V *} -. bfd_arch_dlx, {* DLX *} -. bfd_arch_m68hc11, {* Motorola 68HC11 *} -. bfd_arch_m68hc12, {* Motorola 68HC12 *} -.#define bfd_mach_m6812_default 0 -.#define bfd_mach_m6812 1 -.#define bfd_mach_m6812s 2 -. bfd_arch_z8k, {* Zilog Z8000 *} -.#define bfd_mach_z8001 1 -.#define bfd_mach_z8002 2 -. bfd_arch_h8500, {* Renesas H8/500 (formerly Hitachi H8/500) *} -. bfd_arch_sh, {* Renesas / SuperH SH (formerly Hitachi SH) *} -.#define bfd_mach_sh 1 -.#define bfd_mach_sh2 0x20 -.#define bfd_mach_sh_dsp 0x2d -.#define bfd_mach_sh2a 0x2a -.#define bfd_mach_sh2a_nofpu 0x2b -.#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 -.#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 -.#define bfd_mach_sh2a_or_sh4 0x2a3 -.#define bfd_mach_sh2a_or_sh3e 0x2a4 -.#define bfd_mach_sh2e 0x2e -.#define bfd_mach_sh3 0x30 -.#define bfd_mach_sh3_nommu 0x31 -.#define bfd_mach_sh3_dsp 0x3d -.#define bfd_mach_sh3e 0x3e -.#define bfd_mach_sh4 0x40 -.#define bfd_mach_sh4_nofpu 0x41 -.#define bfd_mach_sh4_nommu_nofpu 0x42 -.#define bfd_mach_sh4a 0x4a -.#define bfd_mach_sh4a_nofpu 0x4b -.#define bfd_mach_sh4al_dsp 0x4d -.#define bfd_mach_sh5 0x50 -. bfd_arch_alpha, {* Dec Alpha *} -.#define bfd_mach_alpha_ev4 0x10 -.#define bfd_mach_alpha_ev5 0x20 -.#define bfd_mach_alpha_ev6 0x30 -. bfd_arch_arm, {* Advanced Risc Machines ARM. *} -.#define bfd_mach_arm_unknown 0 -.#define bfd_mach_arm_2 1 -.#define bfd_mach_arm_2a 2 -.#define bfd_mach_arm_3 3 -.#define bfd_mach_arm_3M 4 -.#define bfd_mach_arm_4 5 -.#define bfd_mach_arm_4T 6 -.#define bfd_mach_arm_5 7 -.#define bfd_mach_arm_5T 8 -.#define bfd_mach_arm_5TE 9 -.#define bfd_mach_arm_XScale 10 -.#define bfd_mach_arm_ep9312 11 -.#define bfd_mach_arm_iWMMXt 12 -.#define bfd_mach_arm_iWMMXt2 13 -. bfd_arch_ns32k, {* National Semiconductors ns32000 *} -. bfd_arch_w65, {* WDC 65816 *} -. bfd_arch_tic30, {* Texas Instruments TMS320C30 *} -. bfd_arch_tic4x, {* Texas Instruments TMS320C3X/4X *} -.#define bfd_mach_tic3x 30 -.#define bfd_mach_tic4x 40 -. bfd_arch_tic54x, {* Texas Instruments TMS320C54X *} -. bfd_arch_tic6x, {* Texas Instruments TMS320C6X *} -. bfd_arch_tic80, {* TI TMS320c80 (MVP) *} -. bfd_arch_v850, {* NEC V850 *} -.#define bfd_mach_v850 1 -.#define bfd_mach_v850e 'E' -.#define bfd_mach_v850e1 '1' -.#define bfd_mach_v850e2 0x4532 -.#define bfd_mach_v850e2v3 0x45325633 -. bfd_arch_arc, {* ARC Cores *} -.#define bfd_mach_arc_5 5 -.#define bfd_mach_arc_6 6 -.#define bfd_mach_arc_7 7 -.#define bfd_mach_arc_8 8 -. bfd_arch_m32c, {* Renesas M16C/M32C. *} -.#define bfd_mach_m16c 0x75 -.#define bfd_mach_m32c 0x78 -. bfd_arch_m32r, {* Renesas M32R (formerly Mitsubishi M32R/D) *} -.#define bfd_mach_m32r 1 {* For backwards compatibility. *} -.#define bfd_mach_m32rx 'x' -.#define bfd_mach_m32r2 '2' -. bfd_arch_mn10200, {* Matsushita MN10200 *} -. bfd_arch_mn10300, {* Matsushita MN10300 *} -.#define bfd_mach_mn10300 300 -.#define bfd_mach_am33 330 -.#define bfd_mach_am33_2 332 -. bfd_arch_fr30, -.#define bfd_mach_fr30 0x46523330 -. bfd_arch_frv, -.#define bfd_mach_frv 1 -.#define bfd_mach_frvsimple 2 -.#define bfd_mach_fr300 300 -.#define bfd_mach_fr400 400 -.#define bfd_mach_fr450 450 -.#define bfd_mach_frvtomcat 499 {* fr500 prototype *} -.#define bfd_mach_fr500 500 -.#define bfd_mach_fr550 550 -. bfd_arch_moxie, {* The moxie processor *} -.#define bfd_mach_moxie 1 -. bfd_arch_mcore, -. bfd_arch_mep, -.#define bfd_mach_mep 1 -.#define bfd_mach_mep_h1 0x6831 -.#define bfd_mach_mep_c5 0x6335 -. bfd_arch_ia64, {* HP/Intel ia64 *} -.#define bfd_mach_ia64_elf64 64 -.#define bfd_mach_ia64_elf32 32 -. bfd_arch_ip2k, {* Ubicom IP2K microcontrollers. *} -.#define bfd_mach_ip2022 1 -.#define bfd_mach_ip2022ext 2 -. bfd_arch_iq2000, {* Vitesse IQ2000. *} -.#define bfd_mach_iq2000 1 -.#define bfd_mach_iq10 2 -. bfd_arch_mt, -.#define bfd_mach_ms1 1 -.#define bfd_mach_mrisc2 2 -.#define bfd_mach_ms2 3 -. bfd_arch_pj, -. bfd_arch_avr, {* Atmel AVR microcontrollers. *} -.#define bfd_mach_avr1 1 -.#define bfd_mach_avr2 2 -.#define bfd_mach_avr25 25 -.#define bfd_mach_avr3 3 -.#define bfd_mach_avr31 31 -.#define bfd_mach_avr35 35 -.#define bfd_mach_avr4 4 -.#define bfd_mach_avr5 5 -.#define bfd_mach_avr51 51 -.#define bfd_mach_avr6 6 -.#define bfd_mach_avrxmega1 101 -.#define bfd_mach_avrxmega2 102 -.#define bfd_mach_avrxmega3 103 -.#define bfd_mach_avrxmega4 104 -.#define bfd_mach_avrxmega5 105 -.#define bfd_mach_avrxmega6 106 -.#define bfd_mach_avrxmega7 107 -. bfd_arch_bfin, {* ADI Blackfin *} -.#define bfd_mach_bfin 1 -. bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *} -.#define bfd_mach_cr16 1 -. bfd_arch_cr16c, {* National Semiconductor CompactRISC. *} -.#define bfd_mach_cr16c 1 -. bfd_arch_crx, {* National Semiconductor CRX. *} -.#define bfd_mach_crx 1 -. bfd_arch_cris, {* Axis CRIS *} -.#define bfd_mach_cris_v0_v10 255 -.#define bfd_mach_cris_v32 32 -.#define bfd_mach_cris_v10_v32 1032 -. bfd_arch_rx, {* Renesas RX. *} -.#define bfd_mach_rx 0x75 -. bfd_arch_s390, {* IBM s390 *} -.#define bfd_mach_s390_31 31 -.#define bfd_mach_s390_64 64 -. bfd_arch_score, {* Sunplus score *} -.#define bfd_mach_score3 3 -.#define bfd_mach_score7 7 -. bfd_arch_openrisc, {* OpenRISC *} -. bfd_arch_mmix, {* Donald Knuth's educational processor. *} -. bfd_arch_xstormy16, -.#define bfd_mach_xstormy16 1 -. bfd_arch_msp430, {* Texas Instruments MSP430 architecture. *} -.#define bfd_mach_msp11 11 -.#define bfd_mach_msp110 110 -.#define bfd_mach_msp12 12 -.#define bfd_mach_msp13 13 -.#define bfd_mach_msp14 14 -.#define bfd_mach_msp15 15 -.#define bfd_mach_msp16 16 -.#define bfd_mach_msp21 21 -.#define bfd_mach_msp31 31 -.#define bfd_mach_msp32 32 -.#define bfd_mach_msp33 33 -.#define bfd_mach_msp41 41 -.#define bfd_mach_msp42 42 -.#define bfd_mach_msp43 43 -.#define bfd_mach_msp44 44 -. bfd_arch_xc16x, {* Infineon's XC16X Series. *} -.#define bfd_mach_xc16x 1 -.#define bfd_mach_xc16xl 2 -.#define bfd_mach_xc16xs 3 -. bfd_arch_xtensa, {* Tensilica's Xtensa cores. *} -.#define bfd_mach_xtensa 1 -. bfd_arch_z80, -.#define bfd_mach_z80strict 1 {* No undocumented opcodes. *} -.#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *} -.#define bfd_mach_z80full 7 {* All undocumented instructions. *} -.#define bfd_mach_r800 11 {* R800: successor with multiplication. *} -. bfd_arch_lm32, {* Lattice Mico32 *} -.#define bfd_mach_lm32 1 -. bfd_arch_microblaze,{* Xilinx MicroBlaze. *} -. bfd_arch_tilepro, {* Tilera TILEPro *} -. bfd_arch_tilegx, {* Tilera TILE-Gx *} -.#define bfd_mach_tilepro 1 -.#define bfd_mach_tilegx 1 -. bfd_arch_last -. }; -*/ - -/* -SUBSECTION - bfd_arch_info - -DESCRIPTION - This structure contains information on architectures for use - within BFD. - -. -.typedef struct bfd_arch_info -.{ -. int bits_per_word; -. int bits_per_address; -. int bits_per_byte; -. enum bfd_architecture arch; -. unsigned long mach; -. const char *arch_name; -. const char *printable_name; -. unsigned int section_align_power; -. {* TRUE if this is the default machine for the architecture. -. The default arch should be the first entry for an arch so that -. all the entries for that arch can be accessed via <>. *} -. bfd_boolean the_default; -. const struct bfd_arch_info * (*compatible) -. (const struct bfd_arch_info *a, const struct bfd_arch_info *b); -. -. bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); -. -. const struct bfd_arch_info *next; -.} -.bfd_arch_info_type; -. -*/ - -extern const bfd_arch_info_type bfd_alpha_arch; -extern const bfd_arch_info_type bfd_arc_arch; -extern const bfd_arch_info_type bfd_arm_arch; -extern const bfd_arch_info_type bfd_avr_arch; -extern const bfd_arch_info_type bfd_bfin_arch; -extern const bfd_arch_info_type bfd_cr16_arch; -extern const bfd_arch_info_type bfd_cr16c_arch; -extern const bfd_arch_info_type bfd_cris_arch; -extern const bfd_arch_info_type bfd_crx_arch; -extern const bfd_arch_info_type bfd_d10v_arch; -extern const bfd_arch_info_type bfd_d30v_arch; -extern const bfd_arch_info_type bfd_dlx_arch; -extern const bfd_arch_info_type bfd_fr30_arch; -extern const bfd_arch_info_type bfd_frv_arch; -extern const bfd_arch_info_type bfd_h8300_arch; -extern const bfd_arch_info_type bfd_h8500_arch; -extern const bfd_arch_info_type bfd_hppa_arch; -extern const bfd_arch_info_type bfd_i370_arch; -extern const bfd_arch_info_type bfd_i386_arch; -extern const bfd_arch_info_type bfd_i860_arch; -extern const bfd_arch_info_type bfd_i960_arch; -extern const bfd_arch_info_type bfd_ia64_arch; -extern const bfd_arch_info_type bfd_ip2k_arch; -extern const bfd_arch_info_type bfd_iq2000_arch; -extern const bfd_arch_info_type bfd_k1om_arch; -extern const bfd_arch_info_type bfd_l1om_arch; -extern const bfd_arch_info_type bfd_lm32_arch; -extern const bfd_arch_info_type bfd_m32c_arch; -extern const bfd_arch_info_type bfd_m32r_arch; -extern const bfd_arch_info_type bfd_m68hc11_arch; -extern const bfd_arch_info_type bfd_m68hc12_arch; -extern const bfd_arch_info_type bfd_m68k_arch; -extern const bfd_arch_info_type bfd_m88k_arch; -extern const bfd_arch_info_type bfd_mcore_arch; -extern const bfd_arch_info_type bfd_mep_arch; -extern const bfd_arch_info_type bfd_mips_arch; -extern const bfd_arch_info_type bfd_microblaze_arch; -extern const bfd_arch_info_type bfd_mmix_arch; -extern const bfd_arch_info_type bfd_mn10200_arch; -extern const bfd_arch_info_type bfd_mn10300_arch; -extern const bfd_arch_info_type bfd_moxie_arch; -extern const bfd_arch_info_type bfd_msp430_arch; -extern const bfd_arch_info_type bfd_mt_arch; -extern const bfd_arch_info_type bfd_ns32k_arch; -extern const bfd_arch_info_type bfd_openrisc_arch; -extern const bfd_arch_info_type bfd_or32_arch; -extern const bfd_arch_info_type bfd_pdp11_arch; -extern const bfd_arch_info_type bfd_pj_arch; -extern const bfd_arch_info_type bfd_plugin_arch; -extern const bfd_arch_info_type bfd_powerpc_archs[]; -#define bfd_powerpc_arch bfd_powerpc_archs[0] -extern const bfd_arch_info_type bfd_rs6000_arch; -extern const bfd_arch_info_type bfd_rx_arch; -extern const bfd_arch_info_type bfd_s390_arch; -extern const bfd_arch_info_type bfd_score_arch; -extern const bfd_arch_info_type bfd_sh_arch; -extern const bfd_arch_info_type bfd_sparc_arch; -extern const bfd_arch_info_type bfd_spu_arch; -extern const bfd_arch_info_type bfd_tic30_arch; -extern const bfd_arch_info_type bfd_tic4x_arch; -extern const bfd_arch_info_type bfd_tic54x_arch; -extern const bfd_arch_info_type bfd_tic6x_arch; -extern const bfd_arch_info_type bfd_tic80_arch; -extern const bfd_arch_info_type bfd_tilegx_arch; -extern const bfd_arch_info_type bfd_tilepro_arch; -extern const bfd_arch_info_type bfd_v850_arch; -extern const bfd_arch_info_type bfd_vax_arch; -extern const bfd_arch_info_type bfd_w65_arch; -extern const bfd_arch_info_type bfd_we32k_arch; -extern const bfd_arch_info_type bfd_xstormy16_arch; -extern const bfd_arch_info_type bfd_xtensa_arch; -extern const bfd_arch_info_type bfd_xc16x_arch; -extern const bfd_arch_info_type bfd_z80_arch; -extern const bfd_arch_info_type bfd_z8k_arch; - -static const bfd_arch_info_type * const bfd_archures_list[] = - { -#ifdef SELECT_ARCHITECTURES - SELECT_ARCHITECTURES, -#else - &bfd_alpha_arch, - &bfd_arc_arch, - &bfd_arm_arch, - &bfd_avr_arch, - &bfd_bfin_arch, - &bfd_cr16_arch, - &bfd_cr16c_arch, - &bfd_cris_arch, - &bfd_crx_arch, - &bfd_d10v_arch, - &bfd_d30v_arch, - &bfd_dlx_arch, - &bfd_fr30_arch, - &bfd_frv_arch, - &bfd_h8300_arch, - &bfd_h8500_arch, - &bfd_hppa_arch, - &bfd_i370_arch, - &bfd_i386_arch, - &bfd_i860_arch, - &bfd_i960_arch, - &bfd_ia64_arch, - &bfd_ip2k_arch, - &bfd_iq2000_arch, - &bfd_k1om_arch, - &bfd_l1om_arch, - &bfd_lm32_arch, - &bfd_m32c_arch, - &bfd_m32r_arch, - &bfd_m68hc11_arch, - &bfd_m68hc12_arch, - &bfd_m68k_arch, - &bfd_m88k_arch, - &bfd_mcore_arch, - &bfd_mep_arch, - &bfd_microblaze_arch, - &bfd_mips_arch, - &bfd_mmix_arch, - &bfd_mn10200_arch, - &bfd_mn10300_arch, - &bfd_moxie_arch, - &bfd_msp430_arch, - &bfd_mt_arch, - &bfd_ns32k_arch, - &bfd_openrisc_arch, - &bfd_or32_arch, - &bfd_pdp11_arch, - &bfd_powerpc_arch, - &bfd_rs6000_arch, - &bfd_rx_arch, - &bfd_s390_arch, - &bfd_score_arch, - &bfd_sh_arch, - &bfd_sparc_arch, - &bfd_spu_arch, - &bfd_tic30_arch, - &bfd_tic4x_arch, - &bfd_tic54x_arch, - &bfd_tic6x_arch, - &bfd_tic80_arch, - &bfd_tilegx_arch, - &bfd_tilepro_arch, - &bfd_v850_arch, - &bfd_vax_arch, - &bfd_w65_arch, - &bfd_we32k_arch, - &bfd_xstormy16_arch, - &bfd_xtensa_arch, - &bfd_xc16x_arch, - &bfd_z80_arch, - &bfd_z8k_arch, -#endif - 0 -}; - -/* -FUNCTION - bfd_printable_name - -SYNOPSIS - const char *bfd_printable_name (bfd *abfd); - -DESCRIPTION - Return a printable string representing the architecture and machine - from the pointer to the architecture info structure. - -*/ - -const char * -bfd_printable_name (bfd *abfd) -{ - return abfd->arch_info->printable_name; -} - -/* -FUNCTION - bfd_scan_arch - -SYNOPSIS - const bfd_arch_info_type *bfd_scan_arch (const char *string); - -DESCRIPTION - Figure out if BFD supports any cpu which could be described with - the name @var{string}. Return a pointer to an <> - structure if a machine is found, otherwise NULL. -*/ - -const bfd_arch_info_type * -bfd_scan_arch (const char *string) -{ - const bfd_arch_info_type * const *app, *ap; - - /* Look through all the installed architectures. */ - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->scan (ap, string)) - return ap; - } - } - - return NULL; -} - -/* -FUNCTION - bfd_arch_list - -SYNOPSIS - const char **bfd_arch_list (void); - -DESCRIPTION - Return a freshly malloced NULL-terminated vector of the names - of all the valid BFD architectures. Do not modify the names. -*/ - -const char ** -bfd_arch_list (void) -{ - int vec_length = 0; - const char **name_ptr; - const char **name_list; - const bfd_arch_info_type * const *app; - bfd_size_type amt; - - /* Determine the number of architectures. */ - vec_length = 0; - for (app = bfd_archures_list; *app != NULL; app++) - { - const bfd_arch_info_type *ap; - for (ap = *app; ap != NULL; ap = ap->next) - { - vec_length++; - } - } - - amt = (vec_length + 1) * sizeof (char **); - name_list = (const char **) bfd_malloc (amt); - if (name_list == NULL) - return NULL; - - /* Point the list at each of the names. */ - name_ptr = name_list; - for (app = bfd_archures_list; *app != NULL; app++) - { - const bfd_arch_info_type *ap; - for (ap = *app; ap != NULL; ap = ap->next) - { - *name_ptr = ap->printable_name; - name_ptr++; - } - } - *name_ptr = NULL; - - return name_list; -} - -/* -FUNCTION - bfd_arch_get_compatible - -SYNOPSIS - const bfd_arch_info_type *bfd_arch_get_compatible - (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); - -DESCRIPTION - Determine whether two BFDs' architectures and machine types - are compatible. Calculates the lowest common denominator - between the two architectures and machine types implied by - the BFDs and returns a pointer to an <> structure - describing the compatible machine. -*/ - -const bfd_arch_info_type * -bfd_arch_get_compatible (const bfd *abfd, - const bfd *bbfd, - bfd_boolean accept_unknowns) -{ - const bfd *ubfd, *kbfd; - - /* Look for an unknown architecture. */ - if (abfd->arch_info->arch == bfd_arch_unknown) - ubfd = abfd, kbfd = bbfd; - else if (bbfd->arch_info->arch == bfd_arch_unknown) - ubfd = bbfd, kbfd = abfd; - else - /* Otherwise architecture-specific code has to decide. */ - return abfd->arch_info->compatible (abfd->arch_info, bbfd->arch_info); - - /* We can allow an unknown architecture if accept_unknowns - is true, or if the target is the "binary" format, which - has an unknown architecture. Since the binary format can - only be set by explicit request from the user, it is safe - to assume that they know what they are doing. */ - if (accept_unknowns - || strcmp (bfd_get_target (ubfd), "binary") == 0) - return kbfd->arch_info; - return NULL; -} - -/* -INTERNAL_DEFINITION - bfd_default_arch_struct - -DESCRIPTION - The <> is an item of - <> which has been initialized to a fairly - generic state. A BFD starts life by pointing to this - structure, until the correct back end has determined the real - architecture of the file. - -.extern const bfd_arch_info_type bfd_default_arch_struct; -*/ - -const bfd_arch_info_type bfd_default_arch_struct = { - 32, 32, 8, bfd_arch_unknown, 0, "unknown", "unknown", 2, TRUE, - bfd_default_compatible, - bfd_default_scan, - 0, -}; - -/* -FUNCTION - bfd_set_arch_info - -SYNOPSIS - void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); - -DESCRIPTION - Set the architecture info of @var{abfd} to @var{arg}. -*/ - -void -bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg) -{ - abfd->arch_info = arg; -} - -/* -INTERNAL_FUNCTION - bfd_default_set_arch_mach - -SYNOPSIS - bfd_boolean bfd_default_set_arch_mach - (bfd *abfd, enum bfd_architecture arch, unsigned long mach); - -DESCRIPTION - Set the architecture and machine type in BFD @var{abfd} - to @var{arch} and @var{mach}. Find the correct - pointer to a structure and insert it into the <> - pointer. -*/ - -bfd_boolean -bfd_default_set_arch_mach (bfd *abfd, - enum bfd_architecture arch, - unsigned long mach) -{ - abfd->arch_info = bfd_lookup_arch (arch, mach); - if (abfd->arch_info != NULL) - return TRUE; - - abfd->arch_info = &bfd_default_arch_struct; - bfd_set_error (bfd_error_bad_value); - return FALSE; -} - -/* -FUNCTION - bfd_get_arch - -SYNOPSIS - enum bfd_architecture bfd_get_arch (bfd *abfd); - -DESCRIPTION - Return the enumerated type which describes the BFD @var{abfd}'s - architecture. -*/ - -enum bfd_architecture -bfd_get_arch (bfd *abfd) -{ - return abfd->arch_info->arch; -} - -/* -FUNCTION - bfd_get_mach - -SYNOPSIS - unsigned long bfd_get_mach (bfd *abfd); - -DESCRIPTION - Return the long type which describes the BFD @var{abfd}'s - machine. -*/ - -unsigned long -bfd_get_mach (bfd *abfd) -{ - return abfd->arch_info->mach; -} - -/* -FUNCTION - bfd_arch_bits_per_byte - -SYNOPSIS - unsigned int bfd_arch_bits_per_byte (bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's bytes. -*/ - -unsigned int -bfd_arch_bits_per_byte (bfd *abfd) -{ - return abfd->arch_info->bits_per_byte; -} - -/* -FUNCTION - bfd_arch_bits_per_address - -SYNOPSIS - unsigned int bfd_arch_bits_per_address (bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's addresses. -*/ - -unsigned int -bfd_arch_bits_per_address (bfd *abfd) -{ - return abfd->arch_info->bits_per_address; -} - -/* -INTERNAL_FUNCTION - bfd_default_compatible - -SYNOPSIS - const bfd_arch_info_type *bfd_default_compatible - (const bfd_arch_info_type *a, const bfd_arch_info_type *b); - -DESCRIPTION - The default function for testing for compatibility. -*/ - -const bfd_arch_info_type * -bfd_default_compatible (const bfd_arch_info_type *a, - const bfd_arch_info_type *b) -{ - if (a->arch != b->arch) - return NULL; - - if (a->bits_per_word != b->bits_per_word) - return NULL; - - if (a->mach > b->mach) - return a; - - if (b->mach > a->mach) - return b; - - return a; -} - -/* -INTERNAL_FUNCTION - bfd_default_scan - -SYNOPSIS - bfd_boolean bfd_default_scan - (const struct bfd_arch_info *info, const char *string); - -DESCRIPTION - The default function for working out whether this is an - architecture hit and a machine hit. -*/ - -bfd_boolean -bfd_default_scan (const bfd_arch_info_type *info, const char *string) -{ - const char *ptr_src; - const char *ptr_tst; - unsigned long number; - enum bfd_architecture arch; - const char *printable_name_colon; - - /* Exact match of the architecture name (ARCH_NAME) and also the - default architecture? */ - if (strcasecmp (string, info->arch_name) == 0 - && info->the_default) - return TRUE; - - /* Exact match of the machine name (PRINTABLE_NAME)? */ - if (strcasecmp (string, info->printable_name) == 0) - return TRUE; - - /* Given that printable_name contains no colon, attempt to match: - ARCH_NAME [ ":" ] PRINTABLE_NAME? */ - printable_name_colon = strchr (info->printable_name, ':'); - if (printable_name_colon == NULL) - { - size_t strlen_arch_name = strlen (info->arch_name); - if (strncasecmp (string, info->arch_name, strlen_arch_name) == 0) - { - if (string[strlen_arch_name] == ':') - { - if (strcasecmp (string + strlen_arch_name + 1, - info->printable_name) == 0) - return TRUE; - } - else - { - if (strcasecmp (string + strlen_arch_name, - info->printable_name) == 0) - return TRUE; - } - } - } - - /* Given that PRINTABLE_NAME has the form: ":" ; - Attempt to match: ? */ - if (printable_name_colon != NULL) - { - size_t colon_index = printable_name_colon - info->printable_name; - if (strncasecmp (string, info->printable_name, colon_index) == 0 - && strcasecmp (string + colon_index, - info->printable_name + colon_index + 1) == 0) - return TRUE; - } - - /* Given that PRINTABLE_NAME has the form: ":" ; Do not - attempt to match just , it could be ambiguous. This test - is left until later. */ - - /* NOTE: The below is retained for compatibility only. Please do - not add to this code. */ - - /* See how much of the supplied string matches with the - architecture, eg the string m68k:68020 would match the 68k entry - up to the :, then we get left with the machine number. */ - - for (ptr_src = string, ptr_tst = info->arch_name; - *ptr_src && *ptr_tst; - ptr_src++, ptr_tst++) - { - if (*ptr_src != *ptr_tst) - break; - } - - /* Chewed up as much of the architecture as will match, skip any - colons. */ - if (*ptr_src == ':') - ptr_src++; - - if (*ptr_src == 0) - { - /* Nothing more, then only keep this one if it is the default - machine for this architecture. */ - return info->the_default; - } - - number = 0; - while (ISDIGIT (*ptr_src)) - { - number = number * 10 + *ptr_src - '0'; - ptr_src++; - } - - /* NOTE: The below is retained for compatibility only. - PLEASE DO NOT ADD TO THIS CODE. */ - - switch (number) - { - /* FIXME: These are needed to parse IEEE objects. */ - /* The following seven case's are here only for compatibility with - older binutils (at least IEEE objects from binutils 2.9.1 require - them). */ - case bfd_mach_m68000: - case bfd_mach_m68010: - case bfd_mach_m68020: - case bfd_mach_m68030: - case bfd_mach_m68040: - case bfd_mach_m68060: - case bfd_mach_cpu32: - arch = bfd_arch_m68k; - break; - case 68000: - arch = bfd_arch_m68k; - number = bfd_mach_m68000; - break; - case 68010: - arch = bfd_arch_m68k; - number = bfd_mach_m68010; - break; - case 68020: - arch = bfd_arch_m68k; - number = bfd_mach_m68020; - break; - case 68030: - arch = bfd_arch_m68k; - number = bfd_mach_m68030; - break; - case 68040: - arch = bfd_arch_m68k; - number = bfd_mach_m68040; - break; - case 68060: - arch = bfd_arch_m68k; - number = bfd_mach_m68060; - break; - case 68332: - arch = bfd_arch_m68k; - number = bfd_mach_cpu32; - break; - case 5200: - arch = bfd_arch_m68k; - number = bfd_mach_mcf_isa_a_nodiv; - break; - case 5206: - arch = bfd_arch_m68k; - number = bfd_mach_mcf_isa_a_mac; - break; - case 5307: - arch = bfd_arch_m68k; - number = bfd_mach_mcf_isa_a_mac; - break; - case 5407: - arch = bfd_arch_m68k; - number = bfd_mach_mcf_isa_b_nousp_mac; - break; - case 5282: - arch = bfd_arch_m68k; - number = bfd_mach_mcf_isa_aplus_emac; - break; - - case 32000: - arch = bfd_arch_we32k; - break; - - case 3000: - arch = bfd_arch_mips; - number = bfd_mach_mips3000; - break; - - case 4000: - arch = bfd_arch_mips; - number = bfd_mach_mips4000; - break; - - case 6000: - arch = bfd_arch_rs6000; - break; - - case 7410: - arch = bfd_arch_sh; - number = bfd_mach_sh_dsp; - break; - - case 7708: - arch = bfd_arch_sh; - number = bfd_mach_sh3; - break; - - case 7729: - arch = bfd_arch_sh; - number = bfd_mach_sh3_dsp; - break; - - case 7750: - arch = bfd_arch_sh; - number = bfd_mach_sh4; - break; - - default: - return FALSE; - } - - if (arch != info->arch) - return FALSE; - - if (number != info->mach) - return FALSE; - - return TRUE; -} - -/* -FUNCTION - bfd_get_arch_info - -SYNOPSIS - const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); - -DESCRIPTION - Return the architecture info struct in @var{abfd}. -*/ - -const bfd_arch_info_type * -bfd_get_arch_info (bfd *abfd) -{ - return abfd->arch_info; -} - -/* -FUNCTION - bfd_lookup_arch - -SYNOPSIS - const bfd_arch_info_type *bfd_lookup_arch - (enum bfd_architecture arch, unsigned long machine); - -DESCRIPTION - Look for the architecture info structure which matches the - arguments @var{arch} and @var{machine}. A machine of 0 matches the - machine/architecture structure which marks itself as the - default. -*/ - -const bfd_arch_info_type * -bfd_lookup_arch (enum bfd_architecture arch, unsigned long machine) -{ - const bfd_arch_info_type * const *app, *ap; - - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->arch == arch - && (ap->mach == machine - || (machine == 0 && ap->the_default))) - return ap; - } - } - - return NULL; -} - -/* -FUNCTION - bfd_printable_arch_mach - -SYNOPSIS - const char *bfd_printable_arch_mach - (enum bfd_architecture arch, unsigned long machine); - -DESCRIPTION - Return a printable string representing the architecture and - machine type. - - This routine is depreciated. -*/ - -const char * -bfd_printable_arch_mach (enum bfd_architecture arch, unsigned long machine) -{ - const bfd_arch_info_type *ap = bfd_lookup_arch (arch, machine); - - if (ap) - return ap->printable_name; - return "UNKNOWN!"; -} - -/* -FUNCTION - bfd_octets_per_byte - -SYNOPSIS - unsigned int bfd_octets_per_byte (bfd *abfd); - -DESCRIPTION - Return the number of octets (8-bit quantities) per target byte - (minimum addressable unit). In most cases, this will be one, but some - DSP targets have 16, 32, or even 48 bits per byte. -*/ - -unsigned int -bfd_octets_per_byte (bfd *abfd) -{ - return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd), - bfd_get_mach (abfd)); -} - -/* -FUNCTION - bfd_arch_mach_octets_per_byte - -SYNOPSIS - unsigned int bfd_arch_mach_octets_per_byte - (enum bfd_architecture arch, unsigned long machine); - -DESCRIPTION - See bfd_octets_per_byte. - - This routine is provided for those cases where a bfd * is not - available -*/ - -unsigned int -bfd_arch_mach_octets_per_byte (enum bfd_architecture arch, - unsigned long mach) -{ - const bfd_arch_info_type *ap = bfd_lookup_arch (arch, mach); - - if (ap) - return ap->bits_per_byte / 8; - return 1; -} diff --git a/contrib/binutils-2.22/bfd/bfd-in2.h b/contrib/binutils-2.22/bfd/bfd-in2.h deleted file mode 100644 index 22fcdf65bd..0000000000 --- a/contrib/binutils-2.22/bfd/bfd-in2.h +++ /dev/null @@ -1,6228 +0,0 @@ -/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically - generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", - "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", - "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", - "linker.c", "simple.c" and "compress.c". - Run "make headers" in your build bfd/ to regenerate. */ - -/* Main header file for the bfd library -- portable access to object files. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - Contributed by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef __BFD_H_SEEN__ -#define __BFD_H_SEEN__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" -#include "symcat.h" -#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) -#ifndef SABER -/* This hack is to avoid a problem with some strict ANSI C preprocessors. - The problem is, "32_" is not a valid preprocessing token, and we don't - want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will - cause the inner CONCAT2 macros to be evaluated first, producing - still-valid pp-tokens. Then the final concatenation can be done. */ -#undef CONCAT4 -#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d)) -#endif -#endif - -/* This is a utility macro to handle the situation where the code - wants to place a constant string into the code, followed by a - comma and then the length of the string. Doing this by hand - is error prone, so using this macro is safer. */ -#define STRING_COMMA_LEN(STR) (STR), (sizeof (STR) - 1) -/* Unfortunately it is not possible to use the STRING_COMMA_LEN macro - to create the arguments to another macro, since the preprocessor - will mis-count the number of arguments to the outer macro (by not - evaluating STRING_COMMA_LEN and so missing the comma). This is a - problem for example when trying to use STRING_COMMA_LEN to build - the arguments to the strncmp() macro. Hence this alternative - definition of strncmp is provided here. - - Note - these macros do NOT work if STR2 is not a constant string. */ -#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0) - /* strcpy() can have a similar problem, but since we know we are - copying a constant string, we can use memcpy which will be faster - since there is no need to check for a NUL byte inside STR. We - can also save time if we do not need to copy the terminating NUL. */ -#define LITMEMCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2) - 1) -#define LITSTRCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2)) - - -#define BFD_SUPPORTS_PLUGINS @supports_plugins@ - -/* The word size used by BFD on the host. This may be 64 with a 32 - bit target if the host is 64 bit, or if other 64 bit targets have - been selected with --enable-targets, or if --enable-64-bit-bfd. */ -#define BFD_ARCH_SIZE @wordsize@ - -/* The word size of the default bfd target. */ -#define BFD_DEFAULT_TARGET_SIZE @bfd_default_target_size@ - -#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@ -#define BFD_HOST_64BIT_LONG_LONG @BFD_HOST_64BIT_LONG_LONG@ -#if @BFD_HOST_64_BIT_DEFINED@ -#define BFD_HOST_64_BIT @BFD_HOST_64_BIT@ -#define BFD_HOST_U_64_BIT @BFD_HOST_U_64_BIT@ -typedef BFD_HOST_64_BIT bfd_int64_t; -typedef BFD_HOST_U_64_BIT bfd_uint64_t; -#endif - -#if BFD_ARCH_SIZE >= 64 -#define BFD64 -#endif - -#ifndef INLINE -#if __GNUC__ >= 2 -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -/* Declaring a type wide enough to hold a host long and a host pointer. */ -#define BFD_HOSTPTR_T @BFD_HOSTPTR_T@ -typedef BFD_HOSTPTR_T bfd_hostptr_t; - -/* Forward declaration. */ -typedef struct bfd bfd; - -/* Boolean type used in bfd. Too many systems define their own - versions of "boolean" for us to safely typedef a "boolean" of - our own. Using an enum for "bfd_boolean" has its own set of - problems, with strange looking casts required to avoid warnings - on some older compilers. Thus we just use an int. - - General rule: Functions which are bfd_boolean return TRUE on - success and FALSE on failure (unless they're a predicate). */ - -typedef int bfd_boolean; -#undef FALSE -#undef TRUE -#define FALSE 0 -#define TRUE 1 - -#ifdef BFD64 - -#ifndef BFD_HOST_64_BIT - #error No 64 bit integer type available -#endif /* ! defined (BFD_HOST_64_BIT) */ - -typedef BFD_HOST_U_64_BIT bfd_vma; -typedef BFD_HOST_64_BIT bfd_signed_vma; -typedef BFD_HOST_U_64_BIT bfd_size_type; -typedef BFD_HOST_U_64_BIT symvalue; - -#if BFD_HOST_64BIT_LONG -#define BFD_VMA_FMT "l" -#elif defined (__MSVCRT__) -#define BFD_VMA_FMT "I64" -#else -#define BFD_VMA_FMT "ll" -#endif - -#ifndef fprintf_vma -#define sprintf_vma(s,x) sprintf (s, "%016" BFD_VMA_FMT "x", x) -#define fprintf_vma(f,x) fprintf (f, "%016" BFD_VMA_FMT "x", x) -#endif - -#else /* not BFD64 */ - -/* Represent a target address. Also used as a generic unsigned type - which is guaranteed to be big enough to hold any arithmetic types - we need to deal with. */ -typedef unsigned long bfd_vma; - -/* A generic signed type which is guaranteed to be big enough to hold any - arithmetic types we need to deal with. Can be assumed to be compatible - with bfd_vma in the same way that signed and unsigned ints are compatible - (as parameters, in assignment, etc). */ -typedef long bfd_signed_vma; - -typedef unsigned long symvalue; -typedef unsigned long bfd_size_type; - -/* Print a bfd_vma x on stream s. */ -#define BFD_VMA_FMT "l" -#define fprintf_vma(s,x) fprintf (s, "%08" BFD_VMA_FMT "x", x) -#define sprintf_vma(s,x) sprintf (s, "%08" BFD_VMA_FMT "x", x) - -#endif /* not BFD64 */ - -#define HALF_BFD_SIZE_TYPE \ - (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2)) - -#ifndef BFD_HOST_64_BIT -/* Fall back on a 32 bit type. The idea is to make these types always - available for function return types, but in the case that - BFD_HOST_64_BIT is undefined such a function should abort or - otherwise signal an error. */ -typedef bfd_signed_vma bfd_int64_t; -typedef bfd_vma bfd_uint64_t; -#endif - -/* An offset into a file. BFD always uses the largest possible offset - based on the build time availability of fseek, fseeko, or fseeko64. */ -typedef @bfd_file_ptr@ file_ptr; -typedef unsigned @bfd_file_ptr@ ufile_ptr; - -extern void bfd_sprintf_vma (bfd *, char *, bfd_vma); -extern void bfd_fprintf_vma (bfd *, void *, bfd_vma); - -#define printf_vma(x) fprintf_vma(stdout,x) -#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x) - -typedef unsigned int flagword; /* 32 bits of flags */ -typedef unsigned char bfd_byte; - -/* File formats. */ - -typedef enum bfd_format -{ - bfd_unknown = 0, /* File format is unknown. */ - bfd_object, /* Linker/assembler/compiler output. */ - bfd_archive, /* Object archive file. */ - bfd_core, /* Core dump. */ - bfd_type_end /* Marks the end; don't use it! */ -} -bfd_format; - -/* Symbols and relocation. */ - -/* A count of carsyms (canonical archive symbols). */ -typedef unsigned long symindex; - -/* How to perform a relocation. */ -typedef const struct reloc_howto_struct reloc_howto_type; - -#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) - -/* General purpose part of a symbol X; - target specific parts are in libcoff.h, libaout.h, etc. */ - -#define bfd_get_section(x) ((x)->section) -#define bfd_get_output_section(x) ((x)->section->output_section) -#define bfd_set_section(x,y) ((x)->section) = (y) -#define bfd_asymbol_base(x) ((x)->section->vma) -#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) -#define bfd_asymbol_name(x) ((x)->name) -/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ -#define bfd_asymbol_bfd(x) ((x)->the_bfd) -#define bfd_asymbol_flavour(x) \ - (((x)->flags & BSF_SYNTHETIC) != 0 \ - ? bfd_target_unknown_flavour \ - : bfd_asymbol_bfd (x)->xvec->flavour) - -/* A canonical archive symbol. */ -/* This is a type pun with struct ranlib on purpose! */ -typedef struct carsym -{ - char *name; - file_ptr file_offset; /* Look here to find the file. */ -} -carsym; /* To make these you call a carsymogen. */ - -/* Used in generating armaps (archive tables of contents). - Perhaps just a forward definition would do? */ -struct orl /* Output ranlib. */ -{ - char **name; /* Symbol name. */ - union - { - file_ptr pos; - bfd *abfd; - } u; /* bfd* or file position. */ - int namidx; /* Index into string table. */ -}; - -/* Linenumber stuff. */ -typedef struct lineno_cache_entry -{ - unsigned int line_number; /* Linenumber from start of function. */ - union - { - struct bfd_symbol *sym; /* Function name. */ - bfd_vma offset; /* Offset into section. */ - } u; -} -alent; - -/* Object and core file sections. */ - -#define align_power(addr, align) \ - (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align))) - -typedef struct bfd_section *sec_ptr; - -#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) -#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) -#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0) -#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) -#define bfd_section_name(bfd, ptr) ((ptr)->name) -#define bfd_section_size(bfd, ptr) ((ptr)->size) -#define bfd_get_section_size(ptr) ((ptr)->size) -#define bfd_section_vma(bfd, ptr) ((ptr)->vma) -#define bfd_section_lma(bfd, ptr) ((ptr)->lma) -#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) -#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) -#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) - -#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) - -#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) -#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) -#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) -/* Find the address one past the end of SEC. */ -#define bfd_get_section_limit(bfd, sec) \ - (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ - ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd)) - -/* Return TRUE if input section SEC has been discarded. */ -#define elf_discarded_section(sec) \ - (!bfd_is_abs_section (sec) \ - && bfd_is_abs_section ((sec)->output_section) \ - && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \ - && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS) - -/* Forward define. */ -struct stat; - -typedef enum bfd_print_symbol -{ - bfd_print_symbol_name, - bfd_print_symbol_more, - bfd_print_symbol_all -} bfd_print_symbol_type; - -/* Information about a symbol that nm needs. */ - -typedef struct _symbol_info -{ - symvalue value; - char type; - const char *name; /* Symbol name. */ - unsigned char stab_type; /* Stab type. */ - char stab_other; /* Stab other. */ - short stab_desc; /* Stab desc. */ - const char *stab_name; /* String for stab type. */ -} symbol_info; - -/* Get the name of a stabs type code. */ - -extern const char *bfd_get_stab_name (int); - -/* Hash table routines. There is no way to free up a hash table. */ - -/* An element in the hash table. Most uses will actually use a larger - structure, and an instance of this will be the first field. */ - -struct bfd_hash_entry -{ - /* Next entry for this hash code. */ - struct bfd_hash_entry *next; - /* String being hashed. */ - const char *string; - /* Hash code. This is the full hash code, not the index into the - table. */ - unsigned long hash; -}; - -/* A hash table. */ - -struct bfd_hash_table -{ - /* The hash array. */ - struct bfd_hash_entry **table; - /* A function used to create new elements in the hash table. The - first entry is itself a pointer to an element. When this - function is first invoked, this pointer will be NULL. However, - having the pointer permits a hierarchy of method functions to be - built each of which calls the function in the superclass. Thus - each function should be written to allocate a new block of memory - only if the argument is NULL. */ - struct bfd_hash_entry *(*newfunc) - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); - /* An objalloc for this hash table. This is a struct objalloc *, - but we use void * to avoid requiring the inclusion of objalloc.h. */ - void *memory; - /* The number of slots in the hash table. */ - unsigned int size; - /* The number of entries in the hash table. */ - unsigned int count; - /* The size of elements. */ - unsigned int entsize; - /* If non-zero, don't grow the hash table. */ - unsigned int frozen:1; -}; - -/* Initialize a hash table. */ -extern bfd_boolean bfd_hash_table_init - (struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int); - -/* Initialize a hash table specifying a size. */ -extern bfd_boolean bfd_hash_table_init_n - (struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int, unsigned int); - -/* Free up a hash table. */ -extern void bfd_hash_table_free - (struct bfd_hash_table *); - -/* Look up a string in a hash table. If CREATE is TRUE, a new entry - will be created for this string if one does not already exist. The - COPY argument must be TRUE if this routine should copy the string - into newly allocated memory when adding an entry. */ -extern struct bfd_hash_entry *bfd_hash_lookup - (struct bfd_hash_table *, const char *, bfd_boolean create, - bfd_boolean copy); - -/* Insert an entry in a hash table. */ -extern struct bfd_hash_entry *bfd_hash_insert - (struct bfd_hash_table *, const char *, unsigned long); - -/* Rename an entry in a hash table. */ -extern void bfd_hash_rename - (struct bfd_hash_table *, const char *, struct bfd_hash_entry *); - -/* Replace an entry in a hash table. */ -extern void bfd_hash_replace - (struct bfd_hash_table *, struct bfd_hash_entry *old, - struct bfd_hash_entry *nw); - -/* Base method for creating a hash table entry. */ -extern struct bfd_hash_entry *bfd_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); - -/* Grab some space for a hash table entry. */ -extern void *bfd_hash_allocate - (struct bfd_hash_table *, unsigned int); - -/* Traverse a hash table in a random order, calling a function on each - element. If the function returns FALSE, the traversal stops. The - INFO argument is passed to the function. */ -extern void bfd_hash_traverse - (struct bfd_hash_table *, - bfd_boolean (*) (struct bfd_hash_entry *, void *), - void *info); - -/* Allows the default size of a hash table to be configured. New hash - tables allocated using bfd_hash_table_init will be created with - this size. */ -extern unsigned long bfd_hash_set_default_size (unsigned long); - -/* This structure is used to keep track of stabs in sections - information while linking. */ - -struct stab_info -{ - /* A hash table used to hold stabs strings. */ - struct bfd_strtab_hash *strings; - /* The header file hash table. */ - struct bfd_hash_table includes; - /* The first .stabstr section. */ - struct bfd_section *stabstr; -}; - -#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table - -/* User program access to BFD facilities. */ - -/* Direct I/O routines, for programs which know more about the object - file than BFD does. Use higher level routines if possible. */ - -extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *); -extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *); -extern int bfd_seek (bfd *, file_ptr, int); -extern file_ptr bfd_tell (bfd *); -extern int bfd_flush (bfd *); -extern int bfd_stat (bfd *, struct stat *); - -/* Deprecated old routines. */ -#if __GNUC__ -#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ - (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \ - bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) -#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ - (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \ - bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) -#else -#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ - (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \ - bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) -#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ - (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\ - bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) -#endif -extern void warn_deprecated (const char *, const char *, int, const char *); - -/* Cast from const char * to char * so that caller can assign to - a char * without a warning. */ -#define bfd_get_filename(abfd) ((char *) (abfd)->filename) -#define bfd_get_cacheable(abfd) ((abfd)->cacheable) -#define bfd_get_format(abfd) ((abfd)->format) -#define bfd_get_target(abfd) ((abfd)->xvec->name) -#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) -#define bfd_family_coff(abfd) \ - (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \ - bfd_get_flavour (abfd) == bfd_target_xcoff_flavour) -#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) -#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) -#define bfd_header_big_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) -#define bfd_header_little_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) -#define bfd_get_file_flags(abfd) ((abfd)->flags) -#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) -#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) -#define bfd_my_archive(abfd) ((abfd)->my_archive) -#define bfd_has_map(abfd) ((abfd)->has_armap) -#define bfd_is_thin_archive(abfd) ((abfd)->is_thin_archive) - -#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) -#define bfd_usrdata(abfd) ((abfd)->usrdata) - -#define bfd_get_start_address(abfd) ((abfd)->start_address) -#define bfd_get_symcount(abfd) ((abfd)->symcount) -#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) -#define bfd_count_sections(abfd) ((abfd)->section_count) - -#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount) - -#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) - -#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) - -extern bfd_boolean bfd_cache_close - (bfd *abfd); -/* NB: This declaration should match the autogenerated one in libbfd.h. */ - -extern bfd_boolean bfd_cache_close_all (void); - -extern bfd_boolean bfd_record_phdr - (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma, - bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **); - -/* Byte swapping routines. */ - -bfd_uint64_t bfd_getb64 (const void *); -bfd_uint64_t bfd_getl64 (const void *); -bfd_int64_t bfd_getb_signed_64 (const void *); -bfd_int64_t bfd_getl_signed_64 (const void *); -bfd_vma bfd_getb32 (const void *); -bfd_vma bfd_getl32 (const void *); -bfd_signed_vma bfd_getb_signed_32 (const void *); -bfd_signed_vma bfd_getl_signed_32 (const void *); -bfd_vma bfd_getb16 (const void *); -bfd_vma bfd_getl16 (const void *); -bfd_signed_vma bfd_getb_signed_16 (const void *); -bfd_signed_vma bfd_getl_signed_16 (const void *); -void bfd_putb64 (bfd_uint64_t, void *); -void bfd_putl64 (bfd_uint64_t, void *); -void bfd_putb32 (bfd_vma, void *); -void bfd_putl32 (bfd_vma, void *); -void bfd_putb16 (bfd_vma, void *); -void bfd_putl16 (bfd_vma, void *); - -/* Byte swapping routines which take size and endiannes as arguments. */ - -bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean); -void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean); - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_debug_info; -struct ecoff_debug_swap; -struct ecoff_extr; -struct bfd_symbol; -struct bfd_link_info; -struct bfd_link_hash_entry; -struct bfd_section_already_linked; -struct bfd_elf_version_tree; -#endif - -extern bfd_boolean bfd_section_already_linked_table_init (void); -extern void bfd_section_already_linked_table_free (void); -extern bfd_boolean _bfd_handle_already_linked - (struct bfd_section *, struct bfd_section_already_linked *, - struct bfd_link_info *); - -/* Externally visible ECOFF routines. */ - -extern bfd_vma bfd_ecoff_get_gp_value - (bfd * abfd); -extern bfd_boolean bfd_ecoff_set_gp_value - (bfd *abfd, bfd_vma gp_value); -extern bfd_boolean bfd_ecoff_set_regmasks - (bfd *abfd, unsigned long gprmask, unsigned long fprmask, - unsigned long *cprmask); -extern void *bfd_ecoff_debug_init - (bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); -extern void bfd_ecoff_debug_free - (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); -extern bfd_boolean bfd_ecoff_debug_accumulate - (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, bfd *input_bfd, - struct ecoff_debug_info *input_debug, - const struct ecoff_debug_swap *input_swap, struct bfd_link_info *); -extern bfd_boolean bfd_ecoff_debug_accumulate_other - (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, bfd *input_bfd, - struct bfd_link_info *); -extern bfd_boolean bfd_ecoff_debug_externals - (bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, bfd_boolean relocatable, - bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *), - void (*set_index) (struct bfd_symbol *, bfd_size_type)); -extern bfd_boolean bfd_ecoff_debug_one_external - (bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, const char *name, - struct ecoff_extr *esym); -extern bfd_size_type bfd_ecoff_debug_size - (bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap); -extern bfd_boolean bfd_ecoff_write_debug - (bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, file_ptr where); -extern bfd_boolean bfd_ecoff_write_accumulated_debug - (void *handle, bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - struct bfd_link_info *info, file_ptr where); - -/* Externally visible ELF routines. */ - -struct bfd_link_needed_list -{ - struct bfd_link_needed_list *next; - bfd *by; - const char *name; -}; - -enum dynamic_lib_link_class { - DYN_NORMAL = 0, - DYN_AS_NEEDED = 1, - DYN_DT_NEEDED = 2, - DYN_NO_ADD_NEEDED = 4, - DYN_NO_NEEDED = 8 -}; - -enum notice_asneeded_action { - notice_as_needed, - notice_not_needed, - notice_needed -}; - -extern bfd_boolean bfd_elf_record_link_assignment - (bfd *, struct bfd_link_info *, const char *, bfd_boolean, - bfd_boolean); -extern struct bfd_link_needed_list *bfd_elf_get_needed_list - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf_get_bfd_needed_list - (bfd *, struct bfd_link_needed_list **); -extern bfd_boolean bfd_elf_size_dynamic_sections - (bfd *, const char *, const char *, const char *, const char *, const char *, - const char * const *, struct bfd_link_info *, struct bfd_section **); -extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr - (bfd *, struct bfd_link_info *); -extern void bfd_elf_set_dt_needed_name - (bfd *, const char *); -extern const char *bfd_elf_get_dt_soname - (bfd *); -extern void bfd_elf_set_dyn_lib_class - (bfd *, enum dynamic_lib_link_class); -extern int bfd_elf_get_dyn_lib_class - (bfd *); -extern struct bfd_link_needed_list *bfd_elf_get_runpath_list - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf_discard_info - (bfd *, struct bfd_link_info *); -extern unsigned int _bfd_elf_default_action_discarded - (struct bfd_section *); - -/* Return an upper bound on the number of bytes required to store a - copy of ABFD's program header table entries. Return -1 if an error - occurs; bfd_get_error will return an appropriate code. */ -extern long bfd_get_elf_phdr_upper_bound - (bfd *abfd); - -/* Copy ABFD's program header table entries to *PHDRS. The entries - will be stored as an array of Elf_Internal_Phdr structures, as - defined in include/elf/internal.h. To find out how large the - buffer needs to be, call bfd_get_elf_phdr_upper_bound. - - Return the number of program header table entries read, or -1 if an - error occurs; bfd_get_error will return an appropriate code. */ -extern int bfd_get_elf_phdrs - (bfd *abfd, void *phdrs); - -/* Create a new BFD as if by bfd_openr. Rather than opening a file, - reconstruct an ELF file by reading the segments out of remote memory - based on the ELF file header at EHDR_VMA and the ELF program headers it - points to. If not null, *LOADBASEP is filled in with the difference - between the VMAs from which the segments were read, and the VMAs the - file headers (and hence BFD's idea of each section's VMA) put them at. - - The function TARGET_READ_MEMORY is called to copy LEN bytes from the - remote memory at target address VMA into the local buffer at MYADDR; it - should return zero on success or an `errno' code on failure. TEMPL must - be a BFD for an ELF target with the word size and byte order found in - the remote memory. */ -extern bfd *bfd_elf_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len)); - -/* Return the arch_size field of an elf bfd, or -1 if not elf. */ -extern int bfd_get_arch_size - (bfd *); - -/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */ -extern int bfd_get_sign_extend_vma - (bfd *); - -extern struct bfd_section *_bfd_elf_tls_setup - (bfd *, struct bfd_link_info *); - -extern void _bfd_fix_excluded_sec_syms - (bfd *, struct bfd_link_info *); - -extern unsigned bfd_m68k_mach_to_features (int); - -extern int bfd_m68k_features_to_mach (unsigned); - -extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs - (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, - char **); - -extern void bfd_elf_m68k_set_target_options (struct bfd_link_info *, int); - -extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs - (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, - char **); - -extern bfd_boolean bfd_cr16_elf32_create_embedded_relocs - (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, - char **); - -/* SunOS shared library support routines for the linker. */ - -extern struct bfd_link_needed_list *bfd_sunos_get_needed_list - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_sunos_record_link_assignment - (bfd *, struct bfd_link_info *, const char *); -extern bfd_boolean bfd_sunos_size_dynamic_sections - (bfd *, struct bfd_link_info *, struct bfd_section **, - struct bfd_section **, struct bfd_section **); - -/* Linux shared library support routines for the linker. */ - -extern bfd_boolean bfd_i386linux_size_dynamic_sections - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_m68klinux_size_dynamic_sections - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_sparclinux_size_dynamic_sections - (bfd *, struct bfd_link_info *); - -/* mmap hacks */ - -struct _bfd_window_internal; -typedef struct _bfd_window_internal bfd_window_internal; - -typedef struct _bfd_window -{ - /* What the user asked for. */ - void *data; - bfd_size_type size; - /* The actual window used by BFD. Small user-requested read-only - regions sharing a page may share a single window into the object - file. Read-write versions shouldn't until I've fixed things to - keep track of which portions have been claimed by the - application; don't want to give the same region back when the - application wants two writable copies! */ - struct _bfd_window_internal *i; -} -bfd_window; - -extern void bfd_init_window - (bfd_window *); -extern void bfd_free_window - (bfd_window *); -extern bfd_boolean bfd_get_file_window - (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean); - -/* XCOFF support routines for the linker. */ - -extern bfd_boolean bfd_xcoff_split_import_path - (bfd *, const char *, const char **, const char **); -extern bfd_boolean bfd_xcoff_set_archive_import_path - (struct bfd_link_info *, bfd *, const char *); -extern bfd_boolean bfd_xcoff_link_record_set - (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type); -extern bfd_boolean bfd_xcoff_import_symbol - (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma, - const char *, const char *, const char *, unsigned int); -extern bfd_boolean bfd_xcoff_export_symbol - (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); -extern bfd_boolean bfd_xcoff_link_count_reloc - (bfd *, struct bfd_link_info *, const char *); -extern bfd_boolean bfd_xcoff_record_link_assignment - (bfd *, struct bfd_link_info *, const char *); -extern bfd_boolean bfd_xcoff_size_dynamic_sections - (bfd *, struct bfd_link_info *, const char *, const char *, - unsigned long, unsigned long, unsigned long, bfd_boolean, - int, bfd_boolean, unsigned int, struct bfd_section **, bfd_boolean); -extern bfd_boolean bfd_xcoff_link_generate_rtinit - (bfd *, const char *, const char *, bfd_boolean); - -/* XCOFF support routines for ar. */ -extern bfd_boolean bfd_xcoff_ar_archive_set_magic - (bfd *, char *); - -/* Externally visible COFF routines. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct internal_syment; -union internal_auxent; -#endif - -extern bfd_boolean bfd_coff_get_syment - (bfd *, struct bfd_symbol *, struct internal_syment *); - -extern bfd_boolean bfd_coff_get_auxent - (bfd *, struct bfd_symbol *, int, union internal_auxent *); - -extern bfd_boolean bfd_coff_set_symbol_class - (bfd *, struct bfd_symbol *, unsigned int); - -extern bfd_boolean bfd_m68k_coff_create_embedded_relocs - (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); - -/* ARM VFP11 erratum workaround support. */ -typedef enum -{ - BFD_ARM_VFP11_FIX_DEFAULT, - BFD_ARM_VFP11_FIX_NONE, - BFD_ARM_VFP11_FIX_SCALAR, - BFD_ARM_VFP11_FIX_VECTOR -} bfd_arm_vfp11_fix; - -extern void bfd_elf32_arm_init_maps - (bfd *); - -extern void bfd_elf32_arm_set_vfp11_fix - (bfd *, struct bfd_link_info *); - -extern void bfd_elf32_arm_set_cortex_a8_fix - (bfd *, struct bfd_link_info *); - -extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan - (bfd *, struct bfd_link_info *); - -extern void bfd_elf32_arm_vfp11_fix_veneer_locations - (bfd *, struct bfd_link_info *); - -/* ARM Interworking support. Called from linker. */ -extern bfd_boolean bfd_arm_allocate_interworking_sections - (struct bfd_link_info *); - -extern bfd_boolean bfd_arm_process_before_allocation - (bfd *, struct bfd_link_info *, int); - -extern bfd_boolean bfd_arm_get_bfd_for_interworking - (bfd *, struct bfd_link_info *); - -/* PE ARM Interworking support. Called from linker. */ -extern bfd_boolean bfd_arm_pe_allocate_interworking_sections - (struct bfd_link_info *); - -extern bfd_boolean bfd_arm_pe_process_before_allocation - (bfd *, struct bfd_link_info *, int); - -extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking - (bfd *, struct bfd_link_info *); - -/* ELF ARM Interworking support. Called from linker. */ -extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections - (struct bfd_link_info *); - -extern bfd_boolean bfd_elf32_arm_process_before_allocation - (bfd *, struct bfd_link_info *); - -void bfd_elf32_arm_set_target_relocs - (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix, - int, int, int, int, int); - -extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking - (bfd *, struct bfd_link_info *); - -extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd - (bfd *, struct bfd_link_info *); - -/* ELF ARM mapping symbol support */ -#define BFD_ARM_SPECIAL_SYM_TYPE_MAP (1 << 0) -#define BFD_ARM_SPECIAL_SYM_TYPE_TAG (1 << 1) -#define BFD_ARM_SPECIAL_SYM_TYPE_OTHER (1 << 2) -#define BFD_ARM_SPECIAL_SYM_TYPE_ANY (~0) -extern bfd_boolean bfd_is_arm_special_symbol_name - (const char * name, int type); - -extern void bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *, int); - -/* ARM Note section processing. */ -extern bfd_boolean bfd_arm_merge_machines - (bfd *, bfd *); - -extern bfd_boolean bfd_arm_update_notes - (bfd *, const char *); - -extern unsigned int bfd_arm_get_mach_from_notes - (bfd *, const char *); - -/* ARM stub generation support. Called from the linker. */ -extern int elf32_arm_setup_section_lists - (bfd *, struct bfd_link_info *); -extern void elf32_arm_next_input_section - (struct bfd_link_info *, struct bfd_section *); -extern bfd_boolean elf32_arm_size_stubs - (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma, - struct bfd_section * (*) (const char *, struct bfd_section *), void (*) (void)); -extern bfd_boolean elf32_arm_build_stubs - (struct bfd_link_info *); - -/* ARM unwind section editing support. */ -extern bfd_boolean elf32_arm_fix_exidx_coverage -(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean); - -/* C6x unwind section editing support. */ -extern bfd_boolean elf32_tic6x_fix_exidx_coverage -(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean); - -/* PowerPC @tls opcode transform/validate. */ -extern unsigned int _bfd_elf_ppc_at_tls_transform - (unsigned int, unsigned int); -/* PowerPC @tprel opcode transform/validate. */ -extern unsigned int _bfd_elf_ppc_at_tprel_transform - (unsigned int, unsigned int); - -/* TI COFF load page support. */ -extern void bfd_ticoff_set_section_load_page - (struct bfd_section *, int); - -extern int bfd_ticoff_get_section_load_page - (struct bfd_section *); - -/* H8/300 functions. */ -extern bfd_vma bfd_h8300_pad_address - (bfd *, bfd_vma); - -/* IA64 Itanium code generation. Called from linker. */ -extern void bfd_elf32_ia64_after_parse - (int); - -extern void bfd_elf64_ia64_after_parse - (int); - -/* This structure is used for a comdat section, as in PE. A comdat - section is associated with a particular symbol. When the linker - sees a comdat section, it keeps only one of the sections with a - given name and associated with a given symbol. */ - -struct coff_comdat_info -{ - /* The name of the symbol associated with a comdat section. */ - const char *name; - - /* The local symbol table index of the symbol associated with a - comdat section. This is only meaningful to the object file format - specific code; it is not an index into the list returned by - bfd_canonicalize_symtab. */ - long symbol; -}; - -extern struct coff_comdat_info *bfd_coff_get_comdat_section - (bfd *, struct bfd_section *); - -/* Extracted from init.c. */ -void bfd_init (void); - -/* Extracted from opncls.c. */ -extern unsigned int bfd_use_reserved_id; -bfd *bfd_fopen (const char *filename, const char *target, - const char *mode, int fd); - -bfd *bfd_openr (const char *filename, const char *target); - -bfd *bfd_fdopenr (const char *filename, const char *target, int fd); - -bfd *bfd_openstreamr (const char *, const char *, void *); - -bfd *bfd_openr_iovec (const char *filename, const char *target, - void *(*open_func) (struct bfd *nbfd, - void *open_closure), - void *open_closure, - file_ptr (*pread_func) (struct bfd *nbfd, - void *stream, - void *buf, - file_ptr nbytes, - file_ptr offset), - int (*close_func) (struct bfd *nbfd, - void *stream), - int (*stat_func) (struct bfd *abfd, - void *stream, - struct stat *sb)); - -bfd *bfd_openw (const char *filename, const char *target); - -bfd_boolean bfd_close (bfd *abfd); - -bfd_boolean bfd_close_all_done (bfd *); - -bfd *bfd_create (const char *filename, bfd *templ); - -bfd_boolean bfd_make_writable (bfd *abfd); - -bfd_boolean bfd_make_readable (bfd *abfd); - -void *bfd_alloc (bfd *abfd, bfd_size_type wanted); - -void *bfd_zalloc (bfd *abfd, bfd_size_type wanted); - -unsigned long bfd_calc_gnu_debuglink_crc32 - (unsigned long crc, const unsigned char *buf, bfd_size_type len); - -char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); - -struct bfd_section *bfd_create_gnu_debuglink_section - (bfd *abfd, const char *filename); - -bfd_boolean bfd_fill_in_gnu_debuglink_section - (bfd *abfd, struct bfd_section *sect, const char *filename); - -/* Extracted from libbfd.c. */ - -/* Byte swapping macros for user section data. */ - -#define bfd_put_8(abfd, val, ptr) \ - ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) -#define bfd_put_signed_8 \ - bfd_put_8 -#define bfd_get_8(abfd, ptr) \ - (*(const unsigned char *) (ptr) & 0xff) -#define bfd_get_signed_8(abfd, ptr) \ - (((*(const unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) - -#define bfd_put_16(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) -#define bfd_put_signed_16 \ - bfd_put_16 -#define bfd_get_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx16, (ptr)) -#define bfd_get_signed_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) - -#define bfd_put_32(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) -#define bfd_put_signed_32 \ - bfd_put_32 -#define bfd_get_32(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx32, (ptr)) -#define bfd_get_signed_32(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) - -#define bfd_put_64(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) -#define bfd_put_signed_64 \ - bfd_put_64 -#define bfd_get_64(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx64, (ptr)) -#define bfd_get_signed_64(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) - -#define bfd_get(bits, abfd, ptr) \ - ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ - : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ - : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ - : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ - : (abort (), (bfd_vma) - 1)) - -#define bfd_put(bits, abfd, val, ptr) \ - ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ - : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ - : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ - : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ - : (abort (), (void) 0)) - - -/* Byte swapping macros for file header data. */ - -#define bfd_h_put_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_put_signed_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_get_8(abfd, ptr) \ - bfd_get_8 (abfd, ptr) -#define bfd_h_get_signed_8(abfd, ptr) \ - bfd_get_signed_8 (abfd, ptr) - -#define bfd_h_put_16(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) -#define bfd_h_put_signed_16 \ - bfd_h_put_16 -#define bfd_h_get_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx16, (ptr)) -#define bfd_h_get_signed_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) - -#define bfd_h_put_32(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) -#define bfd_h_put_signed_32 \ - bfd_h_put_32 -#define bfd_h_get_32(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx32, (ptr)) -#define bfd_h_get_signed_32(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) - -#define bfd_h_put_64(abfd, val, ptr) \ - BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) -#define bfd_h_put_signed_64 \ - bfd_h_put_64 -#define bfd_h_get_64(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx64, (ptr)) -#define bfd_h_get_signed_64(abfd, ptr) \ - BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) - -/* Aliases for the above, which should eventually go away. */ - -#define H_PUT_64 bfd_h_put_64 -#define H_PUT_32 bfd_h_put_32 -#define H_PUT_16 bfd_h_put_16 -#define H_PUT_8 bfd_h_put_8 -#define H_PUT_S64 bfd_h_put_signed_64 -#define H_PUT_S32 bfd_h_put_signed_32 -#define H_PUT_S16 bfd_h_put_signed_16 -#define H_PUT_S8 bfd_h_put_signed_8 -#define H_GET_64 bfd_h_get_64 -#define H_GET_32 bfd_h_get_32 -#define H_GET_16 bfd_h_get_16 -#define H_GET_8 bfd_h_get_8 -#define H_GET_S64 bfd_h_get_signed_64 -#define H_GET_S32 bfd_h_get_signed_32 -#define H_GET_S16 bfd_h_get_signed_16 -#define H_GET_S8 bfd_h_get_signed_8 - - -/* Extracted from bfdio.c. */ -long bfd_get_mtime (bfd *abfd); - -file_ptr bfd_get_size (bfd *abfd); - -void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, - int prot, int flags, file_ptr offset, - void **map_addr, bfd_size_type *map_len); - -/* Extracted from bfdwin.c. */ -/* Extracted from section.c. */ -typedef struct bfd_section -{ - /* The name of the section; the name isn't a copy, the pointer is - the same as that passed to bfd_make_section. */ - const char *name; - - /* A unique sequence number. */ - int id; - - /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ - int index; - - /* The next section in the list belonging to the BFD, or NULL. */ - struct bfd_section *next; - - /* The previous section in the list belonging to the BFD, or NULL. */ - struct bfd_section *prev; - - /* The field flags contains attributes of the section. Some - flags are read in from the object file, and some are - synthesized from other information. */ - flagword flags; - -#define SEC_NO_FLAGS 0x000 - - /* Tells the OS to allocate space for this section when loading. - This is clear for a section containing debug information only. */ -#define SEC_ALLOC 0x001 - - /* Tells the OS to load the section from the file when loading. - This is clear for a .bss section. */ -#define SEC_LOAD 0x002 - - /* The section contains data still to be relocated, so there is - some relocation information too. */ -#define SEC_RELOC 0x004 - - /* A signal to the OS that the section contains read only data. */ -#define SEC_READONLY 0x008 - - /* The section contains code only. */ -#define SEC_CODE 0x010 - - /* The section contains data only. */ -#define SEC_DATA 0x020 - - /* The section will reside in ROM. */ -#define SEC_ROM 0x040 - - /* The section contains constructor information. This section - type is used by the linker to create lists of constructors and - destructors used by <>. When a back end sees a symbol - which should be used in a constructor list, it creates a new - section for the type of name (e.g., <<__CTOR_LIST__>>), attaches - the symbol to it, and builds a relocation. To build the lists - of constructors, all the linker has to do is catenate all the - sections called <<__CTOR_LIST__>> and relocate the data - contained within - exactly the operations it would peform on - standard data. */ -#define SEC_CONSTRUCTOR 0x080 - - /* The section has contents - a data section could be - <> | <>; a debug section could be - <> */ -#define SEC_HAS_CONTENTS 0x100 - - /* An instruction to the linker to not output the section - even if it has information which would normally be written. */ -#define SEC_NEVER_LOAD 0x200 - - /* The section contains thread local data. */ -#define SEC_THREAD_LOCAL 0x400 - - /* The section has GOT references. This flag is only for the - linker, and is currently only used by the elf32-hppa back end. - It will be set if global offset table references were detected - in this section, which indicate to the linker that the section - contains PIC code, and must be handled specially when doing a - static link. */ -#define SEC_HAS_GOT_REF 0x800 - - /* The section contains common symbols (symbols may be defined - multiple times, the value of a symbol is the amount of - space it requires, and the largest symbol value is the one - used). Most targets have exactly one of these (which we - translate to bfd_com_section_ptr), but ECOFF has two. */ -#define SEC_IS_COMMON 0x1000 - - /* The section contains only debugging information. For - example, this is set for ELF .debug and .stab sections. - strip tests this flag to see if a section can be - discarded. */ -#define SEC_DEBUGGING 0x2000 - - /* The contents of this section are held in memory pointed to - by the contents field. This is checked by bfd_get_section_contents, - and the data is retrieved from memory if appropriate. */ -#define SEC_IN_MEMORY 0x4000 - - /* The contents of this section are to be excluded by the - linker for executable and shared objects unless those - objects are to be further relocated. */ -#define SEC_EXCLUDE 0x8000 - - /* The contents of this section are to be sorted based on the sum of - the symbol and addend values specified by the associated relocation - entries. Entries without associated relocation entries will be - appended to the end of the section in an unspecified order. */ -#define SEC_SORT_ENTRIES 0x10000 - - /* When linking, duplicate sections of the same name should be - discarded, rather than being combined into a single section as - is usually done. This is similar to how common symbols are - handled. See SEC_LINK_DUPLICATES below. */ -#define SEC_LINK_ONCE 0x20000 - - /* If SEC_LINK_ONCE is set, this bitfield describes how the linker - should handle duplicate sections. */ -#define SEC_LINK_DUPLICATES 0xc0000 - - /* This value for SEC_LINK_DUPLICATES means that duplicate - sections with the same name should simply be discarded. */ -#define SEC_LINK_DUPLICATES_DISCARD 0x0 - - /* This value for SEC_LINK_DUPLICATES means that the linker - should warn if there are any duplicate sections, although - it should still only link one copy. */ -#define SEC_LINK_DUPLICATES_ONE_ONLY 0x40000 - - /* This value for SEC_LINK_DUPLICATES means that the linker - should warn if any duplicate sections are a different size. */ -#define SEC_LINK_DUPLICATES_SAME_SIZE 0x80000 - - /* This value for SEC_LINK_DUPLICATES means that the linker - should warn if any duplicate sections contain different - contents. */ -#define SEC_LINK_DUPLICATES_SAME_CONTENTS \ - (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) - - /* This section was created by the linker as part of dynamic - relocation or other arcane processing. It is skipped when - going through the first-pass output, trusting that someone - else up the line will take care of it later. */ -#define SEC_LINKER_CREATED 0x100000 - - /* This section should not be subject to garbage collection. - Also set to inform the linker that this section should not be - listed in the link map as discarded. */ -#define SEC_KEEP 0x200000 - - /* This section contains "short" data, and should be placed - "near" the GP. */ -#define SEC_SMALL_DATA 0x400000 - - /* Attempt to merge identical entities in the section. - Entity size is given in the entsize field. */ -#define SEC_MERGE 0x800000 - - /* If given with SEC_MERGE, entities to merge are zero terminated - strings where entsize specifies character size instead of fixed - size entries. */ -#define SEC_STRINGS 0x1000000 - - /* This section contains data about section groups. */ -#define SEC_GROUP 0x2000000 - - /* The section is a COFF shared library section. This flag is - only for the linker. If this type of section appears in - the input file, the linker must copy it to the output file - without changing the vma or size. FIXME: Although this - was originally intended to be general, it really is COFF - specific (and the flag was renamed to indicate this). It - might be cleaner to have some more general mechanism to - allow the back end to control what the linker does with - sections. */ -#define SEC_COFF_SHARED_LIBRARY 0x4000000 - - /* This input section should be copied to output in reverse order - as an array of pointers. This is for ELF linker internal use - only. */ -#define SEC_ELF_REVERSE_COPY 0x4000000 - - /* This section contains data which may be shared with other - executables or shared objects. This is for COFF only. */ -#define SEC_COFF_SHARED 0x8000000 - - /* When a section with this flag is being linked, then if the size of - the input section is less than a page, it should not cross a page - boundary. If the size of the input section is one page or more, - it should be aligned on a page boundary. This is for TI - TMS320C54X only. */ -#define SEC_TIC54X_BLOCK 0x10000000 - - /* Conditionally link this section; do not link if there are no - references found to any symbol in the section. This is for TI - TMS320C54X only. */ -#define SEC_TIC54X_CLINK 0x20000000 - - /* Indicate that section has the no read flag set. This happens - when memory read flag isn't set. */ -#define SEC_COFF_NOREAD 0x40000000 - - /* End of section flags. */ - - /* Some internal packed boolean fields. */ - - /* See the vma field. */ - unsigned int user_set_vma : 1; - - /* A mark flag used by some of the linker backends. */ - unsigned int linker_mark : 1; - - /* Another mark flag used by some of the linker backends. Set for - output sections that have an input section. */ - unsigned int linker_has_input : 1; - - /* Mark flag used by some linker backends for garbage collection. */ - unsigned int gc_mark : 1; - - /* Section compression status. */ - unsigned int compress_status : 2; -#define COMPRESS_SECTION_NONE 0 -#define COMPRESS_SECTION_DONE 1 -#define DECOMPRESS_SECTION_SIZED 2 - - /* The following flags are used by the ELF linker. */ - - /* Mark sections which have been allocated to segments. */ - unsigned int segment_mark : 1; - - /* Type of sec_info information. */ - unsigned int sec_info_type:3; -#define ELF_INFO_TYPE_NONE 0 -#define ELF_INFO_TYPE_STABS 1 -#define ELF_INFO_TYPE_MERGE 2 -#define ELF_INFO_TYPE_EH_FRAME 3 -#define ELF_INFO_TYPE_JUST_SYMS 4 - - /* Nonzero if this section uses RELA relocations, rather than REL. */ - unsigned int use_rela_p:1; - - /* Bits used by various backends. The generic code doesn't touch - these fields. */ - - unsigned int sec_flg0:1; - unsigned int sec_flg1:1; - unsigned int sec_flg2:1; - unsigned int sec_flg3:1; - unsigned int sec_flg4:1; - unsigned int sec_flg5:1; - - /* End of internal packed boolean fields. */ - - /* The virtual memory address of the section - where it will be - at run time. The symbols are relocated against this. The - user_set_vma flag is maintained by bfd; if it's not set, the - backend can assign addresses (for example, in <>, where - the default address for <<.data>> is dependent on the specific - target and various flags). */ - bfd_vma vma; - - /* The load address of the section - where it would be in a - rom image; really only used for writing section header - information. */ - bfd_vma lma; - - /* The size of the section in octets, as it will be output. - Contains a value even if the section has no contents (e.g., the - size of <<.bss>>). */ - bfd_size_type size; - - /* For input sections, the original size on disk of the section, in - octets. This field should be set for any section whose size is - changed by linker relaxation. It is required for sections where - the linker relaxation scheme doesn't cache altered section and - reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing - targets), and thus the original size needs to be kept to read the - section multiple times. For output sections, rawsize holds the - section size calculated on a previous linker relaxation pass. */ - bfd_size_type rawsize; - - /* The compressed size of the section in octets. */ - bfd_size_type compressed_size; - - /* Relaxation table. */ - struct relax_table *relax; - - /* Count of used relaxation table entries. */ - int relax_count; - - - /* If this section is going to be output, then this value is the - offset in *bytes* into the output section of the first byte in the - input section (byte ==> smallest addressable unit on the - target). In most cases, if this was going to start at the - 100th octet (8-bit quantity) in the output section, this value - would be 100. However, if the target byte size is 16 bits - (bfd_octets_per_byte is "2"), this value would be 50. */ - bfd_vma output_offset; - - /* The output section through which to map on output. */ - struct bfd_section *output_section; - - /* The alignment requirement of the section, as an exponent of 2 - - e.g., 3 aligns to 2^3 (or 8). */ - unsigned int alignment_power; - - /* If an input section, a pointer to a vector of relocation - records for the data in this section. */ - struct reloc_cache_entry *relocation; - - /* If an output section, a pointer to a vector of pointers to - relocation records for the data in this section. */ - struct reloc_cache_entry **orelocation; - - /* The number of relocation records in one of the above. */ - unsigned reloc_count; - - /* Information below is back end specific - and not always used - or updated. */ - - /* File position of section data. */ - file_ptr filepos; - - /* File position of relocation info. */ - file_ptr rel_filepos; - - /* File position of line data. */ - file_ptr line_filepos; - - /* Pointer to data for applications. */ - void *userdata; - - /* If the SEC_IN_MEMORY flag is set, this points to the actual - contents. */ - unsigned char *contents; - - /* Attached line number information. */ - alent *lineno; - - /* Number of line number records. */ - unsigned int lineno_count; - - /* Entity size for merging purposes. */ - unsigned int entsize; - - /* Points to the kept section if this section is a link-once section, - and is discarded. */ - struct bfd_section *kept_section; - - /* When a section is being output, this value changes as more - linenumbers are written out. */ - file_ptr moving_line_filepos; - - /* What the section number is in the target world. */ - int target_index; - - void *used_by_bfd; - - /* If this is a constructor section then here is a list of the - relocations created to relocate items within it. */ - struct relent_chain *constructor_chain; - - /* The BFD which owns the section. */ - bfd *owner; - - /* INPUT_SECTION_FLAGS if specified in the linker script. */ - struct flag_info *section_flag_info; - - /* A symbol which points at this section only. */ - struct bfd_symbol *symbol; - struct bfd_symbol **symbol_ptr_ptr; - - /* Early in the link process, map_head and map_tail are used to build - a list of input sections attached to an output section. Later, - output sections use these fields for a list of bfd_link_order - structs. */ - union { - struct bfd_link_order *link_order; - struct bfd_section *s; - } map_head, map_tail; -} asection; - -/* Relax table contains information about instructions which can - be removed by relaxation -- replacing a long address with a - short address. */ -struct relax_table { - /* Address where bytes may be deleted. */ - bfd_vma addr; - - /* Number of bytes to be deleted. */ - int size; -}; - -/* These sections are global, and are managed by BFD. The application - and target back end are not permitted to change the values in - these sections. New code should use the section_ptr macros rather - than referring directly to the const sections. The const sections - may eventually vanish. */ -#define BFD_ABS_SECTION_NAME "*ABS*" -#define BFD_UND_SECTION_NAME "*UND*" -#define BFD_COM_SECTION_NAME "*COM*" -#define BFD_IND_SECTION_NAME "*IND*" - -/* The absolute section. */ -extern asection bfd_abs_section; -#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) -/* Pointer to the undefined section. */ -extern asection bfd_und_section; -#define bfd_und_section_ptr ((asection *) &bfd_und_section) -#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) -/* Pointer to the common section. */ -extern asection bfd_com_section; -#define bfd_com_section_ptr ((asection *) &bfd_com_section) -/* Pointer to the indirect section. */ -extern asection bfd_ind_section; -#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) - -#define bfd_is_const_section(SEC) \ - ( ((SEC) == bfd_abs_section_ptr) \ - || ((SEC) == bfd_und_section_ptr) \ - || ((SEC) == bfd_com_section_ptr) \ - || ((SEC) == bfd_ind_section_ptr)) - -/* Macros to handle insertion and deletion of a bfd's sections. These - only handle the list pointers, ie. do not adjust section_count, - target_index etc. */ -#define bfd_section_list_remove(ABFD, S) \ - do \ - { \ - asection *_s = S; \ - asection *_next = _s->next; \ - asection *_prev = _s->prev; \ - if (_prev) \ - _prev->next = _next; \ - else \ - (ABFD)->sections = _next; \ - if (_next) \ - _next->prev = _prev; \ - else \ - (ABFD)->section_last = _prev; \ - } \ - while (0) -#define bfd_section_list_append(ABFD, S) \ - do \ - { \ - asection *_s = S; \ - bfd *_abfd = ABFD; \ - _s->next = NULL; \ - if (_abfd->section_last) \ - { \ - _s->prev = _abfd->section_last; \ - _abfd->section_last->next = _s; \ - } \ - else \ - { \ - _s->prev = NULL; \ - _abfd->sections = _s; \ - } \ - _abfd->section_last = _s; \ - } \ - while (0) -#define bfd_section_list_prepend(ABFD, S) \ - do \ - { \ - asection *_s = S; \ - bfd *_abfd = ABFD; \ - _s->prev = NULL; \ - if (_abfd->sections) \ - { \ - _s->next = _abfd->sections; \ - _abfd->sections->prev = _s; \ - } \ - else \ - { \ - _s->next = NULL; \ - _abfd->section_last = _s; \ - } \ - _abfd->sections = _s; \ - } \ - while (0) -#define bfd_section_list_insert_after(ABFD, A, S) \ - do \ - { \ - asection *_a = A; \ - asection *_s = S; \ - asection *_next = _a->next; \ - _s->next = _next; \ - _s->prev = _a; \ - _a->next = _s; \ - if (_next) \ - _next->prev = _s; \ - else \ - (ABFD)->section_last = _s; \ - } \ - while (0) -#define bfd_section_list_insert_before(ABFD, B, S) \ - do \ - { \ - asection *_b = B; \ - asection *_s = S; \ - asection *_prev = _b->prev; \ - _s->prev = _prev; \ - _s->next = _b; \ - _b->prev = _s; \ - if (_prev) \ - _prev->next = _s; \ - else \ - (ABFD)->sections = _s; \ - } \ - while (0) -#define bfd_section_removed_from_list(ABFD, S) \ - ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) - -#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ - /* name, id, index, next, prev, flags, user_set_vma, */ \ - { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ - \ - /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ - 0, 0, 1, 0, \ - \ - /* segment_mark, sec_info_type, use_rela_p, */ \ - 0, 0, 0, \ - \ - /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \ - 0, 0, 0, 0, 0, 0, \ - \ - /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \ - 0, 0, 0, 0, 0, 0, 0, \ - \ - /* output_offset, output_section, alignment_power, */ \ - 0, (struct bfd_section *) &SEC, 0, \ - \ - /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ - NULL, NULL, 0, 0, 0, \ - \ - /* line_filepos, userdata, contents, lineno, lineno_count, */ \ - 0, NULL, NULL, NULL, 0, \ - \ - /* entsize, kept_section, moving_line_filepos, */ \ - 0, NULL, 0, \ - \ - /* target_index, used_by_bfd, constructor_chain, owner, */ \ - 0, NULL, NULL, NULL, \ - \ - /* flag_info, */ \ - NULL, \ - \ - /* symbol, symbol_ptr_ptr, */ \ - (struct bfd_symbol *) SYM, &SEC.symbol, \ - \ - /* map_head, map_tail */ \ - { NULL }, { NULL } \ - } - -void bfd_section_list_clear (bfd *); - -asection *bfd_get_section_by_name (bfd *abfd, const char *name); - -asection *bfd_get_section_by_name_if - (bfd *abfd, - const char *name, - bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), - void *obj); - -char *bfd_get_unique_section_name - (bfd *abfd, const char *templat, int *count); - -asection *bfd_make_section_old_way (bfd *abfd, const char *name); - -asection *bfd_make_section_anyway_with_flags - (bfd *abfd, const char *name, flagword flags); - -asection *bfd_make_section_anyway (bfd *abfd, const char *name); - -asection *bfd_make_section_with_flags - (bfd *, const char *name, flagword flags); - -asection *bfd_make_section (bfd *, const char *name); - -bfd_boolean bfd_set_section_flags - (bfd *abfd, asection *sec, flagword flags); - -void bfd_rename_section - (bfd *abfd, asection *sec, const char *newname); - -void bfd_map_over_sections - (bfd *abfd, - void (*func) (bfd *abfd, asection *sect, void *obj), - void *obj); - -asection *bfd_sections_find_if - (bfd *abfd, - bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), - void *obj); - -bfd_boolean bfd_set_section_size - (bfd *abfd, asection *sec, bfd_size_type val); - -bfd_boolean bfd_set_section_contents - (bfd *abfd, asection *section, const void *data, - file_ptr offset, bfd_size_type count); - -bfd_boolean bfd_get_section_contents - (bfd *abfd, asection *section, void *location, file_ptr offset, - bfd_size_type count); - -bfd_boolean bfd_malloc_and_get_section - (bfd *abfd, asection *section, bfd_byte **buf); - -bfd_boolean bfd_copy_private_section_data - (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); - -#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ - BFD_SEND (obfd, _bfd_copy_private_section_data, \ - (ibfd, isection, obfd, osection)) -bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); - -bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); - -/* Extracted from archures.c. */ -enum bfd_architecture -{ - bfd_arch_unknown, /* File arch not known. */ - bfd_arch_obscure, /* Arch known, not one of these. */ - bfd_arch_m68k, /* Motorola 68xxx */ -#define bfd_mach_m68000 1 -#define bfd_mach_m68008 2 -#define bfd_mach_m68010 3 -#define bfd_mach_m68020 4 -#define bfd_mach_m68030 5 -#define bfd_mach_m68040 6 -#define bfd_mach_m68060 7 -#define bfd_mach_cpu32 8 -#define bfd_mach_fido 9 -#define bfd_mach_mcf_isa_a_nodiv 10 -#define bfd_mach_mcf_isa_a 11 -#define bfd_mach_mcf_isa_a_mac 12 -#define bfd_mach_mcf_isa_a_emac 13 -#define bfd_mach_mcf_isa_aplus 14 -#define bfd_mach_mcf_isa_aplus_mac 15 -#define bfd_mach_mcf_isa_aplus_emac 16 -#define bfd_mach_mcf_isa_b_nousp 17 -#define bfd_mach_mcf_isa_b_nousp_mac 18 -#define bfd_mach_mcf_isa_b_nousp_emac 19 -#define bfd_mach_mcf_isa_b 20 -#define bfd_mach_mcf_isa_b_mac 21 -#define bfd_mach_mcf_isa_b_emac 22 -#define bfd_mach_mcf_isa_b_float 23 -#define bfd_mach_mcf_isa_b_float_mac 24 -#define bfd_mach_mcf_isa_b_float_emac 25 -#define bfd_mach_mcf_isa_c 26 -#define bfd_mach_mcf_isa_c_mac 27 -#define bfd_mach_mcf_isa_c_emac 28 -#define bfd_mach_mcf_isa_c_nodiv 29 -#define bfd_mach_mcf_isa_c_nodiv_mac 30 -#define bfd_mach_mcf_isa_c_nodiv_emac 31 - bfd_arch_vax, /* DEC Vax */ - bfd_arch_i960, /* Intel 960 */ - /* The order of the following is important. - lower number indicates a machine type that - only accepts a subset of the instructions - available to machines with higher numbers. - The exception is the "ca", which is - incompatible with all other machines except - "core". */ - -#define bfd_mach_i960_core 1 -#define bfd_mach_i960_ka_sa 2 -#define bfd_mach_i960_kb_sb 3 -#define bfd_mach_i960_mc 4 -#define bfd_mach_i960_xa 5 -#define bfd_mach_i960_ca 6 -#define bfd_mach_i960_jx 7 -#define bfd_mach_i960_hx 8 - - bfd_arch_or32, /* OpenRISC 32 */ - - bfd_arch_sparc, /* SPARC */ -#define bfd_mach_sparc 1 -/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ -#define bfd_mach_sparc_sparclet 2 -#define bfd_mach_sparc_sparclite 3 -#define bfd_mach_sparc_v8plus 4 -#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ -#define bfd_mach_sparc_sparclite_le 6 -#define bfd_mach_sparc_v9 7 -#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ -#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ -#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ -/* Nonzero if MACH has the v9 instruction set. */ -#define bfd_mach_sparc_v9_p(mach) \ - ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ - && (mach) != bfd_mach_sparc_sparclite_le) -/* Nonzero if MACH is a 64 bit sparc architecture. */ -#define bfd_mach_sparc_64bit_p(mach) \ - ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) - bfd_arch_spu, /* PowerPC SPU */ -#define bfd_mach_spu 256 - bfd_arch_mips, /* MIPS Rxxxx */ -#define bfd_mach_mips3000 3000 -#define bfd_mach_mips3900 3900 -#define bfd_mach_mips4000 4000 -#define bfd_mach_mips4010 4010 -#define bfd_mach_mips4100 4100 -#define bfd_mach_mips4111 4111 -#define bfd_mach_mips4120 4120 -#define bfd_mach_mips4300 4300 -#define bfd_mach_mips4400 4400 -#define bfd_mach_mips4600 4600 -#define bfd_mach_mips4650 4650 -#define bfd_mach_mips5000 5000 -#define bfd_mach_mips5400 5400 -#define bfd_mach_mips5500 5500 -#define bfd_mach_mips6000 6000 -#define bfd_mach_mips7000 7000 -#define bfd_mach_mips8000 8000 -#define bfd_mach_mips9000 9000 -#define bfd_mach_mips10000 10000 -#define bfd_mach_mips12000 12000 -#define bfd_mach_mips14000 14000 -#define bfd_mach_mips16000 16000 -#define bfd_mach_mips16 16 -#define bfd_mach_mips5 5 -#define bfd_mach_mips_loongson_2e 3001 -#define bfd_mach_mips_loongson_2f 3002 -#define bfd_mach_mips_loongson_3a 3003 -#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ -#define bfd_mach_mips_octeon 6501 -#define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */ -#define bfd_mach_mipsisa32 32 -#define bfd_mach_mipsisa32r2 33 -#define bfd_mach_mipsisa64 64 -#define bfd_mach_mipsisa64r2 65 -#define bfd_mach_mips_micromips 96 - bfd_arch_i386, /* Intel 386 */ -#define bfd_mach_i386_intel_syntax (1 << 0) -#define bfd_mach_i386_i8086 (1 << 1) -#define bfd_mach_i386_i386 (1 << 2) -#define bfd_mach_x86_64 (1 << 3) -#define bfd_mach_x64_32 (1 << 4) -#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax) -#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax) -#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax) - bfd_arch_l1om, /* Intel L1OM */ -#define bfd_mach_l1om (1 << 5) -#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax) - bfd_arch_k1om, /* Intel K1OM */ -#define bfd_mach_k1om (1 << 6) -#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax) - bfd_arch_we32k, /* AT&T WE32xxx */ - bfd_arch_tahoe, /* CCI/Harris Tahoe */ - bfd_arch_i860, /* Intel 860 */ - bfd_arch_i370, /* IBM 360/370 Mainframes */ - bfd_arch_romp, /* IBM ROMP PC/RT */ - bfd_arch_convex, /* Convex */ - bfd_arch_m88k, /* Motorola 88xxx */ - bfd_arch_m98k, /* Motorola 98xxx */ - bfd_arch_pyramid, /* Pyramid Technology */ - bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ -#define bfd_mach_h8300 1 -#define bfd_mach_h8300h 2 -#define bfd_mach_h8300s 3 -#define bfd_mach_h8300hn 4 -#define bfd_mach_h8300sn 5 -#define bfd_mach_h8300sx 6 -#define bfd_mach_h8300sxn 7 - bfd_arch_pdp11, /* DEC PDP-11 */ - bfd_arch_plugin, - bfd_arch_powerpc, /* PowerPC */ -#define bfd_mach_ppc 32 -#define bfd_mach_ppc64 64 -#define bfd_mach_ppc_403 403 -#define bfd_mach_ppc_403gc 4030 -#define bfd_mach_ppc_405 405 -#define bfd_mach_ppc_505 505 -#define bfd_mach_ppc_601 601 -#define bfd_mach_ppc_602 602 -#define bfd_mach_ppc_603 603 -#define bfd_mach_ppc_ec603e 6031 -#define bfd_mach_ppc_604 604 -#define bfd_mach_ppc_620 620 -#define bfd_mach_ppc_630 630 -#define bfd_mach_ppc_750 750 -#define bfd_mach_ppc_860 860 -#define bfd_mach_ppc_a35 35 -#define bfd_mach_ppc_rs64ii 642 -#define bfd_mach_ppc_rs64iii 643 -#define bfd_mach_ppc_7400 7400 -#define bfd_mach_ppc_e500 500 -#define bfd_mach_ppc_e500mc 5001 -#define bfd_mach_ppc_e500mc64 5005 -#define bfd_mach_ppc_titan 83 - bfd_arch_rs6000, /* IBM RS/6000 */ -#define bfd_mach_rs6k 6000 -#define bfd_mach_rs6k_rs1 6001 -#define bfd_mach_rs6k_rsc 6003 -#define bfd_mach_rs6k_rs2 6002 - bfd_arch_hppa, /* HP PA RISC */ -#define bfd_mach_hppa10 10 -#define bfd_mach_hppa11 11 -#define bfd_mach_hppa20 20 -#define bfd_mach_hppa20w 25 - bfd_arch_d10v, /* Mitsubishi D10V */ -#define bfd_mach_d10v 1 -#define bfd_mach_d10v_ts2 2 -#define bfd_mach_d10v_ts3 3 - bfd_arch_d30v, /* Mitsubishi D30V */ - bfd_arch_dlx, /* DLX */ - bfd_arch_m68hc11, /* Motorola 68HC11 */ - bfd_arch_m68hc12, /* Motorola 68HC12 */ -#define bfd_mach_m6812_default 0 -#define bfd_mach_m6812 1 -#define bfd_mach_m6812s 2 - bfd_arch_z8k, /* Zilog Z8000 */ -#define bfd_mach_z8001 1 -#define bfd_mach_z8002 2 - bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ - bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ -#define bfd_mach_sh 1 -#define bfd_mach_sh2 0x20 -#define bfd_mach_sh_dsp 0x2d -#define bfd_mach_sh2a 0x2a -#define bfd_mach_sh2a_nofpu 0x2b -#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 -#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 -#define bfd_mach_sh2a_or_sh4 0x2a3 -#define bfd_mach_sh2a_or_sh3e 0x2a4 -#define bfd_mach_sh2e 0x2e -#define bfd_mach_sh3 0x30 -#define bfd_mach_sh3_nommu 0x31 -#define bfd_mach_sh3_dsp 0x3d -#define bfd_mach_sh3e 0x3e -#define bfd_mach_sh4 0x40 -#define bfd_mach_sh4_nofpu 0x41 -#define bfd_mach_sh4_nommu_nofpu 0x42 -#define bfd_mach_sh4a 0x4a -#define bfd_mach_sh4a_nofpu 0x4b -#define bfd_mach_sh4al_dsp 0x4d -#define bfd_mach_sh5 0x50 - bfd_arch_alpha, /* Dec Alpha */ -#define bfd_mach_alpha_ev4 0x10 -#define bfd_mach_alpha_ev5 0x20 -#define bfd_mach_alpha_ev6 0x30 - bfd_arch_arm, /* Advanced Risc Machines ARM. */ -#define bfd_mach_arm_unknown 0 -#define bfd_mach_arm_2 1 -#define bfd_mach_arm_2a 2 -#define bfd_mach_arm_3 3 -#define bfd_mach_arm_3M 4 -#define bfd_mach_arm_4 5 -#define bfd_mach_arm_4T 6 -#define bfd_mach_arm_5 7 -#define bfd_mach_arm_5T 8 -#define bfd_mach_arm_5TE 9 -#define bfd_mach_arm_XScale 10 -#define bfd_mach_arm_ep9312 11 -#define bfd_mach_arm_iWMMXt 12 -#define bfd_mach_arm_iWMMXt2 13 - bfd_arch_ns32k, /* National Semiconductors ns32000 */ - bfd_arch_w65, /* WDC 65816 */ - bfd_arch_tic30, /* Texas Instruments TMS320C30 */ - bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ -#define bfd_mach_tic3x 30 -#define bfd_mach_tic4x 40 - bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ - bfd_arch_tic6x, /* Texas Instruments TMS320C6X */ - bfd_arch_tic80, /* TI TMS320c80 (MVP) */ - bfd_arch_v850, /* NEC V850 */ -#define bfd_mach_v850 1 -#define bfd_mach_v850e 'E' -#define bfd_mach_v850e1 '1' -#define bfd_mach_v850e2 0x4532 -#define bfd_mach_v850e2v3 0x45325633 - bfd_arch_arc, /* ARC Cores */ -#define bfd_mach_arc_5 5 -#define bfd_mach_arc_6 6 -#define bfd_mach_arc_7 7 -#define bfd_mach_arc_8 8 - bfd_arch_m32c, /* Renesas M16C/M32C. */ -#define bfd_mach_m16c 0x75 -#define bfd_mach_m32c 0x78 - bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ -#define bfd_mach_m32r 1 /* For backwards compatibility. */ -#define bfd_mach_m32rx 'x' -#define bfd_mach_m32r2 '2' - bfd_arch_mn10200, /* Matsushita MN10200 */ - bfd_arch_mn10300, /* Matsushita MN10300 */ -#define bfd_mach_mn10300 300 -#define bfd_mach_am33 330 -#define bfd_mach_am33_2 332 - bfd_arch_fr30, -#define bfd_mach_fr30 0x46523330 - bfd_arch_frv, -#define bfd_mach_frv 1 -#define bfd_mach_frvsimple 2 -#define bfd_mach_fr300 300 -#define bfd_mach_fr400 400 -#define bfd_mach_fr450 450 -#define bfd_mach_frvtomcat 499 /* fr500 prototype */ -#define bfd_mach_fr500 500 -#define bfd_mach_fr550 550 - bfd_arch_moxie, /* The moxie processor */ -#define bfd_mach_moxie 1 - bfd_arch_mcore, - bfd_arch_mep, -#define bfd_mach_mep 1 -#define bfd_mach_mep_h1 0x6831 -#define bfd_mach_mep_c5 0x6335 - bfd_arch_ia64, /* HP/Intel ia64 */ -#define bfd_mach_ia64_elf64 64 -#define bfd_mach_ia64_elf32 32 - bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ -#define bfd_mach_ip2022 1 -#define bfd_mach_ip2022ext 2 - bfd_arch_iq2000, /* Vitesse IQ2000. */ -#define bfd_mach_iq2000 1 -#define bfd_mach_iq10 2 - bfd_arch_mt, -#define bfd_mach_ms1 1 -#define bfd_mach_mrisc2 2 -#define bfd_mach_ms2 3 - bfd_arch_pj, - bfd_arch_avr, /* Atmel AVR microcontrollers. */ -#define bfd_mach_avr1 1 -#define bfd_mach_avr2 2 -#define bfd_mach_avr25 25 -#define bfd_mach_avr3 3 -#define bfd_mach_avr31 31 -#define bfd_mach_avr35 35 -#define bfd_mach_avr4 4 -#define bfd_mach_avr5 5 -#define bfd_mach_avr51 51 -#define bfd_mach_avr6 6 -#define bfd_mach_avrxmega1 101 -#define bfd_mach_avrxmega2 102 -#define bfd_mach_avrxmega3 103 -#define bfd_mach_avrxmega4 104 -#define bfd_mach_avrxmega5 105 -#define bfd_mach_avrxmega6 106 -#define bfd_mach_avrxmega7 107 - bfd_arch_bfin, /* ADI Blackfin */ -#define bfd_mach_bfin 1 - bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ -#define bfd_mach_cr16 1 - bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ -#define bfd_mach_cr16c 1 - bfd_arch_crx, /* National Semiconductor CRX. */ -#define bfd_mach_crx 1 - bfd_arch_cris, /* Axis CRIS */ -#define bfd_mach_cris_v0_v10 255 -#define bfd_mach_cris_v32 32 -#define bfd_mach_cris_v10_v32 1032 - bfd_arch_rx, /* Renesas RX. */ -#define bfd_mach_rx 0x75 - bfd_arch_s390, /* IBM s390 */ -#define bfd_mach_s390_31 31 -#define bfd_mach_s390_64 64 - bfd_arch_score, /* Sunplus score */ -#define bfd_mach_score3 3 -#define bfd_mach_score7 7 - bfd_arch_openrisc, /* OpenRISC */ - bfd_arch_mmix, /* Donald Knuth's educational processor. */ - bfd_arch_xstormy16, -#define bfd_mach_xstormy16 1 - bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ -#define bfd_mach_msp11 11 -#define bfd_mach_msp110 110 -#define bfd_mach_msp12 12 -#define bfd_mach_msp13 13 -#define bfd_mach_msp14 14 -#define bfd_mach_msp15 15 -#define bfd_mach_msp16 16 -#define bfd_mach_msp21 21 -#define bfd_mach_msp31 31 -#define bfd_mach_msp32 32 -#define bfd_mach_msp33 33 -#define bfd_mach_msp41 41 -#define bfd_mach_msp42 42 -#define bfd_mach_msp43 43 -#define bfd_mach_msp44 44 - bfd_arch_xc16x, /* Infineon's XC16X Series. */ -#define bfd_mach_xc16x 1 -#define bfd_mach_xc16xl 2 -#define bfd_mach_xc16xs 3 - bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ -#define bfd_mach_xtensa 1 - bfd_arch_z80, -#define bfd_mach_z80strict 1 /* No undocumented opcodes. */ -#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */ -#define bfd_mach_z80full 7 /* All undocumented instructions. */ -#define bfd_mach_r800 11 /* R800: successor with multiplication. */ - bfd_arch_lm32, /* Lattice Mico32 */ -#define bfd_mach_lm32 1 - bfd_arch_microblaze,/* Xilinx MicroBlaze. */ - bfd_arch_tilepro, /* Tilera TILEPro */ - bfd_arch_tilegx, /* Tilera TILE-Gx */ -#define bfd_mach_tilepro 1 -#define bfd_mach_tilegx 1 - bfd_arch_last - }; - -typedef struct bfd_arch_info -{ - int bits_per_word; - int bits_per_address; - int bits_per_byte; - enum bfd_architecture arch; - unsigned long mach; - const char *arch_name; - const char *printable_name; - unsigned int section_align_power; - /* TRUE if this is the default machine for the architecture. - The default arch should be the first entry for an arch so that - all the entries for that arch can be accessed via <>. */ - bfd_boolean the_default; - const struct bfd_arch_info * (*compatible) - (const struct bfd_arch_info *a, const struct bfd_arch_info *b); - - bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); - - const struct bfd_arch_info *next; -} -bfd_arch_info_type; - -const char *bfd_printable_name (bfd *abfd); - -const bfd_arch_info_type *bfd_scan_arch (const char *string); - -const char **bfd_arch_list (void); - -const bfd_arch_info_type *bfd_arch_get_compatible - (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); - -void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); - -enum bfd_architecture bfd_get_arch (bfd *abfd); - -unsigned long bfd_get_mach (bfd *abfd); - -unsigned int bfd_arch_bits_per_byte (bfd *abfd); - -unsigned int bfd_arch_bits_per_address (bfd *abfd); - -const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); - -const bfd_arch_info_type *bfd_lookup_arch - (enum bfd_architecture arch, unsigned long machine); - -const char *bfd_printable_arch_mach - (enum bfd_architecture arch, unsigned long machine); - -unsigned int bfd_octets_per_byte (bfd *abfd); - -unsigned int bfd_arch_mach_octets_per_byte - (enum bfd_architecture arch, unsigned long machine); - -/* Extracted from reloc.c. */ -typedef enum bfd_reloc_status -{ - /* No errors detected. */ - bfd_reloc_ok, - - /* The relocation was performed, but there was an overflow. */ - bfd_reloc_overflow, - - /* The address to relocate was not within the section supplied. */ - bfd_reloc_outofrange, - - /* Used by special functions. */ - bfd_reloc_continue, - - /* Unsupported relocation size requested. */ - bfd_reloc_notsupported, - - /* Unused. */ - bfd_reloc_other, - - /* The symbol to relocate against was undefined. */ - bfd_reloc_undefined, - - /* The relocation was performed, but may not be ok - presently - generated only when linking i960 coff files with i960 b.out - symbols. If this type is returned, the error_message argument - to bfd_perform_relocation will be set. */ - bfd_reloc_dangerous - } - bfd_reloc_status_type; - - -typedef struct reloc_cache_entry -{ - /* A pointer into the canonical table of pointers. */ - struct bfd_symbol **sym_ptr_ptr; - - /* offset in section. */ - bfd_size_type address; - - /* addend for relocation value. */ - bfd_vma addend; - - /* Pointer to how to perform the required relocation. */ - reloc_howto_type *howto; - -} -arelent; - -enum complain_overflow -{ - /* Do not complain on overflow. */ - complain_overflow_dont, - - /* Complain if the value overflows when considered as a signed - number one bit larger than the field. ie. A bitfield of N bits - is allowed to represent -2**n to 2**n-1. */ - complain_overflow_bitfield, - - /* Complain if the value overflows when considered as a signed - number. */ - complain_overflow_signed, - - /* Complain if the value overflows when considered as an - unsigned number. */ - complain_overflow_unsigned -}; - -struct reloc_howto_struct -{ - /* The type field has mainly a documentary use - the back end can - do what it wants with it, though normally the back end's - external idea of what a reloc number is stored - in this field. For example, a PC relative word relocation - in a coff environment has the type 023 - because that's - what the outside world calls a R_PCRWORD reloc. */ - unsigned int type; - - /* The value the final relocation is shifted right by. This drops - unwanted data from the relocation. */ - unsigned int rightshift; - - /* The size of the item to be relocated. This is *not* a - power-of-two measure. To get the number of bytes operated - on by a type of relocation, use bfd_get_reloc_size. */ - int size; - - /* The number of bits in the item to be relocated. This is used - when doing overflow checking. */ - unsigned int bitsize; - - /* The relocation is relative to the field being relocated. */ - bfd_boolean pc_relative; - - /* The bit position of the reloc value in the destination. - The relocated value is left shifted by this amount. */ - unsigned int bitpos; - - /* What type of overflow error should be checked for when - relocating. */ - enum complain_overflow complain_on_overflow; - - /* If this field is non null, then the supplied function is - called rather than the normal function. This allows really - strange relocation methods to be accommodated (e.g., i960 callj - instructions). */ - bfd_reloc_status_type (*special_function) - (bfd *, arelent *, struct bfd_symbol *, void *, asection *, - bfd *, char **); - - /* The textual name of the relocation type. */ - char *name; - - /* Some formats record a relocation addend in the section contents - rather than with the relocation. For ELF formats this is the - distinction between USE_REL and USE_RELA (though the code checks - for USE_REL == 1/0). The value of this field is TRUE if the - addend is recorded with the section contents; when performing a - partial link (ld -r) the section contents (the data) will be - modified. The value of this field is FALSE if addends are - recorded with the relocation (in arelent.addend); when performing - a partial link the relocation will be modified. - All relocations for all ELF USE_RELA targets should set this field - to FALSE (values of TRUE should be looked on with suspicion). - However, the converse is not true: not all relocations of all ELF - USE_REL targets set this field to TRUE. Why this is so is peculiar - to each particular target. For relocs that aren't used in partial - links (e.g. GOT stuff) it doesn't matter what this is set to. */ - bfd_boolean partial_inplace; - - /* src_mask selects the part of the instruction (or data) to be used - in the relocation sum. If the target relocations don't have an - addend in the reloc, eg. ELF USE_REL, src_mask will normally equal - dst_mask to extract the addend from the section contents. If - relocations do have an addend in the reloc, eg. ELF USE_RELA, this - field should be zero. Non-zero values for ELF USE_RELA targets are - bogus as in those cases the value in the dst_mask part of the - section contents should be treated as garbage. */ - bfd_vma src_mask; - - /* dst_mask selects which parts of the instruction (or data) are - replaced with a relocated value. */ - bfd_vma dst_mask; - - /* When some formats create PC relative instructions, they leave - the value of the pc of the place being relocated in the offset - slot of the instruction, so that a PC relative relocation can - be made just by adding in an ordinary offset (e.g., sun3 a.out). - Some formats leave the displacement part of an instruction - empty (e.g., m88k bcs); this flag signals the fact. */ - bfd_boolean pcrel_offset; -}; - -#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ - { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } -#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ - HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ - NAME, FALSE, 0, 0, IN) - -#define EMPTY_HOWTO(C) \ - HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ - NULL, FALSE, 0, 0, FALSE) - -#define HOWTO_PREPARE(relocation, symbol) \ - { \ - if (symbol != NULL) \ - { \ - if (bfd_is_com_section (symbol->section)) \ - { \ - relocation = 0; \ - } \ - else \ - { \ - relocation = symbol->value; \ - } \ - } \ - } - -unsigned int bfd_get_reloc_size (reloc_howto_type *); - -typedef struct relent_chain -{ - arelent relent; - struct relent_chain *next; -} -arelent_chain; - -bfd_reloc_status_type bfd_check_overflow - (enum complain_overflow how, - unsigned int bitsize, - unsigned int rightshift, - unsigned int addrsize, - bfd_vma relocation); - -bfd_reloc_status_type bfd_perform_relocation - (bfd *abfd, - arelent *reloc_entry, - void *data, - asection *input_section, - bfd *output_bfd, - char **error_message); - -bfd_reloc_status_type bfd_install_relocation - (bfd *abfd, - arelent *reloc_entry, - void *data, bfd_vma data_start, - asection *input_section, - char **error_message); - -enum bfd_reloc_code_real { - _dummy_first_bfd_reloc_code_real, - - -/* Basic absolute relocations of N bits. */ - BFD_RELOC_64, - BFD_RELOC_32, - BFD_RELOC_26, - BFD_RELOC_24, - BFD_RELOC_16, - BFD_RELOC_14, - BFD_RELOC_8, - -/* PC-relative relocations. Sometimes these are relative to the address -of the relocation itself; sometimes they are relative to the start of -the section containing the relocation. It depends on the specific target. - -The 24-bit relocation is used in some Intel 960 configurations. */ - BFD_RELOC_64_PCREL, - BFD_RELOC_32_PCREL, - BFD_RELOC_24_PCREL, - BFD_RELOC_16_PCREL, - BFD_RELOC_12_PCREL, - BFD_RELOC_8_PCREL, - -/* Section relative relocations. Some targets need this for DWARF2. */ - BFD_RELOC_32_SECREL, - -/* For ELF. */ - BFD_RELOC_32_GOT_PCREL, - BFD_RELOC_16_GOT_PCREL, - BFD_RELOC_8_GOT_PCREL, - BFD_RELOC_32_GOTOFF, - BFD_RELOC_16_GOTOFF, - BFD_RELOC_LO16_GOTOFF, - BFD_RELOC_HI16_GOTOFF, - BFD_RELOC_HI16_S_GOTOFF, - BFD_RELOC_8_GOTOFF, - BFD_RELOC_64_PLT_PCREL, - BFD_RELOC_32_PLT_PCREL, - BFD_RELOC_24_PLT_PCREL, - BFD_RELOC_16_PLT_PCREL, - BFD_RELOC_8_PLT_PCREL, - BFD_RELOC_64_PLTOFF, - BFD_RELOC_32_PLTOFF, - BFD_RELOC_16_PLTOFF, - BFD_RELOC_LO16_PLTOFF, - BFD_RELOC_HI16_PLTOFF, - BFD_RELOC_HI16_S_PLTOFF, - BFD_RELOC_8_PLTOFF, - -/* Relocations used by 68K ELF. */ - BFD_RELOC_68K_GLOB_DAT, - BFD_RELOC_68K_JMP_SLOT, - BFD_RELOC_68K_RELATIVE, - BFD_RELOC_68K_TLS_GD32, - BFD_RELOC_68K_TLS_GD16, - BFD_RELOC_68K_TLS_GD8, - BFD_RELOC_68K_TLS_LDM32, - BFD_RELOC_68K_TLS_LDM16, - BFD_RELOC_68K_TLS_LDM8, - BFD_RELOC_68K_TLS_LDO32, - BFD_RELOC_68K_TLS_LDO16, - BFD_RELOC_68K_TLS_LDO8, - BFD_RELOC_68K_TLS_IE32, - BFD_RELOC_68K_TLS_IE16, - BFD_RELOC_68K_TLS_IE8, - BFD_RELOC_68K_TLS_LE32, - BFD_RELOC_68K_TLS_LE16, - BFD_RELOC_68K_TLS_LE8, - -/* Linkage-table relative. */ - BFD_RELOC_32_BASEREL, - BFD_RELOC_16_BASEREL, - BFD_RELOC_LO16_BASEREL, - BFD_RELOC_HI16_BASEREL, - BFD_RELOC_HI16_S_BASEREL, - BFD_RELOC_8_BASEREL, - BFD_RELOC_RVA, - -/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ - BFD_RELOC_8_FFnn, - -/* These PC-relative relocations are stored as word displacements -- -i.e., byte displacements shifted right two bits. The 30-bit word -displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the -SPARC. (SPARC tools generally refer to this as <>.) The -signed 16-bit displacement is used on the MIPS, and the 23-bit -displacement is used on the Alpha. */ - BFD_RELOC_32_PCREL_S2, - BFD_RELOC_16_PCREL_S2, - BFD_RELOC_23_PCREL_S2, - -/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of -the target word. These are used on the SPARC. */ - BFD_RELOC_HI22, - BFD_RELOC_LO10, - -/* For systems that allocate a Global Pointer register, these are -displacements off that register. These relocation types are -handled specially, because the value the register will have is -decided relatively late. */ - BFD_RELOC_GPREL16, - BFD_RELOC_GPREL32, - -/* Reloc types used for i960/b.out. */ - BFD_RELOC_I960_CALLJ, - -/* SPARC ELF relocations. There is probably some overlap with other -relocation types already defined. */ - BFD_RELOC_NONE, - BFD_RELOC_SPARC_WDISP22, - BFD_RELOC_SPARC22, - BFD_RELOC_SPARC13, - BFD_RELOC_SPARC_GOT10, - BFD_RELOC_SPARC_GOT13, - BFD_RELOC_SPARC_GOT22, - BFD_RELOC_SPARC_PC10, - BFD_RELOC_SPARC_PC22, - BFD_RELOC_SPARC_WPLT30, - BFD_RELOC_SPARC_COPY, - BFD_RELOC_SPARC_GLOB_DAT, - BFD_RELOC_SPARC_JMP_SLOT, - BFD_RELOC_SPARC_RELATIVE, - BFD_RELOC_SPARC_UA16, - BFD_RELOC_SPARC_UA32, - BFD_RELOC_SPARC_UA64, - BFD_RELOC_SPARC_GOTDATA_HIX22, - BFD_RELOC_SPARC_GOTDATA_LOX10, - BFD_RELOC_SPARC_GOTDATA_OP_HIX22, - BFD_RELOC_SPARC_GOTDATA_OP_LOX10, - BFD_RELOC_SPARC_GOTDATA_OP, - BFD_RELOC_SPARC_JMP_IREL, - BFD_RELOC_SPARC_IRELATIVE, - -/* I think these are specific to SPARC a.out (e.g., Sun 4). */ - BFD_RELOC_SPARC_BASE13, - BFD_RELOC_SPARC_BASE22, - -/* SPARC64 relocations */ -#define BFD_RELOC_SPARC_64 BFD_RELOC_64 - BFD_RELOC_SPARC_10, - BFD_RELOC_SPARC_11, - BFD_RELOC_SPARC_OLO10, - BFD_RELOC_SPARC_HH22, - BFD_RELOC_SPARC_HM10, - BFD_RELOC_SPARC_LM22, - BFD_RELOC_SPARC_PC_HH22, - BFD_RELOC_SPARC_PC_HM10, - BFD_RELOC_SPARC_PC_LM22, - BFD_RELOC_SPARC_WDISP16, - BFD_RELOC_SPARC_WDISP19, - BFD_RELOC_SPARC_7, - BFD_RELOC_SPARC_6, - BFD_RELOC_SPARC_5, -#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL - BFD_RELOC_SPARC_PLT32, - BFD_RELOC_SPARC_PLT64, - BFD_RELOC_SPARC_HIX22, - BFD_RELOC_SPARC_LOX10, - BFD_RELOC_SPARC_H44, - BFD_RELOC_SPARC_M44, - BFD_RELOC_SPARC_L44, - BFD_RELOC_SPARC_REGISTER, - -/* SPARC little endian relocation */ - BFD_RELOC_SPARC_REV32, - -/* SPARC TLS relocations */ - BFD_RELOC_SPARC_TLS_GD_HI22, - BFD_RELOC_SPARC_TLS_GD_LO10, - BFD_RELOC_SPARC_TLS_GD_ADD, - BFD_RELOC_SPARC_TLS_GD_CALL, - BFD_RELOC_SPARC_TLS_LDM_HI22, - BFD_RELOC_SPARC_TLS_LDM_LO10, - BFD_RELOC_SPARC_TLS_LDM_ADD, - BFD_RELOC_SPARC_TLS_LDM_CALL, - BFD_RELOC_SPARC_TLS_LDO_HIX22, - BFD_RELOC_SPARC_TLS_LDO_LOX10, - BFD_RELOC_SPARC_TLS_LDO_ADD, - BFD_RELOC_SPARC_TLS_IE_HI22, - BFD_RELOC_SPARC_TLS_IE_LO10, - BFD_RELOC_SPARC_TLS_IE_LD, - BFD_RELOC_SPARC_TLS_IE_LDX, - BFD_RELOC_SPARC_TLS_IE_ADD, - BFD_RELOC_SPARC_TLS_LE_HIX22, - BFD_RELOC_SPARC_TLS_LE_LOX10, - BFD_RELOC_SPARC_TLS_DTPMOD32, - BFD_RELOC_SPARC_TLS_DTPMOD64, - BFD_RELOC_SPARC_TLS_DTPOFF32, - BFD_RELOC_SPARC_TLS_DTPOFF64, - BFD_RELOC_SPARC_TLS_TPOFF32, - BFD_RELOC_SPARC_TLS_TPOFF64, - -/* SPU Relocations. */ - BFD_RELOC_SPU_IMM7, - BFD_RELOC_SPU_IMM8, - BFD_RELOC_SPU_IMM10, - BFD_RELOC_SPU_IMM10W, - BFD_RELOC_SPU_IMM16, - BFD_RELOC_SPU_IMM16W, - BFD_RELOC_SPU_IMM18, - BFD_RELOC_SPU_PCREL9a, - BFD_RELOC_SPU_PCREL9b, - BFD_RELOC_SPU_PCREL16, - BFD_RELOC_SPU_LO16, - BFD_RELOC_SPU_HI16, - BFD_RELOC_SPU_PPU32, - BFD_RELOC_SPU_PPU64, - BFD_RELOC_SPU_ADD_PIC, - -/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or -"addend" in some special way. -For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when -writing; when reading, it will be the absolute section symbol. The -addend is the displacement in bytes of the "lda" instruction from -the "ldah" instruction (which is at the address of this reloc). */ - BFD_RELOC_ALPHA_GPDISP_HI16, - -/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as -with GPDISP_HI16 relocs. The addend is ignored when writing the -relocations out, and is filled in with the file's GP value on -reading, for convenience. */ - BFD_RELOC_ALPHA_GPDISP_LO16, - -/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 -relocation except that there is no accompanying GPDISP_LO16 -relocation. */ - BFD_RELOC_ALPHA_GPDISP, - -/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; -the assembler turns it into a LDQ instruction to load the address of -the symbol, and then fills in a register in the real instruction. - -The LITERAL reloc, at the LDQ instruction, refers to the .lita -section symbol. The addend is ignored when writing, but is filled -in with the file's GP value on reading, for convenience, as with the -GPDISP_LO16 reloc. - -The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. -It should refer to the symbol to be referenced, as with 16_GOTOFF, -but it generates output not based on the position within the .got -section, but relative to the GP value chosen for the file during the -final link stage. - -The LITUSE reloc, on the instruction using the loaded address, gives -information to the linker that it might be able to use to optimize -away some literal section references. The symbol is ignored (read -as the absolute section symbol), and the "addend" indicates the type -of instruction using the register: -1 - "memory" fmt insn -2 - byte-manipulation (byte offset reg) -3 - jsr (target of branch) */ - BFD_RELOC_ALPHA_LITERAL, - BFD_RELOC_ALPHA_ELF_LITERAL, - BFD_RELOC_ALPHA_LITUSE, - -/* The HINT relocation indicates a value that should be filled into the -"hint" field of a jmp/jsr/ret instruction, for possible branch- -prediction logic which may be provided on some processors. */ - BFD_RELOC_ALPHA_HINT, - -/* The LINKAGE relocation outputs a linkage pair in the object file, -which is filled by the linker. */ - BFD_RELOC_ALPHA_LINKAGE, - -/* The CODEADDR relocation outputs a STO_CA in the object file, -which is filled by the linker. */ - BFD_RELOC_ALPHA_CODEADDR, - -/* The GPREL_HI/LO relocations together form a 32-bit offset from the -GP register. */ - BFD_RELOC_ALPHA_GPREL_HI16, - BFD_RELOC_ALPHA_GPREL_LO16, - -/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must -share a common GP, and the target address is adjusted for -STO_ALPHA_STD_GPLOAD. */ - BFD_RELOC_ALPHA_BRSGP, - -/* The NOP relocation outputs a NOP if the longword displacement -between two procedure entry points is < 2^21. */ - BFD_RELOC_ALPHA_NOP, - -/* The BSR relocation outputs a BSR if the longword displacement -between two procedure entry points is < 2^21. */ - BFD_RELOC_ALPHA_BSR, - -/* The LDA relocation outputs a LDA if the longword displacement -between two procedure entry points is < 2^16. */ - BFD_RELOC_ALPHA_LDA, - -/* The BOH relocation outputs a BSR if the longword displacement -between two procedure entry points is < 2^21, or else a hint. */ - BFD_RELOC_ALPHA_BOH, - -/* Alpha thread-local storage relocations. */ - BFD_RELOC_ALPHA_TLSGD, - BFD_RELOC_ALPHA_TLSLDM, - BFD_RELOC_ALPHA_DTPMOD64, - BFD_RELOC_ALPHA_GOTDTPREL16, - BFD_RELOC_ALPHA_DTPREL64, - BFD_RELOC_ALPHA_DTPREL_HI16, - BFD_RELOC_ALPHA_DTPREL_LO16, - BFD_RELOC_ALPHA_DTPREL16, - BFD_RELOC_ALPHA_GOTTPREL16, - BFD_RELOC_ALPHA_TPREL64, - BFD_RELOC_ALPHA_TPREL_HI16, - BFD_RELOC_ALPHA_TPREL_LO16, - BFD_RELOC_ALPHA_TPREL16, - -/* The MIPS jump instruction. */ - BFD_RELOC_MIPS_JMP, - BFD_RELOC_MICROMIPS_JMP, - -/* The MIPS16 jump instruction. */ - BFD_RELOC_MIPS16_JMP, - -/* MIPS16 GP relative reloc. */ - BFD_RELOC_MIPS16_GPREL, - -/* High 16 bits of 32-bit value; simple reloc. */ - BFD_RELOC_HI16, - -/* High 16 bits of 32-bit value but the low 16 bits will be sign -extended and added to form the final result. If the low 16 -bits form a negative number, we need to add one to the high value -to compensate for the borrow when the low bits are added. */ - BFD_RELOC_HI16_S, - -/* Low 16 bits. */ - BFD_RELOC_LO16, - -/* High 16 bits of 32-bit pc-relative value */ - BFD_RELOC_HI16_PCREL, - -/* High 16 bits of 32-bit pc-relative value, adjusted */ - BFD_RELOC_HI16_S_PCREL, - -/* Low 16 bits of pc-relative value */ - BFD_RELOC_LO16_PCREL, - -/* Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of -16-bit immediate fields */ - BFD_RELOC_MIPS16_GOT16, - BFD_RELOC_MIPS16_CALL16, - -/* MIPS16 high 16 bits of 32-bit value. */ - BFD_RELOC_MIPS16_HI16, - -/* MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign -extended and added to form the final result. If the low 16 -bits form a negative number, we need to add one to the high value -to compensate for the borrow when the low bits are added. */ - BFD_RELOC_MIPS16_HI16_S, - -/* MIPS16 low 16 bits. */ - BFD_RELOC_MIPS16_LO16, - -/* Relocation against a MIPS literal section. */ - BFD_RELOC_MIPS_LITERAL, - BFD_RELOC_MICROMIPS_LITERAL, - -/* microMIPS PC-relative relocations. */ - BFD_RELOC_MICROMIPS_7_PCREL_S1, - BFD_RELOC_MICROMIPS_10_PCREL_S1, - BFD_RELOC_MICROMIPS_16_PCREL_S1, - -/* microMIPS versions of generic BFD relocs. */ - BFD_RELOC_MICROMIPS_GPREL16, - BFD_RELOC_MICROMIPS_HI16, - BFD_RELOC_MICROMIPS_HI16_S, - BFD_RELOC_MICROMIPS_LO16, - -/* MIPS ELF relocations. */ - BFD_RELOC_MIPS_GOT16, - BFD_RELOC_MICROMIPS_GOT16, - BFD_RELOC_MIPS_CALL16, - BFD_RELOC_MICROMIPS_CALL16, - BFD_RELOC_MIPS_GOT_HI16, - BFD_RELOC_MICROMIPS_GOT_HI16, - BFD_RELOC_MIPS_GOT_LO16, - BFD_RELOC_MICROMIPS_GOT_LO16, - BFD_RELOC_MIPS_CALL_HI16, - BFD_RELOC_MICROMIPS_CALL_HI16, - BFD_RELOC_MIPS_CALL_LO16, - BFD_RELOC_MICROMIPS_CALL_LO16, - BFD_RELOC_MIPS_SUB, - BFD_RELOC_MICROMIPS_SUB, - BFD_RELOC_MIPS_GOT_PAGE, - BFD_RELOC_MICROMIPS_GOT_PAGE, - BFD_RELOC_MIPS_GOT_OFST, - BFD_RELOC_MICROMIPS_GOT_OFST, - BFD_RELOC_MIPS_GOT_DISP, - BFD_RELOC_MICROMIPS_GOT_DISP, - BFD_RELOC_MIPS_SHIFT5, - BFD_RELOC_MIPS_SHIFT6, - BFD_RELOC_MIPS_INSERT_A, - BFD_RELOC_MIPS_INSERT_B, - BFD_RELOC_MIPS_DELETE, - BFD_RELOC_MIPS_HIGHEST, - BFD_RELOC_MICROMIPS_HIGHEST, - BFD_RELOC_MIPS_HIGHER, - BFD_RELOC_MICROMIPS_HIGHER, - BFD_RELOC_MIPS_SCN_DISP, - BFD_RELOC_MICROMIPS_SCN_DISP, - BFD_RELOC_MIPS_REL16, - BFD_RELOC_MIPS_RELGOT, - BFD_RELOC_MIPS_JALR, - BFD_RELOC_MICROMIPS_JALR, - BFD_RELOC_MIPS_TLS_DTPMOD32, - BFD_RELOC_MIPS_TLS_DTPREL32, - BFD_RELOC_MIPS_TLS_DTPMOD64, - BFD_RELOC_MIPS_TLS_DTPREL64, - BFD_RELOC_MIPS_TLS_GD, - BFD_RELOC_MICROMIPS_TLS_GD, - BFD_RELOC_MIPS_TLS_LDM, - BFD_RELOC_MICROMIPS_TLS_LDM, - BFD_RELOC_MIPS_TLS_DTPREL_HI16, - BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16, - BFD_RELOC_MIPS_TLS_DTPREL_LO16, - BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16, - BFD_RELOC_MIPS_TLS_GOTTPREL, - BFD_RELOC_MICROMIPS_TLS_GOTTPREL, - BFD_RELOC_MIPS_TLS_TPREL32, - BFD_RELOC_MIPS_TLS_TPREL64, - BFD_RELOC_MIPS_TLS_TPREL_HI16, - BFD_RELOC_MICROMIPS_TLS_TPREL_HI16, - BFD_RELOC_MIPS_TLS_TPREL_LO16, - BFD_RELOC_MICROMIPS_TLS_TPREL_LO16, - - -/* MIPS ELF relocations (VxWorks and PLT extensions). */ - BFD_RELOC_MIPS_COPY, - BFD_RELOC_MIPS_JUMP_SLOT, - - -/* Moxie ELF relocations. */ - BFD_RELOC_MOXIE_10_PCREL, - - -/* Fujitsu Frv Relocations. */ - BFD_RELOC_FRV_LABEL16, - BFD_RELOC_FRV_LABEL24, - BFD_RELOC_FRV_LO16, - BFD_RELOC_FRV_HI16, - BFD_RELOC_FRV_GPREL12, - BFD_RELOC_FRV_GPRELU12, - BFD_RELOC_FRV_GPREL32, - BFD_RELOC_FRV_GPRELHI, - BFD_RELOC_FRV_GPRELLO, - BFD_RELOC_FRV_GOT12, - BFD_RELOC_FRV_GOTHI, - BFD_RELOC_FRV_GOTLO, - BFD_RELOC_FRV_FUNCDESC, - BFD_RELOC_FRV_FUNCDESC_GOT12, - BFD_RELOC_FRV_FUNCDESC_GOTHI, - BFD_RELOC_FRV_FUNCDESC_GOTLO, - BFD_RELOC_FRV_FUNCDESC_VALUE, - BFD_RELOC_FRV_FUNCDESC_GOTOFF12, - BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, - BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, - BFD_RELOC_FRV_GOTOFF12, - BFD_RELOC_FRV_GOTOFFHI, - BFD_RELOC_FRV_GOTOFFLO, - BFD_RELOC_FRV_GETTLSOFF, - BFD_RELOC_FRV_TLSDESC_VALUE, - BFD_RELOC_FRV_GOTTLSDESC12, - BFD_RELOC_FRV_GOTTLSDESCHI, - BFD_RELOC_FRV_GOTTLSDESCLO, - BFD_RELOC_FRV_TLSMOFF12, - BFD_RELOC_FRV_TLSMOFFHI, - BFD_RELOC_FRV_TLSMOFFLO, - BFD_RELOC_FRV_GOTTLSOFF12, - BFD_RELOC_FRV_GOTTLSOFFHI, - BFD_RELOC_FRV_GOTTLSOFFLO, - BFD_RELOC_FRV_TLSOFF, - BFD_RELOC_FRV_TLSDESC_RELAX, - BFD_RELOC_FRV_GETTLSOFF_RELAX, - BFD_RELOC_FRV_TLSOFF_RELAX, - BFD_RELOC_FRV_TLSMOFF, - - -/* This is a 24bit GOT-relative reloc for the mn10300. */ - BFD_RELOC_MN10300_GOTOFF24, - -/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes -in the instruction. */ - BFD_RELOC_MN10300_GOT32, - -/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes -in the instruction. */ - BFD_RELOC_MN10300_GOT24, - -/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes -in the instruction. */ - BFD_RELOC_MN10300_GOT16, - -/* Copy symbol at runtime. */ - BFD_RELOC_MN10300_COPY, - -/* Create GOT entry. */ - BFD_RELOC_MN10300_GLOB_DAT, - -/* Create PLT entry. */ - BFD_RELOC_MN10300_JMP_SLOT, - -/* Adjust by program base. */ - BFD_RELOC_MN10300_RELATIVE, - -/* Together with another reloc targeted at the same location, -allows for a value that is the difference of two symbols -in the same section. */ - BFD_RELOC_MN10300_SYM_DIFF, - -/* The addend of this reloc is an alignment power that must -be honoured at the offset's location, regardless of linker -relaxation. */ - BFD_RELOC_MN10300_ALIGN, - - -/* i386/elf relocations */ - BFD_RELOC_386_GOT32, - BFD_RELOC_386_PLT32, - BFD_RELOC_386_COPY, - BFD_RELOC_386_GLOB_DAT, - BFD_RELOC_386_JUMP_SLOT, - BFD_RELOC_386_RELATIVE, - BFD_RELOC_386_GOTOFF, - BFD_RELOC_386_GOTPC, - BFD_RELOC_386_TLS_TPOFF, - BFD_RELOC_386_TLS_IE, - BFD_RELOC_386_TLS_GOTIE, - BFD_RELOC_386_TLS_LE, - BFD_RELOC_386_TLS_GD, - BFD_RELOC_386_TLS_LDM, - BFD_RELOC_386_TLS_LDO_32, - BFD_RELOC_386_TLS_IE_32, - BFD_RELOC_386_TLS_LE_32, - BFD_RELOC_386_TLS_DTPMOD32, - BFD_RELOC_386_TLS_DTPOFF32, - BFD_RELOC_386_TLS_TPOFF32, - BFD_RELOC_386_TLS_GOTDESC, - BFD_RELOC_386_TLS_DESC_CALL, - BFD_RELOC_386_TLS_DESC, - BFD_RELOC_386_IRELATIVE, - -/* x86-64/elf relocations */ - BFD_RELOC_X86_64_GOT32, - BFD_RELOC_X86_64_PLT32, - BFD_RELOC_X86_64_COPY, - BFD_RELOC_X86_64_GLOB_DAT, - BFD_RELOC_X86_64_JUMP_SLOT, - BFD_RELOC_X86_64_RELATIVE, - BFD_RELOC_X86_64_GOTPCREL, - BFD_RELOC_X86_64_32S, - BFD_RELOC_X86_64_DTPMOD64, - BFD_RELOC_X86_64_DTPOFF64, - BFD_RELOC_X86_64_TPOFF64, - BFD_RELOC_X86_64_TLSGD, - BFD_RELOC_X86_64_TLSLD, - BFD_RELOC_X86_64_DTPOFF32, - BFD_RELOC_X86_64_GOTTPOFF, - BFD_RELOC_X86_64_TPOFF32, - BFD_RELOC_X86_64_GOTOFF64, - BFD_RELOC_X86_64_GOTPC32, - BFD_RELOC_X86_64_GOT64, - BFD_RELOC_X86_64_GOTPCREL64, - BFD_RELOC_X86_64_GOTPC64, - BFD_RELOC_X86_64_GOTPLT64, - BFD_RELOC_X86_64_PLTOFF64, - BFD_RELOC_X86_64_GOTPC32_TLSDESC, - BFD_RELOC_X86_64_TLSDESC_CALL, - BFD_RELOC_X86_64_TLSDESC, - BFD_RELOC_X86_64_IRELATIVE, - -/* ns32k relocations */ - BFD_RELOC_NS32K_IMM_8, - BFD_RELOC_NS32K_IMM_16, - BFD_RELOC_NS32K_IMM_32, - BFD_RELOC_NS32K_IMM_8_PCREL, - BFD_RELOC_NS32K_IMM_16_PCREL, - BFD_RELOC_NS32K_IMM_32_PCREL, - BFD_RELOC_NS32K_DISP_8, - BFD_RELOC_NS32K_DISP_16, - BFD_RELOC_NS32K_DISP_32, - BFD_RELOC_NS32K_DISP_8_PCREL, - BFD_RELOC_NS32K_DISP_16_PCREL, - BFD_RELOC_NS32K_DISP_32_PCREL, - -/* PDP11 relocations */ - BFD_RELOC_PDP11_DISP_8_PCREL, - BFD_RELOC_PDP11_DISP_6_PCREL, - -/* Picojava relocs. Not all of these appear in object files. */ - BFD_RELOC_PJ_CODE_HI16, - BFD_RELOC_PJ_CODE_LO16, - BFD_RELOC_PJ_CODE_DIR16, - BFD_RELOC_PJ_CODE_DIR32, - BFD_RELOC_PJ_CODE_REL16, - BFD_RELOC_PJ_CODE_REL32, - -/* Power(rs6000) and PowerPC relocations. */ - BFD_RELOC_PPC_B26, - BFD_RELOC_PPC_BA26, - BFD_RELOC_PPC_TOC16, - BFD_RELOC_PPC_B16, - BFD_RELOC_PPC_B16_BRTAKEN, - BFD_RELOC_PPC_B16_BRNTAKEN, - BFD_RELOC_PPC_BA16, - BFD_RELOC_PPC_BA16_BRTAKEN, - BFD_RELOC_PPC_BA16_BRNTAKEN, - BFD_RELOC_PPC_COPY, - BFD_RELOC_PPC_GLOB_DAT, - BFD_RELOC_PPC_JMP_SLOT, - BFD_RELOC_PPC_RELATIVE, - BFD_RELOC_PPC_LOCAL24PC, - BFD_RELOC_PPC_EMB_NADDR32, - BFD_RELOC_PPC_EMB_NADDR16, - BFD_RELOC_PPC_EMB_NADDR16_LO, - BFD_RELOC_PPC_EMB_NADDR16_HI, - BFD_RELOC_PPC_EMB_NADDR16_HA, - BFD_RELOC_PPC_EMB_SDAI16, - BFD_RELOC_PPC_EMB_SDA2I16, - BFD_RELOC_PPC_EMB_SDA2REL, - BFD_RELOC_PPC_EMB_SDA21, - BFD_RELOC_PPC_EMB_MRKREF, - BFD_RELOC_PPC_EMB_RELSEC16, - BFD_RELOC_PPC_EMB_RELST_LO, - BFD_RELOC_PPC_EMB_RELST_HI, - BFD_RELOC_PPC_EMB_RELST_HA, - BFD_RELOC_PPC_EMB_BIT_FLD, - BFD_RELOC_PPC_EMB_RELSDA, - BFD_RELOC_PPC64_HIGHER, - BFD_RELOC_PPC64_HIGHER_S, - BFD_RELOC_PPC64_HIGHEST, - BFD_RELOC_PPC64_HIGHEST_S, - BFD_RELOC_PPC64_TOC16_LO, - BFD_RELOC_PPC64_TOC16_HI, - BFD_RELOC_PPC64_TOC16_HA, - BFD_RELOC_PPC64_TOC, - BFD_RELOC_PPC64_PLTGOT16, - BFD_RELOC_PPC64_PLTGOT16_LO, - BFD_RELOC_PPC64_PLTGOT16_HI, - BFD_RELOC_PPC64_PLTGOT16_HA, - BFD_RELOC_PPC64_ADDR16_DS, - BFD_RELOC_PPC64_ADDR16_LO_DS, - BFD_RELOC_PPC64_GOT16_DS, - BFD_RELOC_PPC64_GOT16_LO_DS, - BFD_RELOC_PPC64_PLT16_LO_DS, - BFD_RELOC_PPC64_SECTOFF_DS, - BFD_RELOC_PPC64_SECTOFF_LO_DS, - BFD_RELOC_PPC64_TOC16_DS, - BFD_RELOC_PPC64_TOC16_LO_DS, - BFD_RELOC_PPC64_PLTGOT16_DS, - BFD_RELOC_PPC64_PLTGOT16_LO_DS, - -/* PowerPC and PowerPC64 thread-local storage relocations. */ - BFD_RELOC_PPC_TLS, - BFD_RELOC_PPC_TLSGD, - BFD_RELOC_PPC_TLSLD, - BFD_RELOC_PPC_DTPMOD, - BFD_RELOC_PPC_TPREL16, - BFD_RELOC_PPC_TPREL16_LO, - BFD_RELOC_PPC_TPREL16_HI, - BFD_RELOC_PPC_TPREL16_HA, - BFD_RELOC_PPC_TPREL, - BFD_RELOC_PPC_DTPREL16, - BFD_RELOC_PPC_DTPREL16_LO, - BFD_RELOC_PPC_DTPREL16_HI, - BFD_RELOC_PPC_DTPREL16_HA, - BFD_RELOC_PPC_DTPREL, - BFD_RELOC_PPC_GOT_TLSGD16, - BFD_RELOC_PPC_GOT_TLSGD16_LO, - BFD_RELOC_PPC_GOT_TLSGD16_HI, - BFD_RELOC_PPC_GOT_TLSGD16_HA, - BFD_RELOC_PPC_GOT_TLSLD16, - BFD_RELOC_PPC_GOT_TLSLD16_LO, - BFD_RELOC_PPC_GOT_TLSLD16_HI, - BFD_RELOC_PPC_GOT_TLSLD16_HA, - BFD_RELOC_PPC_GOT_TPREL16, - BFD_RELOC_PPC_GOT_TPREL16_LO, - BFD_RELOC_PPC_GOT_TPREL16_HI, - BFD_RELOC_PPC_GOT_TPREL16_HA, - BFD_RELOC_PPC_GOT_DTPREL16, - BFD_RELOC_PPC_GOT_DTPREL16_LO, - BFD_RELOC_PPC_GOT_DTPREL16_HI, - BFD_RELOC_PPC_GOT_DTPREL16_HA, - BFD_RELOC_PPC64_TPREL16_DS, - BFD_RELOC_PPC64_TPREL16_LO_DS, - BFD_RELOC_PPC64_TPREL16_HIGHER, - BFD_RELOC_PPC64_TPREL16_HIGHERA, - BFD_RELOC_PPC64_TPREL16_HIGHEST, - BFD_RELOC_PPC64_TPREL16_HIGHESTA, - BFD_RELOC_PPC64_DTPREL16_DS, - BFD_RELOC_PPC64_DTPREL16_LO_DS, - BFD_RELOC_PPC64_DTPREL16_HIGHER, - BFD_RELOC_PPC64_DTPREL16_HIGHERA, - BFD_RELOC_PPC64_DTPREL16_HIGHEST, - BFD_RELOC_PPC64_DTPREL16_HIGHESTA, - -/* IBM 370/390 relocations */ - BFD_RELOC_I370_D12, - -/* The type of reloc used to build a constructor table - at the moment -probably a 32 bit wide absolute relocation, but the target can choose. -It generally does map to one of the other relocation types. */ - BFD_RELOC_CTOR, - -/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are -not stored in the instruction. */ - BFD_RELOC_ARM_PCREL_BRANCH, - -/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is -not stored in the instruction. The 2nd lowest bit comes from a 1 bit -field in the instruction. */ - BFD_RELOC_ARM_PCREL_BLX, - -/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is -not stored in the instruction. The 2nd lowest bit comes from a 1 bit -field in the instruction. */ - BFD_RELOC_THUMB_PCREL_BLX, - -/* ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. */ - BFD_RELOC_ARM_PCREL_CALL, - -/* ARM 26-bit pc-relative branch for B or conditional BL instruction. */ - BFD_RELOC_ARM_PCREL_JUMP, - -/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. -The lowest bit must be zero and is not stored in the instruction. -Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an -"nn" one smaller in all cases. Note further that BRANCH23 -corresponds to R_ARM_THM_CALL. */ - BFD_RELOC_THUMB_PCREL_BRANCH7, - BFD_RELOC_THUMB_PCREL_BRANCH9, - BFD_RELOC_THUMB_PCREL_BRANCH12, - BFD_RELOC_THUMB_PCREL_BRANCH20, - BFD_RELOC_THUMB_PCREL_BRANCH23, - BFD_RELOC_THUMB_PCREL_BRANCH25, - -/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */ - BFD_RELOC_ARM_OFFSET_IMM, - -/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */ - BFD_RELOC_ARM_THUMB_OFFSET, - -/* Pc-relative or absolute relocation depending on target. Used for -entries in .init_array sections. */ - BFD_RELOC_ARM_TARGET1, - -/* Read-only segment base relative address. */ - BFD_RELOC_ARM_ROSEGREL32, - -/* Data segment base relative address. */ - BFD_RELOC_ARM_SBREL32, - -/* This reloc is used for references to RTTI data from exception handling -tables. The actual definition depends on the target. It may be a -pc-relative or some form of GOT-indirect relocation. */ - BFD_RELOC_ARM_TARGET2, - -/* 31-bit PC relative address. */ - BFD_RELOC_ARM_PREL31, - -/* Low and High halfword relocations for MOVW and MOVT instructions. */ - BFD_RELOC_ARM_MOVW, - BFD_RELOC_ARM_MOVT, - BFD_RELOC_ARM_MOVW_PCREL, - BFD_RELOC_ARM_MOVT_PCREL, - BFD_RELOC_ARM_THUMB_MOVW, - BFD_RELOC_ARM_THUMB_MOVT, - BFD_RELOC_ARM_THUMB_MOVW_PCREL, - BFD_RELOC_ARM_THUMB_MOVT_PCREL, - -/* Relocations for setting up GOTs and PLTs for shared libraries. */ - BFD_RELOC_ARM_JUMP_SLOT, - BFD_RELOC_ARM_GLOB_DAT, - BFD_RELOC_ARM_GOT32, - BFD_RELOC_ARM_PLT32, - BFD_RELOC_ARM_RELATIVE, - BFD_RELOC_ARM_GOTOFF, - BFD_RELOC_ARM_GOTPC, - BFD_RELOC_ARM_GOT_PREL, - -/* ARM thread-local storage relocations. */ - BFD_RELOC_ARM_TLS_GD32, - BFD_RELOC_ARM_TLS_LDO32, - BFD_RELOC_ARM_TLS_LDM32, - BFD_RELOC_ARM_TLS_DTPOFF32, - BFD_RELOC_ARM_TLS_DTPMOD32, - BFD_RELOC_ARM_TLS_TPOFF32, - BFD_RELOC_ARM_TLS_IE32, - BFD_RELOC_ARM_TLS_LE32, - BFD_RELOC_ARM_TLS_GOTDESC, - BFD_RELOC_ARM_TLS_CALL, - BFD_RELOC_ARM_THM_TLS_CALL, - BFD_RELOC_ARM_TLS_DESCSEQ, - BFD_RELOC_ARM_THM_TLS_DESCSEQ, - BFD_RELOC_ARM_TLS_DESC, - -/* ARM group relocations. */ - BFD_RELOC_ARM_ALU_PC_G0_NC, - BFD_RELOC_ARM_ALU_PC_G0, - BFD_RELOC_ARM_ALU_PC_G1_NC, - BFD_RELOC_ARM_ALU_PC_G1, - BFD_RELOC_ARM_ALU_PC_G2, - BFD_RELOC_ARM_LDR_PC_G0, - BFD_RELOC_ARM_LDR_PC_G1, - BFD_RELOC_ARM_LDR_PC_G2, - BFD_RELOC_ARM_LDRS_PC_G0, - BFD_RELOC_ARM_LDRS_PC_G1, - BFD_RELOC_ARM_LDRS_PC_G2, - BFD_RELOC_ARM_LDC_PC_G0, - BFD_RELOC_ARM_LDC_PC_G1, - BFD_RELOC_ARM_LDC_PC_G2, - BFD_RELOC_ARM_ALU_SB_G0_NC, - BFD_RELOC_ARM_ALU_SB_G0, - BFD_RELOC_ARM_ALU_SB_G1_NC, - BFD_RELOC_ARM_ALU_SB_G1, - BFD_RELOC_ARM_ALU_SB_G2, - BFD_RELOC_ARM_LDR_SB_G0, - BFD_RELOC_ARM_LDR_SB_G1, - BFD_RELOC_ARM_LDR_SB_G2, - BFD_RELOC_ARM_LDRS_SB_G0, - BFD_RELOC_ARM_LDRS_SB_G1, - BFD_RELOC_ARM_LDRS_SB_G2, - BFD_RELOC_ARM_LDC_SB_G0, - BFD_RELOC_ARM_LDC_SB_G1, - BFD_RELOC_ARM_LDC_SB_G2, - -/* Annotation of BX instructions. */ - BFD_RELOC_ARM_V4BX, - -/* ARM support for STT_GNU_IFUNC. */ - BFD_RELOC_ARM_IRELATIVE, - -/* These relocs are only used within the ARM assembler. They are not -(at present) written to any object files. */ - BFD_RELOC_ARM_IMMEDIATE, - BFD_RELOC_ARM_ADRL_IMMEDIATE, - BFD_RELOC_ARM_T32_IMMEDIATE, - BFD_RELOC_ARM_T32_ADD_IMM, - BFD_RELOC_ARM_T32_IMM12, - BFD_RELOC_ARM_T32_ADD_PC12, - BFD_RELOC_ARM_SHIFT_IMM, - BFD_RELOC_ARM_SMC, - BFD_RELOC_ARM_HVC, - BFD_RELOC_ARM_SWI, - BFD_RELOC_ARM_MULTI, - BFD_RELOC_ARM_CP_OFF_IMM, - BFD_RELOC_ARM_CP_OFF_IMM_S2, - BFD_RELOC_ARM_T32_CP_OFF_IMM, - BFD_RELOC_ARM_T32_CP_OFF_IMM_S2, - BFD_RELOC_ARM_ADR_IMM, - BFD_RELOC_ARM_LDR_IMM, - BFD_RELOC_ARM_LITERAL, - BFD_RELOC_ARM_IN_POOL, - BFD_RELOC_ARM_OFFSET_IMM8, - BFD_RELOC_ARM_T32_OFFSET_U8, - BFD_RELOC_ARM_T32_OFFSET_IMM, - BFD_RELOC_ARM_HWLITERAL, - BFD_RELOC_ARM_THUMB_ADD, - BFD_RELOC_ARM_THUMB_IMM, - BFD_RELOC_ARM_THUMB_SHIFT, - -/* Renesas / SuperH SH relocs. Not all of these appear in object files. */ - BFD_RELOC_SH_PCDISP8BY2, - BFD_RELOC_SH_PCDISP12BY2, - BFD_RELOC_SH_IMM3, - BFD_RELOC_SH_IMM3U, - BFD_RELOC_SH_DISP12, - BFD_RELOC_SH_DISP12BY2, - BFD_RELOC_SH_DISP12BY4, - BFD_RELOC_SH_DISP12BY8, - BFD_RELOC_SH_DISP20, - BFD_RELOC_SH_DISP20BY8, - BFD_RELOC_SH_IMM4, - BFD_RELOC_SH_IMM4BY2, - BFD_RELOC_SH_IMM4BY4, - BFD_RELOC_SH_IMM8, - BFD_RELOC_SH_IMM8BY2, - BFD_RELOC_SH_IMM8BY4, - BFD_RELOC_SH_PCRELIMM8BY2, - BFD_RELOC_SH_PCRELIMM8BY4, - BFD_RELOC_SH_SWITCH16, - BFD_RELOC_SH_SWITCH32, - BFD_RELOC_SH_USES, - BFD_RELOC_SH_COUNT, - BFD_RELOC_SH_ALIGN, - BFD_RELOC_SH_CODE, - BFD_RELOC_SH_DATA, - BFD_RELOC_SH_LABEL, - BFD_RELOC_SH_LOOP_START, - BFD_RELOC_SH_LOOP_END, - BFD_RELOC_SH_COPY, - BFD_RELOC_SH_GLOB_DAT, - BFD_RELOC_SH_JMP_SLOT, - BFD_RELOC_SH_RELATIVE, - BFD_RELOC_SH_GOTPC, - BFD_RELOC_SH_GOT_LOW16, - BFD_RELOC_SH_GOT_MEDLOW16, - BFD_RELOC_SH_GOT_MEDHI16, - BFD_RELOC_SH_GOT_HI16, - BFD_RELOC_SH_GOTPLT_LOW16, - BFD_RELOC_SH_GOTPLT_MEDLOW16, - BFD_RELOC_SH_GOTPLT_MEDHI16, - BFD_RELOC_SH_GOTPLT_HI16, - BFD_RELOC_SH_PLT_LOW16, - BFD_RELOC_SH_PLT_MEDLOW16, - BFD_RELOC_SH_PLT_MEDHI16, - BFD_RELOC_SH_PLT_HI16, - BFD_RELOC_SH_GOTOFF_LOW16, - BFD_RELOC_SH_GOTOFF_MEDLOW16, - BFD_RELOC_SH_GOTOFF_MEDHI16, - BFD_RELOC_SH_GOTOFF_HI16, - BFD_RELOC_SH_GOTPC_LOW16, - BFD_RELOC_SH_GOTPC_MEDLOW16, - BFD_RELOC_SH_GOTPC_MEDHI16, - BFD_RELOC_SH_GOTPC_HI16, - BFD_RELOC_SH_COPY64, - BFD_RELOC_SH_GLOB_DAT64, - BFD_RELOC_SH_JMP_SLOT64, - BFD_RELOC_SH_RELATIVE64, - BFD_RELOC_SH_GOT10BY4, - BFD_RELOC_SH_GOT10BY8, - BFD_RELOC_SH_GOTPLT10BY4, - BFD_RELOC_SH_GOTPLT10BY8, - BFD_RELOC_SH_GOTPLT32, - BFD_RELOC_SH_SHMEDIA_CODE, - BFD_RELOC_SH_IMMU5, - BFD_RELOC_SH_IMMS6, - BFD_RELOC_SH_IMMS6BY32, - BFD_RELOC_SH_IMMU6, - BFD_RELOC_SH_IMMS10, - BFD_RELOC_SH_IMMS10BY2, - BFD_RELOC_SH_IMMS10BY4, - BFD_RELOC_SH_IMMS10BY8, - BFD_RELOC_SH_IMMS16, - BFD_RELOC_SH_IMMU16, - BFD_RELOC_SH_IMM_LOW16, - BFD_RELOC_SH_IMM_LOW16_PCREL, - BFD_RELOC_SH_IMM_MEDLOW16, - BFD_RELOC_SH_IMM_MEDLOW16_PCREL, - BFD_RELOC_SH_IMM_MEDHI16, - BFD_RELOC_SH_IMM_MEDHI16_PCREL, - BFD_RELOC_SH_IMM_HI16, - BFD_RELOC_SH_IMM_HI16_PCREL, - BFD_RELOC_SH_PT_16, - BFD_RELOC_SH_TLS_GD_32, - BFD_RELOC_SH_TLS_LD_32, - BFD_RELOC_SH_TLS_LDO_32, - BFD_RELOC_SH_TLS_IE_32, - BFD_RELOC_SH_TLS_LE_32, - BFD_RELOC_SH_TLS_DTPMOD32, - BFD_RELOC_SH_TLS_DTPOFF32, - BFD_RELOC_SH_TLS_TPOFF32, - BFD_RELOC_SH_GOT20, - BFD_RELOC_SH_GOTOFF20, - BFD_RELOC_SH_GOTFUNCDESC, - BFD_RELOC_SH_GOTFUNCDESC20, - BFD_RELOC_SH_GOTOFFFUNCDESC, - BFD_RELOC_SH_GOTOFFFUNCDESC20, - BFD_RELOC_SH_FUNCDESC, - -/* ARC Cores relocs. -ARC 22 bit pc-relative branch. The lowest two bits must be zero and are -not stored in the instruction. The high 20 bits are installed in bits 26 -through 7 of the instruction. */ - BFD_RELOC_ARC_B22_PCREL, - -/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not -stored in the instruction. The high 24 bits are installed in bits 23 -through 0. */ - BFD_RELOC_ARC_B26, - -/* ADI Blackfin 16 bit immediate absolute reloc. */ - BFD_RELOC_BFIN_16_IMM, - -/* ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. */ - BFD_RELOC_BFIN_16_HIGH, - -/* ADI Blackfin 'a' part of LSETUP. */ - BFD_RELOC_BFIN_4_PCREL, - -/* ADI Blackfin. */ - BFD_RELOC_BFIN_5_PCREL, - -/* ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. */ - BFD_RELOC_BFIN_16_LOW, - -/* ADI Blackfin. */ - BFD_RELOC_BFIN_10_PCREL, - -/* ADI Blackfin 'b' part of LSETUP. */ - BFD_RELOC_BFIN_11_PCREL, - -/* ADI Blackfin. */ - BFD_RELOC_BFIN_12_PCREL_JUMP, - -/* ADI Blackfin Short jump, pcrel. */ - BFD_RELOC_BFIN_12_PCREL_JUMP_S, - -/* ADI Blackfin Call.x not implemented. */ - BFD_RELOC_BFIN_24_PCREL_CALL_X, - -/* ADI Blackfin Long Jump pcrel. */ - BFD_RELOC_BFIN_24_PCREL_JUMP_L, - -/* ADI Blackfin FD-PIC relocations. */ - BFD_RELOC_BFIN_GOT17M4, - BFD_RELOC_BFIN_GOTHI, - BFD_RELOC_BFIN_GOTLO, - BFD_RELOC_BFIN_FUNCDESC, - BFD_RELOC_BFIN_FUNCDESC_GOT17M4, - BFD_RELOC_BFIN_FUNCDESC_GOTHI, - BFD_RELOC_BFIN_FUNCDESC_GOTLO, - BFD_RELOC_BFIN_FUNCDESC_VALUE, - BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4, - BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI, - BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO, - BFD_RELOC_BFIN_GOTOFF17M4, - BFD_RELOC_BFIN_GOTOFFHI, - BFD_RELOC_BFIN_GOTOFFLO, - -/* ADI Blackfin GOT relocation. */ - BFD_RELOC_BFIN_GOT, - -/* ADI Blackfin PLTPC relocation. */ - BFD_RELOC_BFIN_PLTPC, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_PUSH, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_CONST, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_ADD, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_SUB, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_MULT, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_DIV, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_MOD, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_LSHIFT, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_RSHIFT, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_AND, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_OR, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_XOR, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_LAND, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_LOR, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_LEN, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_NEG, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_COMP, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_PAGE, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_HWPAGE, - -/* ADI Blackfin arithmetic relocation. */ - BFD_ARELOC_BFIN_ADDR, - -/* Mitsubishi D10V relocs. -This is a 10-bit reloc with the right 2 bits -assumed to be 0. */ - BFD_RELOC_D10V_10_PCREL_R, - -/* Mitsubishi D10V relocs. -This is a 10-bit reloc with the right 2 bits -assumed to be 0. This is the same as the previous reloc -except it is in the left container, i.e., -shifted left 15 bits. */ - BFD_RELOC_D10V_10_PCREL_L, - -/* This is an 18-bit reloc with the right 2 bits -assumed to be 0. */ - BFD_RELOC_D10V_18, - -/* This is an 18-bit reloc with the right 2 bits -assumed to be 0. */ - BFD_RELOC_D10V_18_PCREL, - -/* Mitsubishi D30V relocs. -This is a 6-bit absolute reloc. */ - BFD_RELOC_D30V_6, - -/* This is a 6-bit pc-relative reloc with -the right 3 bits assumed to be 0. */ - BFD_RELOC_D30V_9_PCREL, - -/* This is a 6-bit pc-relative reloc with -the right 3 bits assumed to be 0. Same -as the previous reloc but on the right side -of the container. */ - BFD_RELOC_D30V_9_PCREL_R, - -/* This is a 12-bit absolute reloc with the -right 3 bitsassumed to be 0. */ - BFD_RELOC_D30V_15, - -/* This is a 12-bit pc-relative reloc with -the right 3 bits assumed to be 0. */ - BFD_RELOC_D30V_15_PCREL, - -/* This is a 12-bit pc-relative reloc with -the right 3 bits assumed to be 0. Same -as the previous reloc but on the right side -of the container. */ - BFD_RELOC_D30V_15_PCREL_R, - -/* This is an 18-bit absolute reloc with -the right 3 bits assumed to be 0. */ - BFD_RELOC_D30V_21, - -/* This is an 18-bit pc-relative reloc with -the right 3 bits assumed to be 0. */ - BFD_RELOC_D30V_21_PCREL, - -/* This is an 18-bit pc-relative reloc with -the right 3 bits assumed to be 0. Same -as the previous reloc but on the right side -of the container. */ - BFD_RELOC_D30V_21_PCREL_R, - -/* This is a 32-bit absolute reloc. */ - BFD_RELOC_D30V_32, - -/* This is a 32-bit pc-relative reloc. */ - BFD_RELOC_D30V_32_PCREL, - -/* DLX relocs */ - BFD_RELOC_DLX_HI16_S, - -/* DLX relocs */ - BFD_RELOC_DLX_LO16, - -/* DLX relocs */ - BFD_RELOC_DLX_JMP26, - -/* Renesas M16C/M32C Relocations. */ - BFD_RELOC_M32C_HI8, - BFD_RELOC_M32C_RL_JUMP, - BFD_RELOC_M32C_RL_1ADDR, - BFD_RELOC_M32C_RL_2ADDR, - -/* Renesas M32R (formerly Mitsubishi M32R) relocs. -This is a 24 bit absolute address. */ - BFD_RELOC_M32R_24, - -/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */ - BFD_RELOC_M32R_10_PCREL, - -/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */ - BFD_RELOC_M32R_18_PCREL, - -/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */ - BFD_RELOC_M32R_26_PCREL, - -/* This is a 16-bit reloc containing the high 16 bits of an address -used when the lower 16 bits are treated as unsigned. */ - BFD_RELOC_M32R_HI16_ULO, - -/* This is a 16-bit reloc containing the high 16 bits of an address -used when the lower 16 bits are treated as signed. */ - BFD_RELOC_M32R_HI16_SLO, - -/* This is a 16-bit reloc containing the lower 16 bits of an address. */ - BFD_RELOC_M32R_LO16, - -/* This is a 16-bit reloc containing the small data area offset for use in -add3, load, and store instructions. */ - BFD_RELOC_M32R_SDA16, - -/* For PIC. */ - BFD_RELOC_M32R_GOT24, - BFD_RELOC_M32R_26_PLTREL, - BFD_RELOC_M32R_COPY, - BFD_RELOC_M32R_GLOB_DAT, - BFD_RELOC_M32R_JMP_SLOT, - BFD_RELOC_M32R_RELATIVE, - BFD_RELOC_M32R_GOTOFF, - BFD_RELOC_M32R_GOTOFF_HI_ULO, - BFD_RELOC_M32R_GOTOFF_HI_SLO, - BFD_RELOC_M32R_GOTOFF_LO, - BFD_RELOC_M32R_GOTPC24, - BFD_RELOC_M32R_GOT16_HI_ULO, - BFD_RELOC_M32R_GOT16_HI_SLO, - BFD_RELOC_M32R_GOT16_LO, - BFD_RELOC_M32R_GOTPC_HI_ULO, - BFD_RELOC_M32R_GOTPC_HI_SLO, - BFD_RELOC_M32R_GOTPC_LO, - -/* This is a 9-bit reloc */ - BFD_RELOC_V850_9_PCREL, - -/* This is a 22-bit reloc */ - BFD_RELOC_V850_22_PCREL, - -/* This is a 16 bit offset from the short data area pointer. */ - BFD_RELOC_V850_SDA_16_16_OFFSET, - -/* This is a 16 bit offset (of which only 15 bits are used) from the -short data area pointer. */ - BFD_RELOC_V850_SDA_15_16_OFFSET, - -/* This is a 16 bit offset from the zero data area pointer. */ - BFD_RELOC_V850_ZDA_16_16_OFFSET, - -/* This is a 16 bit offset (of which only 15 bits are used) from the -zero data area pointer. */ - BFD_RELOC_V850_ZDA_15_16_OFFSET, - -/* This is an 8 bit offset (of which only 6 bits are used) from the -tiny data area pointer. */ - BFD_RELOC_V850_TDA_6_8_OFFSET, - -/* This is an 8bit offset (of which only 7 bits are used) from the tiny -data area pointer. */ - BFD_RELOC_V850_TDA_7_8_OFFSET, - -/* This is a 7 bit offset from the tiny data area pointer. */ - BFD_RELOC_V850_TDA_7_7_OFFSET, - -/* This is a 16 bit offset from the tiny data area pointer. */ - BFD_RELOC_V850_TDA_16_16_OFFSET, - -/* This is a 5 bit offset (of which only 4 bits are used) from the tiny -data area pointer. */ - BFD_RELOC_V850_TDA_4_5_OFFSET, - -/* This is a 4 bit offset from the tiny data area pointer. */ - BFD_RELOC_V850_TDA_4_4_OFFSET, - -/* This is a 16 bit offset from the short data area pointer, with the -bits placed non-contiguously in the instruction. */ - BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, - -/* This is a 16 bit offset from the zero data area pointer, with the -bits placed non-contiguously in the instruction. */ - BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, - -/* This is a 6 bit offset from the call table base pointer. */ - BFD_RELOC_V850_CALLT_6_7_OFFSET, - -/* This is a 16 bit offset from the call table base pointer. */ - BFD_RELOC_V850_CALLT_16_16_OFFSET, - -/* Used for relaxing indirect function calls. */ - BFD_RELOC_V850_LONGCALL, - -/* Used for relaxing indirect jumps. */ - BFD_RELOC_V850_LONGJUMP, - -/* Used to maintain alignment whilst relaxing. */ - BFD_RELOC_V850_ALIGN, - -/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu -instructions. */ - BFD_RELOC_V850_LO16_SPLIT_OFFSET, - -/* This is a 16-bit reloc. */ - BFD_RELOC_V850_16_PCREL, - -/* This is a 17-bit reloc. */ - BFD_RELOC_V850_17_PCREL, - -/* This is a 23-bit reloc. */ - BFD_RELOC_V850_23, - -/* This is a 32-bit reloc. */ - BFD_RELOC_V850_32_PCREL, - -/* This is a 32-bit reloc. */ - BFD_RELOC_V850_32_ABS, - -/* This is a 16-bit reloc. */ - BFD_RELOC_V850_16_SPLIT_OFFSET, - -/* This is a 16-bit reloc. */ - BFD_RELOC_V850_16_S1, - -/* Low 16 bits. 16 bit shifted by 1. */ - BFD_RELOC_V850_LO16_S1, - -/* This is a 16 bit offset from the call table base pointer. */ - BFD_RELOC_V850_CALLT_15_16_OFFSET, - -/* DSO relocations. */ - BFD_RELOC_V850_32_GOTPCREL, - -/* DSO relocations. */ - BFD_RELOC_V850_16_GOT, - -/* DSO relocations. */ - BFD_RELOC_V850_32_GOT, - -/* DSO relocations. */ - BFD_RELOC_V850_22_PLT_PCREL, - -/* DSO relocations. */ - BFD_RELOC_V850_32_PLT_PCREL, - -/* DSO relocations. */ - BFD_RELOC_V850_COPY, - -/* DSO relocations. */ - BFD_RELOC_V850_GLOB_DAT, - -/* DSO relocations. */ - BFD_RELOC_V850_JMP_SLOT, - -/* DSO relocations. */ - BFD_RELOC_V850_RELATIVE, - -/* DSO relocations. */ - BFD_RELOC_V850_16_GOTOFF, - -/* DSO relocations. */ - BFD_RELOC_V850_32_GOTOFF, - -/* start code. */ - BFD_RELOC_V850_CODE, - -/* start data in text. */ - BFD_RELOC_V850_DATA, - -/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the -instruction. */ - BFD_RELOC_MN10300_32_PCREL, - -/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the -instruction. */ - BFD_RELOC_MN10300_16_PCREL, - -/* This is a 8bit DP reloc for the tms320c30, where the most -significant 8 bits of a 24 bit word are placed into the least -significant 8 bits of the opcode. */ - BFD_RELOC_TIC30_LDP, - -/* This is a 7bit reloc for the tms320c54x, where the least -significant 7 bits of a 16 bit word are placed into the least -significant 7 bits of the opcode. */ - BFD_RELOC_TIC54X_PARTLS7, - -/* This is a 9bit DP reloc for the tms320c54x, where the most -significant 9 bits of a 16 bit word are placed into the least -significant 9 bits of the opcode. */ - BFD_RELOC_TIC54X_PARTMS9, - -/* This is an extended address 23-bit reloc for the tms320c54x. */ - BFD_RELOC_TIC54X_23, - -/* This is a 16-bit reloc for the tms320c54x, where the least -significant 16 bits of a 23-bit extended address are placed into -the opcode. */ - BFD_RELOC_TIC54X_16_OF_23, - -/* This is a reloc for the tms320c54x, where the most -significant 7 bits of a 23-bit extended address are placed into -the opcode. */ - BFD_RELOC_TIC54X_MS7_OF_23, - -/* TMS320C6000 relocations. */ - BFD_RELOC_C6000_PCR_S21, - BFD_RELOC_C6000_PCR_S12, - BFD_RELOC_C6000_PCR_S10, - BFD_RELOC_C6000_PCR_S7, - BFD_RELOC_C6000_ABS_S16, - BFD_RELOC_C6000_ABS_L16, - BFD_RELOC_C6000_ABS_H16, - BFD_RELOC_C6000_SBR_U15_B, - BFD_RELOC_C6000_SBR_U15_H, - BFD_RELOC_C6000_SBR_U15_W, - BFD_RELOC_C6000_SBR_S16, - BFD_RELOC_C6000_SBR_L16_B, - BFD_RELOC_C6000_SBR_L16_H, - BFD_RELOC_C6000_SBR_L16_W, - BFD_RELOC_C6000_SBR_H16_B, - BFD_RELOC_C6000_SBR_H16_H, - BFD_RELOC_C6000_SBR_H16_W, - BFD_RELOC_C6000_SBR_GOT_U15_W, - BFD_RELOC_C6000_SBR_GOT_L16_W, - BFD_RELOC_C6000_SBR_GOT_H16_W, - BFD_RELOC_C6000_DSBT_INDEX, - BFD_RELOC_C6000_PREL31, - BFD_RELOC_C6000_COPY, - BFD_RELOC_C6000_JUMP_SLOT, - BFD_RELOC_C6000_EHTYPE, - BFD_RELOC_C6000_PCR_H16, - BFD_RELOC_C6000_PCR_L16, - BFD_RELOC_C6000_ALIGN, - BFD_RELOC_C6000_FPHEAD, - BFD_RELOC_C6000_NOCMP, - -/* This is a 48 bit reloc for the FR30 that stores 32 bits. */ - BFD_RELOC_FR30_48, - -/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into -two sections. */ - BFD_RELOC_FR30_20, - -/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in -4 bits. */ - BFD_RELOC_FR30_6_IN_4, - -/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset -into 8 bits. */ - BFD_RELOC_FR30_8_IN_8, - -/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset -into 8 bits. */ - BFD_RELOC_FR30_9_IN_8, - -/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset -into 8 bits. */ - BFD_RELOC_FR30_10_IN_8, - -/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative -short offset into 8 bits. */ - BFD_RELOC_FR30_9_PCREL, - -/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative -short offset into 11 bits. */ - BFD_RELOC_FR30_12_PCREL, - -/* Motorola Mcore relocations. */ - BFD_RELOC_MCORE_PCREL_IMM8BY4, - BFD_RELOC_MCORE_PCREL_IMM11BY2, - BFD_RELOC_MCORE_PCREL_IMM4BY2, - BFD_RELOC_MCORE_PCREL_32, - BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, - BFD_RELOC_MCORE_RVA, - -/* Toshiba Media Processor Relocations. */ - BFD_RELOC_MEP_8, - BFD_RELOC_MEP_16, - BFD_RELOC_MEP_32, - BFD_RELOC_MEP_PCREL8A2, - BFD_RELOC_MEP_PCREL12A2, - BFD_RELOC_MEP_PCREL17A2, - BFD_RELOC_MEP_PCREL24A2, - BFD_RELOC_MEP_PCABS24A2, - BFD_RELOC_MEP_LOW16, - BFD_RELOC_MEP_HI16U, - BFD_RELOC_MEP_HI16S, - BFD_RELOC_MEP_GPREL, - BFD_RELOC_MEP_TPREL, - BFD_RELOC_MEP_TPREL7, - BFD_RELOC_MEP_TPREL7A2, - BFD_RELOC_MEP_TPREL7A4, - BFD_RELOC_MEP_UIMM24, - BFD_RELOC_MEP_ADDR24A4, - BFD_RELOC_MEP_GNU_VTINHERIT, - BFD_RELOC_MEP_GNU_VTENTRY, - - -/* These are relocations for the GETA instruction. */ - BFD_RELOC_MMIX_GETA, - BFD_RELOC_MMIX_GETA_1, - BFD_RELOC_MMIX_GETA_2, - BFD_RELOC_MMIX_GETA_3, - -/* These are relocations for a conditional branch instruction. */ - BFD_RELOC_MMIX_CBRANCH, - BFD_RELOC_MMIX_CBRANCH_J, - BFD_RELOC_MMIX_CBRANCH_1, - BFD_RELOC_MMIX_CBRANCH_2, - BFD_RELOC_MMIX_CBRANCH_3, - -/* These are relocations for the PUSHJ instruction. */ - BFD_RELOC_MMIX_PUSHJ, - BFD_RELOC_MMIX_PUSHJ_1, - BFD_RELOC_MMIX_PUSHJ_2, - BFD_RELOC_MMIX_PUSHJ_3, - BFD_RELOC_MMIX_PUSHJ_STUBBABLE, - -/* These are relocations for the JMP instruction. */ - BFD_RELOC_MMIX_JMP, - BFD_RELOC_MMIX_JMP_1, - BFD_RELOC_MMIX_JMP_2, - BFD_RELOC_MMIX_JMP_3, - -/* This is a relocation for a relative address as in a GETA instruction or -a branch. */ - BFD_RELOC_MMIX_ADDR19, - -/* This is a relocation for a relative address as in a JMP instruction. */ - BFD_RELOC_MMIX_ADDR27, - -/* This is a relocation for an instruction field that may be a general -register or a value 0..255. */ - BFD_RELOC_MMIX_REG_OR_BYTE, - -/* This is a relocation for an instruction field that may be a general -register. */ - BFD_RELOC_MMIX_REG, - -/* This is a relocation for two instruction fields holding a register and -an offset, the equivalent of the relocation. */ - BFD_RELOC_MMIX_BASE_PLUS_OFFSET, - -/* This relocation is an assertion that the expression is not allocated as -a global register. It does not modify contents. */ - BFD_RELOC_MMIX_LOCAL, - -/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative -short offset into 7 bits. */ - BFD_RELOC_AVR_7_PCREL, - -/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative -short offset into 12 bits. */ - BFD_RELOC_AVR_13_PCREL, - -/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually -program memory address) into 16 bits. */ - BFD_RELOC_AVR_16_PM, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually -data memory address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_LO8_LDI, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit -of data memory address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_HI8_LDI, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit -of program memory address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_HH8_LDI, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit -of 32 bit value) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_MS8_LDI, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(usually data memory address) into 8 bit immediate value of SUBI insn. */ - BFD_RELOC_AVR_LO8_LDI_NEG, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(high 8 bit of data memory address) into 8 bit immediate value of -SUBI insn. */ - BFD_RELOC_AVR_HI8_LDI_NEG, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(most high 8 bit of program memory address) into 8 bit immediate value -of LDI or SUBI insn. */ - BFD_RELOC_AVR_HH8_LDI_NEG, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb -of 32 bit value) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_MS8_LDI_NEG, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually -command address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_LO8_LDI_PM, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value -(command address) into 8 bit immediate value of LDI insn. If the address -is beyond the 128k boundary, the linker inserts a jump stub for this reloc -in the lower 128k. */ - BFD_RELOC_AVR_LO8_LDI_GS, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit -of command address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_HI8_LDI_PM, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit -of command address) into 8 bit immediate value of LDI insn. If the address -is beyond the 128k boundary, the linker inserts a jump stub for this reloc -below 128k. */ - BFD_RELOC_AVR_HI8_LDI_GS, - -/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit -of command address) into 8 bit immediate value of LDI insn. */ - BFD_RELOC_AVR_HH8_LDI_PM, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(usually command address) into 8 bit immediate value of SUBI insn. */ - BFD_RELOC_AVR_LO8_LDI_PM_NEG, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(high 8 bit of 16 bit command address) into 8 bit immediate value -of SUBI insn. */ - BFD_RELOC_AVR_HI8_LDI_PM_NEG, - -/* This is a 16 bit reloc for the AVR that stores negated 8 bit value -(high 6 bit of 22 bit command address) into 8 bit immediate -value of SUBI insn. */ - BFD_RELOC_AVR_HH8_LDI_PM_NEG, - -/* This is a 32 bit reloc for the AVR that stores 23 bit value -into 22 bits. */ - BFD_RELOC_AVR_CALL, - -/* This is a 16 bit reloc for the AVR that stores all needed bits -for absolute addressing with ldi with overflow check to linktime */ - BFD_RELOC_AVR_LDI, - -/* This is a 6 bit reloc for the AVR that stores offset for ldd/std -instructions */ - BFD_RELOC_AVR_6, - -/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw -instructions */ - BFD_RELOC_AVR_6_ADIW, - -/* Renesas RX Relocations. */ - BFD_RELOC_RX_NEG8, - BFD_RELOC_RX_NEG16, - BFD_RELOC_RX_NEG24, - BFD_RELOC_RX_NEG32, - BFD_RELOC_RX_16_OP, - BFD_RELOC_RX_24_OP, - BFD_RELOC_RX_32_OP, - BFD_RELOC_RX_8U, - BFD_RELOC_RX_16U, - BFD_RELOC_RX_24U, - BFD_RELOC_RX_DIR3U_PCREL, - BFD_RELOC_RX_DIFF, - BFD_RELOC_RX_GPRELB, - BFD_RELOC_RX_GPRELW, - BFD_RELOC_RX_GPRELL, - BFD_RELOC_RX_SYM, - BFD_RELOC_RX_OP_SUBTRACT, - BFD_RELOC_RX_OP_NEG, - BFD_RELOC_RX_ABS8, - BFD_RELOC_RX_ABS16, - BFD_RELOC_RX_ABS16_REV, - BFD_RELOC_RX_ABS32, - BFD_RELOC_RX_ABS32_REV, - BFD_RELOC_RX_ABS16U, - BFD_RELOC_RX_ABS16UW, - BFD_RELOC_RX_ABS16UL, - BFD_RELOC_RX_RELAX, - -/* Direct 12 bit. */ - BFD_RELOC_390_12, - -/* 12 bit GOT offset. */ - BFD_RELOC_390_GOT12, - -/* 32 bit PC relative PLT address. */ - BFD_RELOC_390_PLT32, - -/* Copy symbol at runtime. */ - BFD_RELOC_390_COPY, - -/* Create GOT entry. */ - BFD_RELOC_390_GLOB_DAT, - -/* Create PLT entry. */ - BFD_RELOC_390_JMP_SLOT, - -/* Adjust by program base. */ - BFD_RELOC_390_RELATIVE, - -/* 32 bit PC relative offset to GOT. */ - BFD_RELOC_390_GOTPC, - -/* 16 bit GOT offset. */ - BFD_RELOC_390_GOT16, - -/* PC relative 16 bit shifted by 1. */ - BFD_RELOC_390_PC16DBL, - -/* 16 bit PC rel. PLT shifted by 1. */ - BFD_RELOC_390_PLT16DBL, - -/* PC relative 32 bit shifted by 1. */ - BFD_RELOC_390_PC32DBL, - -/* 32 bit PC rel. PLT shifted by 1. */ - BFD_RELOC_390_PLT32DBL, - -/* 32 bit PC rel. GOT shifted by 1. */ - BFD_RELOC_390_GOTPCDBL, - -/* 64 bit GOT offset. */ - BFD_RELOC_390_GOT64, - -/* 64 bit PC relative PLT address. */ - BFD_RELOC_390_PLT64, - -/* 32 bit rel. offset to GOT entry. */ - BFD_RELOC_390_GOTENT, - -/* 64 bit offset to GOT. */ - BFD_RELOC_390_GOTOFF64, - -/* 12-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_390_GOTPLT12, - -/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_390_GOTPLT16, - -/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_390_GOTPLT32, - -/* 64-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_390_GOTPLT64, - -/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_390_GOTPLTENT, - -/* 16-bit rel. offset from the GOT to a PLT entry. */ - BFD_RELOC_390_PLTOFF16, - -/* 32-bit rel. offset from the GOT to a PLT entry. */ - BFD_RELOC_390_PLTOFF32, - -/* 64-bit rel. offset from the GOT to a PLT entry. */ - BFD_RELOC_390_PLTOFF64, - -/* s390 tls relocations. */ - BFD_RELOC_390_TLS_LOAD, - BFD_RELOC_390_TLS_GDCALL, - BFD_RELOC_390_TLS_LDCALL, - BFD_RELOC_390_TLS_GD32, - BFD_RELOC_390_TLS_GD64, - BFD_RELOC_390_TLS_GOTIE12, - BFD_RELOC_390_TLS_GOTIE32, - BFD_RELOC_390_TLS_GOTIE64, - BFD_RELOC_390_TLS_LDM32, - BFD_RELOC_390_TLS_LDM64, - BFD_RELOC_390_TLS_IE32, - BFD_RELOC_390_TLS_IE64, - BFD_RELOC_390_TLS_IEENT, - BFD_RELOC_390_TLS_LE32, - BFD_RELOC_390_TLS_LE64, - BFD_RELOC_390_TLS_LDO32, - BFD_RELOC_390_TLS_LDO64, - BFD_RELOC_390_TLS_DTPMOD, - BFD_RELOC_390_TLS_DTPOFF, - BFD_RELOC_390_TLS_TPOFF, - -/* Long displacement extension. */ - BFD_RELOC_390_20, - BFD_RELOC_390_GOT20, - BFD_RELOC_390_GOTPLT20, - BFD_RELOC_390_TLS_GOTIE20, - -/* Score relocations -Low 16 bit for load/store */ - BFD_RELOC_SCORE_GPREL15, - -/* This is a 24-bit reloc with the right 1 bit assumed to be 0 */ - BFD_RELOC_SCORE_DUMMY2, - BFD_RELOC_SCORE_JMP, - -/* This is a 19-bit reloc with the right 1 bit assumed to be 0 */ - BFD_RELOC_SCORE_BRANCH, - -/* This is a 32-bit reloc for 48-bit instructions. */ - BFD_RELOC_SCORE_IMM30, - -/* This is a 32-bit reloc for 48-bit instructions. */ - BFD_RELOC_SCORE_IMM32, - -/* This is a 11-bit reloc with the right 1 bit assumed to be 0 */ - BFD_RELOC_SCORE16_JMP, - -/* This is a 8-bit reloc with the right 1 bit assumed to be 0 */ - BFD_RELOC_SCORE16_BRANCH, - -/* This is a 9-bit reloc with the right 1 bit assumed to be 0 */ - BFD_RELOC_SCORE_BCMP, - -/* Undocumented Score relocs */ - BFD_RELOC_SCORE_GOT15, - BFD_RELOC_SCORE_GOT_LO16, - BFD_RELOC_SCORE_CALL15, - BFD_RELOC_SCORE_DUMMY_HI16, - -/* Scenix IP2K - 9-bit register number / data address */ - BFD_RELOC_IP2K_FR9, - -/* Scenix IP2K - 4-bit register/data bank number */ - BFD_RELOC_IP2K_BANK, - -/* Scenix IP2K - low 13 bits of instruction word address */ - BFD_RELOC_IP2K_ADDR16CJP, - -/* Scenix IP2K - high 3 bits of instruction word address */ - BFD_RELOC_IP2K_PAGE3, - -/* Scenix IP2K - ext/low/high 8 bits of data address */ - BFD_RELOC_IP2K_LO8DATA, - BFD_RELOC_IP2K_HI8DATA, - BFD_RELOC_IP2K_EX8DATA, - -/* Scenix IP2K - low/high 8 bits of instruction word address */ - BFD_RELOC_IP2K_LO8INSN, - BFD_RELOC_IP2K_HI8INSN, - -/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */ - BFD_RELOC_IP2K_PC_SKIP, - -/* Scenix IP2K - 16 bit word address in text section. */ - BFD_RELOC_IP2K_TEXT, - -/* Scenix IP2K - 7-bit sp or dp offset */ - BFD_RELOC_IP2K_FR_OFFSET, - -/* Scenix VPE4K coprocessor - data/insn-space addressing */ - BFD_RELOC_VPE4KMATH_DATA, - BFD_RELOC_VPE4KMATH_INSN, - -/* These two relocations are used by the linker to determine which of -the entries in a C++ virtual function table are actually used. When -the --gc-sections option is given, the linker will zero out the entries -that are not used, so that the code for those functions need not be -included in the output. - -VTABLE_INHERIT is a zero-space relocation used to describe to the -linker the inheritance tree of a C++ virtual function table. The -relocation's symbol should be the parent class' vtable, and the -relocation should be located at the child vtable. - -VTABLE_ENTRY is a zero-space relocation that describes the use of a -virtual function table entry. The reloc's symbol should refer to the -table of the class mentioned in the code. Off of that base, an offset -describes the entry that is being used. For Rela hosts, this offset -is stored in the reloc's addend. For Rel hosts, we are forced to put -this offset in the reloc's section offset. */ - BFD_RELOC_VTABLE_INHERIT, - BFD_RELOC_VTABLE_ENTRY, - -/* Intel IA64 Relocations. */ - BFD_RELOC_IA64_IMM14, - BFD_RELOC_IA64_IMM22, - BFD_RELOC_IA64_IMM64, - BFD_RELOC_IA64_DIR32MSB, - BFD_RELOC_IA64_DIR32LSB, - BFD_RELOC_IA64_DIR64MSB, - BFD_RELOC_IA64_DIR64LSB, - BFD_RELOC_IA64_GPREL22, - BFD_RELOC_IA64_GPREL64I, - BFD_RELOC_IA64_GPREL32MSB, - BFD_RELOC_IA64_GPREL32LSB, - BFD_RELOC_IA64_GPREL64MSB, - BFD_RELOC_IA64_GPREL64LSB, - BFD_RELOC_IA64_LTOFF22, - BFD_RELOC_IA64_LTOFF64I, - BFD_RELOC_IA64_PLTOFF22, - BFD_RELOC_IA64_PLTOFF64I, - BFD_RELOC_IA64_PLTOFF64MSB, - BFD_RELOC_IA64_PLTOFF64LSB, - BFD_RELOC_IA64_FPTR64I, - BFD_RELOC_IA64_FPTR32MSB, - BFD_RELOC_IA64_FPTR32LSB, - BFD_RELOC_IA64_FPTR64MSB, - BFD_RELOC_IA64_FPTR64LSB, - BFD_RELOC_IA64_PCREL21B, - BFD_RELOC_IA64_PCREL21BI, - BFD_RELOC_IA64_PCREL21M, - BFD_RELOC_IA64_PCREL21F, - BFD_RELOC_IA64_PCREL22, - BFD_RELOC_IA64_PCREL60B, - BFD_RELOC_IA64_PCREL64I, - BFD_RELOC_IA64_PCREL32MSB, - BFD_RELOC_IA64_PCREL32LSB, - BFD_RELOC_IA64_PCREL64MSB, - BFD_RELOC_IA64_PCREL64LSB, - BFD_RELOC_IA64_LTOFF_FPTR22, - BFD_RELOC_IA64_LTOFF_FPTR64I, - BFD_RELOC_IA64_LTOFF_FPTR32MSB, - BFD_RELOC_IA64_LTOFF_FPTR32LSB, - BFD_RELOC_IA64_LTOFF_FPTR64MSB, - BFD_RELOC_IA64_LTOFF_FPTR64LSB, - BFD_RELOC_IA64_SEGREL32MSB, - BFD_RELOC_IA64_SEGREL32LSB, - BFD_RELOC_IA64_SEGREL64MSB, - BFD_RELOC_IA64_SEGREL64LSB, - BFD_RELOC_IA64_SECREL32MSB, - BFD_RELOC_IA64_SECREL32LSB, - BFD_RELOC_IA64_SECREL64MSB, - BFD_RELOC_IA64_SECREL64LSB, - BFD_RELOC_IA64_REL32MSB, - BFD_RELOC_IA64_REL32LSB, - BFD_RELOC_IA64_REL64MSB, - BFD_RELOC_IA64_REL64LSB, - BFD_RELOC_IA64_LTV32MSB, - BFD_RELOC_IA64_LTV32LSB, - BFD_RELOC_IA64_LTV64MSB, - BFD_RELOC_IA64_LTV64LSB, - BFD_RELOC_IA64_IPLTMSB, - BFD_RELOC_IA64_IPLTLSB, - BFD_RELOC_IA64_COPY, - BFD_RELOC_IA64_LTOFF22X, - BFD_RELOC_IA64_LDXMOV, - BFD_RELOC_IA64_TPREL14, - BFD_RELOC_IA64_TPREL22, - BFD_RELOC_IA64_TPREL64I, - BFD_RELOC_IA64_TPREL64MSB, - BFD_RELOC_IA64_TPREL64LSB, - BFD_RELOC_IA64_LTOFF_TPREL22, - BFD_RELOC_IA64_DTPMOD64MSB, - BFD_RELOC_IA64_DTPMOD64LSB, - BFD_RELOC_IA64_LTOFF_DTPMOD22, - BFD_RELOC_IA64_DTPREL14, - BFD_RELOC_IA64_DTPREL22, - BFD_RELOC_IA64_DTPREL64I, - BFD_RELOC_IA64_DTPREL32MSB, - BFD_RELOC_IA64_DTPREL32LSB, - BFD_RELOC_IA64_DTPREL64MSB, - BFD_RELOC_IA64_DTPREL64LSB, - BFD_RELOC_IA64_LTOFF_DTPREL22, - -/* Motorola 68HC11 reloc. -This is the 8 bit high part of an absolute address. */ - BFD_RELOC_M68HC11_HI8, - -/* Motorola 68HC11 reloc. -This is the 8 bit low part of an absolute address. */ - BFD_RELOC_M68HC11_LO8, - -/* Motorola 68HC11 reloc. -This is the 3 bit of a value. */ - BFD_RELOC_M68HC11_3B, - -/* Motorola 68HC11 reloc. -This reloc marks the beginning of a jump/call instruction. -It is used for linker relaxation to correctly identify beginning -of instruction and change some branches to use PC-relative -addressing mode. */ - BFD_RELOC_M68HC11_RL_JUMP, - -/* Motorola 68HC11 reloc. -This reloc marks a group of several instructions that gcc generates -and for which the linker relaxation pass can modify and/or remove -some of them. */ - BFD_RELOC_M68HC11_RL_GROUP, - -/* Motorola 68HC11 reloc. -This is the 16-bit lower part of an address. It is used for 'call' -instruction to specify the symbol address without any special -transformation (due to memory bank window). */ - BFD_RELOC_M68HC11_LO16, - -/* Motorola 68HC11 reloc. -This is a 8-bit reloc that specifies the page number of an address. -It is used by 'call' instruction to specify the page number of -the symbol. */ - BFD_RELOC_M68HC11_PAGE, - -/* Motorola 68HC11 reloc. -This is a 24-bit reloc that represents the address with a 16-bit -value and a 8-bit page number. The symbol address is transformed -to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ - BFD_RELOC_M68HC11_24, - -/* Motorola 68HC12 reloc. -This is the 5 bits of a value. */ - BFD_RELOC_M68HC12_5B, - -/* NS CR16C Relocations. */ - BFD_RELOC_16C_NUM08, - BFD_RELOC_16C_NUM08_C, - BFD_RELOC_16C_NUM16, - BFD_RELOC_16C_NUM16_C, - BFD_RELOC_16C_NUM32, - BFD_RELOC_16C_NUM32_C, - BFD_RELOC_16C_DISP04, - BFD_RELOC_16C_DISP04_C, - BFD_RELOC_16C_DISP08, - BFD_RELOC_16C_DISP08_C, - BFD_RELOC_16C_DISP16, - BFD_RELOC_16C_DISP16_C, - BFD_RELOC_16C_DISP24, - BFD_RELOC_16C_DISP24_C, - BFD_RELOC_16C_DISP24a, - BFD_RELOC_16C_DISP24a_C, - BFD_RELOC_16C_REG04, - BFD_RELOC_16C_REG04_C, - BFD_RELOC_16C_REG04a, - BFD_RELOC_16C_REG04a_C, - BFD_RELOC_16C_REG14, - BFD_RELOC_16C_REG14_C, - BFD_RELOC_16C_REG16, - BFD_RELOC_16C_REG16_C, - BFD_RELOC_16C_REG20, - BFD_RELOC_16C_REG20_C, - BFD_RELOC_16C_ABS20, - BFD_RELOC_16C_ABS20_C, - BFD_RELOC_16C_ABS24, - BFD_RELOC_16C_ABS24_C, - BFD_RELOC_16C_IMM04, - BFD_RELOC_16C_IMM04_C, - BFD_RELOC_16C_IMM16, - BFD_RELOC_16C_IMM16_C, - BFD_RELOC_16C_IMM20, - BFD_RELOC_16C_IMM20_C, - BFD_RELOC_16C_IMM24, - BFD_RELOC_16C_IMM24_C, - BFD_RELOC_16C_IMM32, - BFD_RELOC_16C_IMM32_C, - -/* NS CR16 Relocations. */ - BFD_RELOC_CR16_NUM8, - BFD_RELOC_CR16_NUM16, - BFD_RELOC_CR16_NUM32, - BFD_RELOC_CR16_NUM32a, - BFD_RELOC_CR16_REGREL0, - BFD_RELOC_CR16_REGREL4, - BFD_RELOC_CR16_REGREL4a, - BFD_RELOC_CR16_REGREL14, - BFD_RELOC_CR16_REGREL14a, - BFD_RELOC_CR16_REGREL16, - BFD_RELOC_CR16_REGREL20, - BFD_RELOC_CR16_REGREL20a, - BFD_RELOC_CR16_ABS20, - BFD_RELOC_CR16_ABS24, - BFD_RELOC_CR16_IMM4, - BFD_RELOC_CR16_IMM8, - BFD_RELOC_CR16_IMM16, - BFD_RELOC_CR16_IMM20, - BFD_RELOC_CR16_IMM24, - BFD_RELOC_CR16_IMM32, - BFD_RELOC_CR16_IMM32a, - BFD_RELOC_CR16_DISP4, - BFD_RELOC_CR16_DISP8, - BFD_RELOC_CR16_DISP16, - BFD_RELOC_CR16_DISP20, - BFD_RELOC_CR16_DISP24, - BFD_RELOC_CR16_DISP24a, - BFD_RELOC_CR16_SWITCH8, - BFD_RELOC_CR16_SWITCH16, - BFD_RELOC_CR16_SWITCH32, - BFD_RELOC_CR16_GOT_REGREL20, - BFD_RELOC_CR16_GOTC_REGREL20, - BFD_RELOC_CR16_GLOB_DAT, - -/* NS CRX Relocations. */ - BFD_RELOC_CRX_REL4, - BFD_RELOC_CRX_REL8, - BFD_RELOC_CRX_REL8_CMP, - BFD_RELOC_CRX_REL16, - BFD_RELOC_CRX_REL24, - BFD_RELOC_CRX_REL32, - BFD_RELOC_CRX_REGREL12, - BFD_RELOC_CRX_REGREL22, - BFD_RELOC_CRX_REGREL28, - BFD_RELOC_CRX_REGREL32, - BFD_RELOC_CRX_ABS16, - BFD_RELOC_CRX_ABS32, - BFD_RELOC_CRX_NUM8, - BFD_RELOC_CRX_NUM16, - BFD_RELOC_CRX_NUM32, - BFD_RELOC_CRX_IMM16, - BFD_RELOC_CRX_IMM32, - BFD_RELOC_CRX_SWITCH8, - BFD_RELOC_CRX_SWITCH16, - BFD_RELOC_CRX_SWITCH32, - -/* These relocs are only used within the CRIS assembler. They are not -(at present) written to any object files. */ - BFD_RELOC_CRIS_BDISP8, - BFD_RELOC_CRIS_UNSIGNED_5, - BFD_RELOC_CRIS_SIGNED_6, - BFD_RELOC_CRIS_UNSIGNED_6, - BFD_RELOC_CRIS_SIGNED_8, - BFD_RELOC_CRIS_UNSIGNED_8, - BFD_RELOC_CRIS_SIGNED_16, - BFD_RELOC_CRIS_UNSIGNED_16, - BFD_RELOC_CRIS_LAPCQ_OFFSET, - BFD_RELOC_CRIS_UNSIGNED_4, - -/* Relocs used in ELF shared libraries for CRIS. */ - BFD_RELOC_CRIS_COPY, - BFD_RELOC_CRIS_GLOB_DAT, - BFD_RELOC_CRIS_JUMP_SLOT, - BFD_RELOC_CRIS_RELATIVE, - -/* 32-bit offset to symbol-entry within GOT. */ - BFD_RELOC_CRIS_32_GOT, - -/* 16-bit offset to symbol-entry within GOT. */ - BFD_RELOC_CRIS_16_GOT, - -/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_CRIS_32_GOTPLT, - -/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ - BFD_RELOC_CRIS_16_GOTPLT, - -/* 32-bit offset to symbol, relative to GOT. */ - BFD_RELOC_CRIS_32_GOTREL, - -/* 32-bit offset to symbol with PLT entry, relative to GOT. */ - BFD_RELOC_CRIS_32_PLT_GOTREL, - -/* 32-bit offset to symbol with PLT entry, relative to this relocation. */ - BFD_RELOC_CRIS_32_PLT_PCREL, - -/* Relocs used in TLS code for CRIS. */ - BFD_RELOC_CRIS_32_GOT_GD, - BFD_RELOC_CRIS_16_GOT_GD, - BFD_RELOC_CRIS_32_GD, - BFD_RELOC_CRIS_DTP, - BFD_RELOC_CRIS_32_DTPREL, - BFD_RELOC_CRIS_16_DTPREL, - BFD_RELOC_CRIS_32_GOT_TPREL, - BFD_RELOC_CRIS_16_GOT_TPREL, - BFD_RELOC_CRIS_32_TPREL, - BFD_RELOC_CRIS_16_TPREL, - BFD_RELOC_CRIS_DTPMOD, - BFD_RELOC_CRIS_32_IE, - -/* Intel i860 Relocations. */ - BFD_RELOC_860_COPY, - BFD_RELOC_860_GLOB_DAT, - BFD_RELOC_860_JUMP_SLOT, - BFD_RELOC_860_RELATIVE, - BFD_RELOC_860_PC26, - BFD_RELOC_860_PLT26, - BFD_RELOC_860_PC16, - BFD_RELOC_860_LOW0, - BFD_RELOC_860_SPLIT0, - BFD_RELOC_860_LOW1, - BFD_RELOC_860_SPLIT1, - BFD_RELOC_860_LOW2, - BFD_RELOC_860_SPLIT2, - BFD_RELOC_860_LOW3, - BFD_RELOC_860_LOGOT0, - BFD_RELOC_860_SPGOT0, - BFD_RELOC_860_LOGOT1, - BFD_RELOC_860_SPGOT1, - BFD_RELOC_860_LOGOTOFF0, - BFD_RELOC_860_SPGOTOFF0, - BFD_RELOC_860_LOGOTOFF1, - BFD_RELOC_860_SPGOTOFF1, - BFD_RELOC_860_LOGOTOFF2, - BFD_RELOC_860_LOGOTOFF3, - BFD_RELOC_860_LOPC, - BFD_RELOC_860_HIGHADJ, - BFD_RELOC_860_HAGOT, - BFD_RELOC_860_HAGOTOFF, - BFD_RELOC_860_HAPC, - BFD_RELOC_860_HIGH, - BFD_RELOC_860_HIGOT, - BFD_RELOC_860_HIGOTOFF, - -/* OpenRISC Relocations. */ - BFD_RELOC_OPENRISC_ABS_26, - BFD_RELOC_OPENRISC_REL_26, - -/* H8 elf Relocations. */ - BFD_RELOC_H8_DIR16A8, - BFD_RELOC_H8_DIR16R8, - BFD_RELOC_H8_DIR24A8, - BFD_RELOC_H8_DIR24R8, - BFD_RELOC_H8_DIR32A16, - -/* Sony Xstormy16 Relocations. */ - BFD_RELOC_XSTORMY16_REL_12, - BFD_RELOC_XSTORMY16_12, - BFD_RELOC_XSTORMY16_24, - BFD_RELOC_XSTORMY16_FPTR16, - -/* Self-describing complex relocations. */ - BFD_RELOC_RELC, - - -/* Infineon Relocations. */ - BFD_RELOC_XC16X_PAG, - BFD_RELOC_XC16X_POF, - BFD_RELOC_XC16X_SEG, - BFD_RELOC_XC16X_SOF, - -/* Relocations used by VAX ELF. */ - BFD_RELOC_VAX_GLOB_DAT, - BFD_RELOC_VAX_JMP_SLOT, - BFD_RELOC_VAX_RELATIVE, - -/* Morpho MT - 16 bit immediate relocation. */ - BFD_RELOC_MT_PC16, - -/* Morpho MT - Hi 16 bits of an address. */ - BFD_RELOC_MT_HI16, - -/* Morpho MT - Low 16 bits of an address. */ - BFD_RELOC_MT_LO16, - -/* Morpho MT - Used to tell the linker which vtable entries are used. */ - BFD_RELOC_MT_GNU_VTINHERIT, - -/* Morpho MT - Used to tell the linker which vtable entries are used. */ - BFD_RELOC_MT_GNU_VTENTRY, - -/* Morpho MT - 8 bit immediate relocation. */ - BFD_RELOC_MT_PCINSN8, - -/* msp430 specific relocation codes */ - BFD_RELOC_MSP430_10_PCREL, - BFD_RELOC_MSP430_16_PCREL, - BFD_RELOC_MSP430_16, - BFD_RELOC_MSP430_16_PCREL_BYTE, - BFD_RELOC_MSP430_16_BYTE, - BFD_RELOC_MSP430_2X_PCREL, - BFD_RELOC_MSP430_RL_PCREL, - -/* IQ2000 Relocations. */ - BFD_RELOC_IQ2000_OFFSET_16, - BFD_RELOC_IQ2000_OFFSET_21, - BFD_RELOC_IQ2000_UHI16, - -/* Special Xtensa relocation used only by PLT entries in ELF shared -objects to indicate that the runtime linker should set the value -to one of its own internal functions or data structures. */ - BFD_RELOC_XTENSA_RTLD, - -/* Xtensa relocations for ELF shared objects. */ - BFD_RELOC_XTENSA_GLOB_DAT, - BFD_RELOC_XTENSA_JMP_SLOT, - BFD_RELOC_XTENSA_RELATIVE, - -/* Xtensa relocation used in ELF object files for symbols that may require -PLT entries. Otherwise, this is just a generic 32-bit relocation. */ - BFD_RELOC_XTENSA_PLT, - -/* Xtensa relocations to mark the difference of two local symbols. -These are only needed to support linker relaxation and can be ignored -when not relaxing. The field is set to the value of the difference -assuming no relaxation. The relocation encodes the position of the -first symbol so the linker can determine whether to adjust the field -value. */ - BFD_RELOC_XTENSA_DIFF8, - BFD_RELOC_XTENSA_DIFF16, - BFD_RELOC_XTENSA_DIFF32, - -/* Generic Xtensa relocations for instruction operands. Only the slot -number is encoded in the relocation. The relocation applies to the -last PC-relative immediate operand, or if there are no PC-relative -immediates, to the last immediate operand. */ - BFD_RELOC_XTENSA_SLOT0_OP, - BFD_RELOC_XTENSA_SLOT1_OP, - BFD_RELOC_XTENSA_SLOT2_OP, - BFD_RELOC_XTENSA_SLOT3_OP, - BFD_RELOC_XTENSA_SLOT4_OP, - BFD_RELOC_XTENSA_SLOT5_OP, - BFD_RELOC_XTENSA_SLOT6_OP, - BFD_RELOC_XTENSA_SLOT7_OP, - BFD_RELOC_XTENSA_SLOT8_OP, - BFD_RELOC_XTENSA_SLOT9_OP, - BFD_RELOC_XTENSA_SLOT10_OP, - BFD_RELOC_XTENSA_SLOT11_OP, - BFD_RELOC_XTENSA_SLOT12_OP, - BFD_RELOC_XTENSA_SLOT13_OP, - BFD_RELOC_XTENSA_SLOT14_OP, - -/* Alternate Xtensa relocations. Only the slot is encoded in the -relocation. The meaning of these relocations is opcode-specific. */ - BFD_RELOC_XTENSA_SLOT0_ALT, - BFD_RELOC_XTENSA_SLOT1_ALT, - BFD_RELOC_XTENSA_SLOT2_ALT, - BFD_RELOC_XTENSA_SLOT3_ALT, - BFD_RELOC_XTENSA_SLOT4_ALT, - BFD_RELOC_XTENSA_SLOT5_ALT, - BFD_RELOC_XTENSA_SLOT6_ALT, - BFD_RELOC_XTENSA_SLOT7_ALT, - BFD_RELOC_XTENSA_SLOT8_ALT, - BFD_RELOC_XTENSA_SLOT9_ALT, - BFD_RELOC_XTENSA_SLOT10_ALT, - BFD_RELOC_XTENSA_SLOT11_ALT, - BFD_RELOC_XTENSA_SLOT12_ALT, - BFD_RELOC_XTENSA_SLOT13_ALT, - BFD_RELOC_XTENSA_SLOT14_ALT, - -/* Xtensa relocations for backward compatibility. These have all been -replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ - BFD_RELOC_XTENSA_OP0, - BFD_RELOC_XTENSA_OP1, - BFD_RELOC_XTENSA_OP2, - -/* Xtensa relocation to mark that the assembler expanded the -instructions from an original target. The expansion size is -encoded in the reloc size. */ - BFD_RELOC_XTENSA_ASM_EXPAND, - -/* Xtensa relocation to mark that the linker should simplify -assembler-expanded instructions. This is commonly used -internally by the linker after analysis of a -BFD_RELOC_XTENSA_ASM_EXPAND. */ - BFD_RELOC_XTENSA_ASM_SIMPLIFY, - -/* Xtensa TLS relocations. */ - BFD_RELOC_XTENSA_TLSDESC_FN, - BFD_RELOC_XTENSA_TLSDESC_ARG, - BFD_RELOC_XTENSA_TLS_DTPOFF, - BFD_RELOC_XTENSA_TLS_TPOFF, - BFD_RELOC_XTENSA_TLS_FUNC, - BFD_RELOC_XTENSA_TLS_ARG, - BFD_RELOC_XTENSA_TLS_CALL, - -/* 8 bit signed offset in (ix+d) or (iy+d). */ - BFD_RELOC_Z80_DISP8, - -/* DJNZ offset. */ - BFD_RELOC_Z8K_DISP7, - -/* CALR offset. */ - BFD_RELOC_Z8K_CALLR, - -/* 4 bit value. */ - BFD_RELOC_Z8K_IMM4L, - -/* Lattice Mico32 relocations. */ - BFD_RELOC_LM32_CALL, - BFD_RELOC_LM32_BRANCH, - BFD_RELOC_LM32_16_GOT, - BFD_RELOC_LM32_GOTOFF_HI16, - BFD_RELOC_LM32_GOTOFF_LO16, - BFD_RELOC_LM32_COPY, - BFD_RELOC_LM32_GLOB_DAT, - BFD_RELOC_LM32_JMP_SLOT, - BFD_RELOC_LM32_RELATIVE, - -/* Difference between two section addreses. Must be followed by a -BFD_RELOC_MACH_O_PAIR. */ - BFD_RELOC_MACH_O_SECTDIFF, - -/* Pair of relocation. Contains the first symbol. */ - BFD_RELOC_MACH_O_PAIR, - -/* PCREL relocations. They are marked as branch to create PLT entry if -required. */ - BFD_RELOC_MACH_O_X86_64_BRANCH32, - BFD_RELOC_MACH_O_X86_64_BRANCH8, - -/* Used when referencing a GOT entry. */ - BFD_RELOC_MACH_O_X86_64_GOT, - -/* Used when loading a GOT entry with movq. It is specially marked so that -the linker could optimize the movq to a leaq if possible. */ - BFD_RELOC_MACH_O_X86_64_GOT_LOAD, - -/* Symbol will be substracted. Must be followed by a BFD_RELOC_64. */ - BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32, - -/* Symbol will be substracted. Must be followed by a BFD_RELOC_64. */ - BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64, - -/* Same as BFD_RELOC_32_PCREL but with an implicit -1 addend. */ - BFD_RELOC_MACH_O_X86_64_PCREL32_1, - -/* Same as BFD_RELOC_32_PCREL but with an implicit -2 addend. */ - BFD_RELOC_MACH_O_X86_64_PCREL32_2, - -/* Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. */ - BFD_RELOC_MACH_O_X86_64_PCREL32_4, - -/* This is a 32 bit reloc for the microblaze that stores the -low 16 bits of a value */ - BFD_RELOC_MICROBLAZE_32_LO, - -/* This is a 32 bit pc-relative reloc for the microblaze that -stores the low 16 bits of a value */ - BFD_RELOC_MICROBLAZE_32_LO_PCREL, - -/* This is a 32 bit reloc for the microblaze that stores a -value relative to the read-only small data area anchor */ - BFD_RELOC_MICROBLAZE_32_ROSDA, - -/* This is a 32 bit reloc for the microblaze that stores a -value relative to the read-write small data area anchor */ - BFD_RELOC_MICROBLAZE_32_RWSDA, - -/* This is a 32 bit reloc for the microblaze to handle -expressions of the form "Symbol Op Symbol" */ - BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM, - -/* This is a 64 bit reloc that stores the 32 bit pc relative -value in two words (with an imm instruction). No relocation is -done here - only used for relaxing */ - BFD_RELOC_MICROBLAZE_64_NONE, - -/* This is a 64 bit reloc that stores the 32 bit pc relative -value in two words (with an imm instruction). The relocation is -PC-relative GOT offset */ - BFD_RELOC_MICROBLAZE_64_GOTPC, - -/* This is a 64 bit reloc that stores the 32 bit pc relative -value in two words (with an imm instruction). The relocation is -GOT offset */ - BFD_RELOC_MICROBLAZE_64_GOT, - -/* This is a 64 bit reloc that stores the 32 bit pc relative -value in two words (with an imm instruction). The relocation is -PC-relative offset into PLT */ - BFD_RELOC_MICROBLAZE_64_PLT, - -/* This is a 64 bit reloc that stores the 32 bit GOT relative -value in two words (with an imm instruction). The relocation is -relative offset from _GLOBAL_OFFSET_TABLE_ */ - BFD_RELOC_MICROBLAZE_64_GOTOFF, - -/* This is a 32 bit reloc that stores the 32 bit GOT relative -value in a word. The relocation is relative offset from */ - BFD_RELOC_MICROBLAZE_32_GOTOFF, - -/* This is used to tell the dynamic linker to copy the value out of -the dynamic object into the runtime process image. */ - BFD_RELOC_MICROBLAZE_COPY, - -/* Tilera TILEPro Relocations. */ - BFD_RELOC_TILEPRO_COPY, - BFD_RELOC_TILEPRO_GLOB_DAT, - BFD_RELOC_TILEPRO_JMP_SLOT, - BFD_RELOC_TILEPRO_RELATIVE, - BFD_RELOC_TILEPRO_BROFF_X1, - BFD_RELOC_TILEPRO_JOFFLONG_X1, - BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT, - BFD_RELOC_TILEPRO_IMM8_X0, - BFD_RELOC_TILEPRO_IMM8_Y0, - BFD_RELOC_TILEPRO_IMM8_X1, - BFD_RELOC_TILEPRO_IMM8_Y1, - BFD_RELOC_TILEPRO_DEST_IMM8_X1, - BFD_RELOC_TILEPRO_MT_IMM15_X1, - BFD_RELOC_TILEPRO_MF_IMM15_X1, - BFD_RELOC_TILEPRO_IMM16_X0, - BFD_RELOC_TILEPRO_IMM16_X1, - BFD_RELOC_TILEPRO_IMM16_X0_LO, - BFD_RELOC_TILEPRO_IMM16_X1_LO, - BFD_RELOC_TILEPRO_IMM16_X0_HI, - BFD_RELOC_TILEPRO_IMM16_X1_HI, - BFD_RELOC_TILEPRO_IMM16_X0_HA, - BFD_RELOC_TILEPRO_IMM16_X1_HA, - BFD_RELOC_TILEPRO_IMM16_X0_PCREL, - BFD_RELOC_TILEPRO_IMM16_X1_PCREL, - BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL, - BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL, - BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL, - BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL, - BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL, - BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL, - BFD_RELOC_TILEPRO_IMM16_X0_GOT, - BFD_RELOC_TILEPRO_IMM16_X1_GOT, - BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO, - BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO, - BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI, - BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI, - BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA, - BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA, - BFD_RELOC_TILEPRO_MMSTART_X0, - BFD_RELOC_TILEPRO_MMEND_X0, - BFD_RELOC_TILEPRO_MMSTART_X1, - BFD_RELOC_TILEPRO_MMEND_X1, - BFD_RELOC_TILEPRO_SHAMT_X0, - BFD_RELOC_TILEPRO_SHAMT_X1, - BFD_RELOC_TILEPRO_SHAMT_Y0, - BFD_RELOC_TILEPRO_SHAMT_Y1, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI, - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA, - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA, - BFD_RELOC_TILEPRO_TLS_DTPMOD32, - BFD_RELOC_TILEPRO_TLS_DTPOFF32, - BFD_RELOC_TILEPRO_TLS_TPOFF32, - -/* Tilera TILE-Gx Relocations. */ - BFD_RELOC_TILEGX_HW0, - BFD_RELOC_TILEGX_HW1, - BFD_RELOC_TILEGX_HW2, - BFD_RELOC_TILEGX_HW3, - BFD_RELOC_TILEGX_HW0_LAST, - BFD_RELOC_TILEGX_HW1_LAST, - BFD_RELOC_TILEGX_HW2_LAST, - BFD_RELOC_TILEGX_COPY, - BFD_RELOC_TILEGX_GLOB_DAT, - BFD_RELOC_TILEGX_JMP_SLOT, - BFD_RELOC_TILEGX_RELATIVE, - BFD_RELOC_TILEGX_BROFF_X1, - BFD_RELOC_TILEGX_JUMPOFF_X1, - BFD_RELOC_TILEGX_JUMPOFF_X1_PLT, - BFD_RELOC_TILEGX_IMM8_X0, - BFD_RELOC_TILEGX_IMM8_Y0, - BFD_RELOC_TILEGX_IMM8_X1, - BFD_RELOC_TILEGX_IMM8_Y1, - BFD_RELOC_TILEGX_DEST_IMM8_X1, - BFD_RELOC_TILEGX_MT_IMM14_X1, - BFD_RELOC_TILEGX_MF_IMM14_X1, - BFD_RELOC_TILEGX_MMSTART_X0, - BFD_RELOC_TILEGX_MMEND_X0, - BFD_RELOC_TILEGX_SHAMT_X0, - BFD_RELOC_TILEGX_SHAMT_X1, - BFD_RELOC_TILEGX_SHAMT_Y0, - BFD_RELOC_TILEGX_SHAMT_Y1, - BFD_RELOC_TILEGX_IMM16_X0_HW0, - BFD_RELOC_TILEGX_IMM16_X1_HW0, - BFD_RELOC_TILEGX_IMM16_X0_HW1, - BFD_RELOC_TILEGX_IMM16_X1_HW1, - BFD_RELOC_TILEGX_IMM16_X0_HW2, - BFD_RELOC_TILEGX_IMM16_X1_HW2, - BFD_RELOC_TILEGX_IMM16_X0_HW3, - BFD_RELOC_TILEGX_IMM16_X1_HW3, - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST, - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST, - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST, - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST, - BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL, - BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT, - BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD, - BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE, - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE, - BFD_RELOC_TILEGX_TLS_DTPMOD64, - BFD_RELOC_TILEGX_TLS_DTPOFF64, - BFD_RELOC_TILEGX_TLS_TPOFF64, - BFD_RELOC_TILEGX_TLS_DTPMOD32, - BFD_RELOC_TILEGX_TLS_DTPOFF32, - BFD_RELOC_TILEGX_TLS_TPOFF32, - BFD_RELOC_UNUSED }; -typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; -reloc_howto_type *bfd_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); -reloc_howto_type *bfd_reloc_name_lookup - (bfd *abfd, const char *reloc_name); - -const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); - -/* Extracted from syms.c. */ - -typedef struct bfd_symbol -{ - /* A pointer to the BFD which owns the symbol. This information - is necessary so that a back end can work out what additional - information (invisible to the application writer) is carried - with the symbol. - - This field is *almost* redundant, since you can use section->owner - instead, except that some symbols point to the global sections - bfd_{abs,com,und}_section. This could be fixed by making - these globals be per-bfd (or per-target-flavor). FIXME. */ - struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ - - /* The text of the symbol. The name is left alone, and not copied; the - application may not alter it. */ - const char *name; - - /* The value of the symbol. This really should be a union of a - numeric value with a pointer, since some flags indicate that - a pointer to another symbol is stored here. */ - symvalue value; - - /* Attributes of a symbol. */ -#define BSF_NO_FLAGS 0x00 - - /* The symbol has local scope; <> in <>. The value - is the offset into the section of the data. */ -#define BSF_LOCAL (1 << 0) - - /* The symbol has global scope; initialized data in <>. The - value is the offset into the section of the data. */ -#define BSF_GLOBAL (1 << 1) - - /* The symbol has global scope and is exported. The value is - the offset into the section of the data. */ -#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ - - /* A normal C symbol would be one of: - <>, <>, <> or - <>. */ - - /* The symbol is a debugging record. The value has an arbitrary - meaning, unless BSF_DEBUGGING_RELOC is also set. */ -#define BSF_DEBUGGING (1 << 2) - - /* The symbol denotes a function entry point. Used in ELF, - perhaps others someday. */ -#define BSF_FUNCTION (1 << 3) - - /* Used by the linker. */ -#define BSF_KEEP (1 << 5) -#define BSF_KEEP_G (1 << 6) - - /* A weak global symbol, overridable without warnings by - a regular global symbol of the same name. */ -#define BSF_WEAK (1 << 7) - - /* This symbol was created to point to a section, e.g. ELF's - STT_SECTION symbols. */ -#define BSF_SECTION_SYM (1 << 8) - - /* The symbol used to be a common symbol, but now it is - allocated. */ -#define BSF_OLD_COMMON (1 << 9) - - /* In some files the type of a symbol sometimes alters its - location in an output file - ie in coff a <> symbol - which is also <> symbol appears where it was - declared and not at the end of a section. This bit is set - by the target BFD part to convey this information. */ -#define BSF_NOT_AT_END (1 << 10) - - /* Signal that the symbol is the label of constructor section. */ -#define BSF_CONSTRUCTOR (1 << 11) - - /* Signal that the symbol is a warning symbol. The name is a - warning. The name of the next symbol is the one to warn about; - if a reference is made to a symbol with the same name as the next - symbol, a warning is issued by the linker. */ -#define BSF_WARNING (1 << 12) - - /* Signal that the symbol is indirect. This symbol is an indirect - pointer to the symbol with the same name as the next symbol. */ -#define BSF_INDIRECT (1 << 13) - - /* BSF_FILE marks symbols that contain a file name. This is used - for ELF STT_FILE symbols. */ -#define BSF_FILE (1 << 14) - - /* Symbol is from dynamic linking information. */ -#define BSF_DYNAMIC (1 << 15) - - /* The symbol denotes a data object. Used in ELF, and perhaps - others someday. */ -#define BSF_OBJECT (1 << 16) - - /* This symbol is a debugging symbol. The value is the offset - into the section of the data. BSF_DEBUGGING should be set - as well. */ -#define BSF_DEBUGGING_RELOC (1 << 17) - - /* This symbol is thread local. Used in ELF. */ -#define BSF_THREAD_LOCAL (1 << 18) - - /* This symbol represents a complex relocation expression, - with the expression tree serialized in the symbol name. */ -#define BSF_RELC (1 << 19) - - /* This symbol represents a signed complex relocation expression, - with the expression tree serialized in the symbol name. */ -#define BSF_SRELC (1 << 20) - - /* This symbol was created by bfd_get_synthetic_symtab. */ -#define BSF_SYNTHETIC (1 << 21) - - /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT. - The dynamic linker will compute the value of this symbol by - calling the function that it points to. BSF_FUNCTION must - also be also set. */ -#define BSF_GNU_INDIRECT_FUNCTION (1 << 22) - /* This symbol is a globally unique data object. The dynamic linker - will make sure that in the entire process there is just one symbol - with this name and type in use. BSF_OBJECT must also be set. */ -#define BSF_GNU_UNIQUE (1 << 23) - - flagword flags; - - /* A pointer to the section to which this symbol is - relative. This will always be non NULL, there are special - sections for undefined and absolute symbols. */ - struct bfd_section *section; - - /* Back end special data. */ - union - { - void *p; - bfd_vma i; - } - udata; -} -asymbol; - -#define bfd_get_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) - -bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); - -bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); - -#define bfd_is_local_label_name(abfd, name) \ - BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) - -bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); - -#define bfd_is_target_special_symbol(abfd, sym) \ - BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) - -#define bfd_canonicalize_symtab(abfd, location) \ - BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) - -bfd_boolean bfd_set_symtab - (bfd *abfd, asymbol **location, unsigned int count); - -void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); - -#define bfd_make_empty_symbol(abfd) \ - BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) - -asymbol *_bfd_generic_make_empty_symbol (bfd *); - -#define bfd_make_debug_symbol(abfd,ptr,size) \ - BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) - -int bfd_decode_symclass (asymbol *symbol); - -bfd_boolean bfd_is_undefined_symclass (int symclass); - -void bfd_symbol_info (asymbol *symbol, symbol_info *ret); - -bfd_boolean bfd_copy_private_symbol_data - (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); - -#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ - BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ - (ibfd, isymbol, obfd, osymbol)) - -/* Extracted from bfd.c. */ -enum bfd_direction - { - no_direction = 0, - read_direction = 1, - write_direction = 2, - both_direction = 3 - }; - -struct bfd -{ - /* A unique identifier of the BFD */ - unsigned int id; - - /* The filename the application opened the BFD with. */ - const char *filename; - - /* A pointer to the target jump table. */ - const struct bfd_target *xvec; - - /* The IOSTREAM, and corresponding IO vector that provide access - to the file backing the BFD. */ - void *iostream; - const struct bfd_iovec *iovec; - - /* The caching routines use these to maintain a - least-recently-used list of BFDs. */ - struct bfd *lru_prev, *lru_next; - - /* When a file is closed by the caching routines, BFD retains - state information on the file here... */ - ufile_ptr where; - - /* File modified time, if mtime_set is TRUE. */ - long mtime; - - /* Reserved for an unimplemented file locking extension. */ - int ifd; - - /* The format which belongs to the BFD. (object, core, etc.) */ - bfd_format format; - - /* The direction with which the BFD was opened. */ - enum bfd_direction direction; - - /* Format_specific flags. */ - flagword flags; - - /* Values that may appear in the flags field of a BFD. These also - appear in the object_flags field of the bfd_target structure, where - they indicate the set of flags used by that backend (not all flags - are meaningful for all object file formats) (FIXME: at the moment, - the object_flags values have mostly just been copied from backend - to another, and are not necessarily correct). */ - -#define BFD_NO_FLAGS 0x00 - - /* BFD contains relocation entries. */ -#define HAS_RELOC 0x01 - - /* BFD is directly executable. */ -#define EXEC_P 0x02 - - /* BFD has line number information (basically used for F_LNNO in a - COFF header). */ -#define HAS_LINENO 0x04 - - /* BFD has debugging information. */ -#define HAS_DEBUG 0x08 - - /* BFD has symbols. */ -#define HAS_SYMS 0x10 - - /* BFD has local symbols (basically used for F_LSYMS in a COFF - header). */ -#define HAS_LOCALS 0x20 - - /* BFD is a dynamic object. */ -#define DYNAMIC 0x40 - - /* Text section is write protected (if D_PAGED is not set, this is - like an a.out NMAGIC file) (the linker sets this by default, but - clears it for -r or -N). */ -#define WP_TEXT 0x80 - - /* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the - linker sets this by default, but clears it for -r or -n or -N). */ -#define D_PAGED 0x100 - - /* BFD is relaxable (this means that bfd_relax_section may be able to - do something) (sometimes bfd_relax_section can do something even if - this is not set). */ -#define BFD_IS_RELAXABLE 0x200 - - /* This may be set before writing out a BFD to request using a - traditional format. For example, this is used to request that when - writing out an a.out object the symbols not be hashed to eliminate - duplicates. */ -#define BFD_TRADITIONAL_FORMAT 0x400 - - /* This flag indicates that the BFD contents are actually cached - in memory. If this is set, iostream points to a bfd_in_memory - struct. */ -#define BFD_IN_MEMORY 0x800 - - /* The sections in this BFD specify a memory page. */ -#define HAS_LOAD_PAGE 0x1000 - - /* This BFD has been created by the linker and doesn't correspond - to any input file. */ -#define BFD_LINKER_CREATED 0x2000 - - /* This may be set before writing out a BFD to request that it - be written using values for UIDs, GIDs, timestamps, etc. that - will be consistent from run to run. */ -#define BFD_DETERMINISTIC_OUTPUT 0x4000 - - /* Compress sections in this BFD. */ -#define BFD_COMPRESS 0x8000 - - /* Decompress sections in this BFD. */ -#define BFD_DECOMPRESS 0x10000 - - /* BFD is a dummy, for plugins. */ -#define BFD_PLUGIN 0x20000 - - /* Flags bits to be saved in bfd_preserve_save. */ -#define BFD_FLAGS_SAVED \ - (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) - - /* Flags bits which are for BFD use only. */ -#define BFD_FLAGS_FOR_BFD_USE_MASK \ - (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ - | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) - - /* Currently my_archive is tested before adding origin to - anything. I believe that this can become always an add of - origin, with origin set to 0 for non archive files. */ - ufile_ptr origin; - - /* The origin in the archive of the proxy entry. This will - normally be the same as origin, except for thin archives, - when it will contain the current offset of the proxy in the - thin archive rather than the offset of the bfd in its actual - container. */ - ufile_ptr proxy_origin; - - /* A hash table for section names. */ - struct bfd_hash_table section_htab; - - /* Pointer to linked list of sections. */ - struct bfd_section *sections; - - /* The last section on the section list. */ - struct bfd_section *section_last; - - /* The number of sections. */ - unsigned int section_count; - - /* Stuff only useful for object files: - The start address. */ - bfd_vma start_address; - - /* Used for input and output. */ - unsigned int symcount; - - /* Symbol table for output BFD (with symcount entries). - Also used by the linker to cache input BFD symbols. */ - struct bfd_symbol **outsymbols; - - /* Used for slurped dynamic symbol tables. */ - unsigned int dynsymcount; - - /* Pointer to structure which contains architecture information. */ - const struct bfd_arch_info *arch_info; - - /* Stuff only useful for archives. */ - void *arelt_data; - struct bfd *my_archive; /* The containing archive BFD. */ - struct bfd *archive_next; /* The next BFD in the archive. */ - struct bfd *archive_head; /* The first BFD in the archive. */ - struct bfd *nested_archives; /* List of nested archive in a flattened - thin archive. */ - - /* A chain of BFD structures involved in a link. */ - struct bfd *link_next; - - /* A field used by _bfd_generic_link_add_archive_symbols. This will - be used only for archive elements. */ - int archive_pass; - - /* Used by the back end to hold private data. */ - union - { - struct aout_data_struct *aout_data; - struct artdata *aout_ar_data; - struct _oasys_data *oasys_obj_data; - struct _oasys_ar_data *oasys_ar_data; - struct coff_tdata *coff_obj_data; - struct pe_tdata *pe_obj_data; - struct xcoff_tdata *xcoff_obj_data; - struct ecoff_tdata *ecoff_obj_data; - struct ieee_data_struct *ieee_data; - struct ieee_ar_data_struct *ieee_ar_data; - struct srec_data_struct *srec_data; - struct verilog_data_struct *verilog_data; - struct ihex_data_struct *ihex_data; - struct tekhex_data_struct *tekhex_data; - struct elf_obj_tdata *elf_obj_data; - struct nlm_obj_tdata *nlm_obj_data; - struct bout_data_struct *bout_data; - struct mmo_data_struct *mmo_data; - struct sun_core_struct *sun_core_data; - struct sco5_core_struct *sco5_core_data; - struct trad_core_struct *trad_core_data; - struct som_data_struct *som_data; - struct hpux_core_struct *hpux_core_data; - struct hppabsd_core_struct *hppabsd_core_data; - struct sgi_core_struct *sgi_core_data; - struct lynx_core_struct *lynx_core_data; - struct osf_core_struct *osf_core_data; - struct cisco_core_struct *cisco_core_data; - struct versados_data_struct *versados_data; - struct netbsd_core_struct *netbsd_core_data; - struct mach_o_data_struct *mach_o_data; - struct mach_o_fat_data_struct *mach_o_fat_data; - struct plugin_data_struct *plugin_data; - struct bfd_pef_data_struct *pef_data; - struct bfd_pef_xlib_data_struct *pef_xlib_data; - struct bfd_sym_data_struct *sym_data; - void *any; - } - tdata; - - /* Used by the application to hold private data. */ - void *usrdata; - - /* Where all the allocated stuff under this BFD goes. This is a - struct objalloc *, but we use void * to avoid requiring the inclusion - of objalloc.h. */ - void *memory; - - /* Is the file descriptor being cached? That is, can it be closed as - needed, and re-opened when accessed later? */ - unsigned int cacheable : 1; - - /* Marks whether there was a default target specified when the - BFD was opened. This is used to select which matching algorithm - to use to choose the back end. */ - unsigned int target_defaulted : 1; - - /* ... and here: (``once'' means at least once). */ - unsigned int opened_once : 1; - - /* Set if we have a locally maintained mtime value, rather than - getting it from the file each time. */ - unsigned int mtime_set : 1; - - /* Flag set if symbols from this BFD should not be exported. */ - unsigned int no_export : 1; - - /* Remember when output has begun, to stop strange things - from happening. */ - unsigned int output_has_begun : 1; - - /* Have archive map. */ - unsigned int has_armap : 1; - - /* Set if this is a thin archive. */ - unsigned int is_thin_archive : 1; - - /* Set if only required symbols should be added in the link hash table for - this object. Used by VMS linkers. */ - unsigned int selective_search : 1; -}; - -typedef enum bfd_error -{ - bfd_error_no_error = 0, - bfd_error_system_call, - bfd_error_invalid_target, - bfd_error_wrong_format, - bfd_error_wrong_object_format, - bfd_error_invalid_operation, - bfd_error_no_memory, - bfd_error_no_symbols, - bfd_error_no_armap, - bfd_error_no_more_archived_files, - bfd_error_malformed_archive, - bfd_error_file_not_recognized, - bfd_error_file_ambiguously_recognized, - bfd_error_no_contents, - bfd_error_nonrepresentable_section, - bfd_error_no_debug_section, - bfd_error_bad_value, - bfd_error_file_truncated, - bfd_error_file_too_big, - bfd_error_on_input, - bfd_error_invalid_error_code -} -bfd_error_type; - -bfd_error_type bfd_get_error (void); - -void bfd_set_error (bfd_error_type error_tag, ...); - -const char *bfd_errmsg (bfd_error_type error_tag); - -void bfd_perror (const char *message); - -typedef void (*bfd_error_handler_type) (const char *, ...); - -bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); - -void bfd_set_error_program_name (const char *); - -bfd_error_handler_type bfd_get_error_handler (void); - -long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); - -long bfd_canonicalize_reloc - (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); - -void bfd_set_reloc - (bfd *abfd, asection *sec, arelent **rel, unsigned int count); - -bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); - -int bfd_get_arch_size (bfd *abfd); - -int bfd_get_sign_extend_vma (bfd *abfd); - -bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); - -unsigned int bfd_get_gp_size (bfd *abfd); - -void bfd_set_gp_size (bfd *abfd, unsigned int i); - -bfd_vma bfd_scan_vma (const char *string, const char **end, int base); - -bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); - -#define bfd_copy_private_header_data(ibfd, obfd) \ - BFD_SEND (obfd, _bfd_copy_private_header_data, \ - (ibfd, obfd)) -bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); - -#define bfd_copy_private_bfd_data(ibfd, obfd) \ - BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ - (ibfd, obfd)) -bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); - -#define bfd_merge_private_bfd_data(ibfd, obfd) \ - BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ - (ibfd, obfd)) -bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); - -#define bfd_set_private_flags(abfd, flags) \ - BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) -#define bfd_sizeof_headers(abfd, info) \ - BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) - -#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ - BFD_SEND (abfd, _bfd_find_nearest_line, \ - (abfd, sec, syms, off, file, func, line)) - -#define bfd_find_line(abfd, syms, sym, file, line) \ - BFD_SEND (abfd, _bfd_find_line, \ - (abfd, syms, sym, file, line)) - -#define bfd_find_inliner_info(abfd, file, func, line) \ - BFD_SEND (abfd, _bfd_find_inliner_info, \ - (abfd, file, func, line)) - -#define bfd_debug_info_start(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) - -#define bfd_debug_info_end(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) - -#define bfd_debug_info_accumulate(abfd, section) \ - BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) - -#define bfd_stat_arch_elt(abfd, stat) \ - BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) - -#define bfd_update_armap_timestamp(abfd) \ - BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) - -#define bfd_set_arch_mach(abfd, arch, mach)\ - BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) - -#define bfd_relax_section(abfd, section, link_info, again) \ - BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) - -#define bfd_gc_sections(abfd, link_info) \ - BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) - -#define bfd_lookup_section_flags(link_info, flag_info) \ - BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info)) - -#define bfd_merge_sections(abfd, link_info) \ - BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) - -#define bfd_is_group_section(abfd, sec) \ - BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) - -#define bfd_discard_group(abfd, sec) \ - BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) - -#define bfd_link_hash_table_create(abfd) \ - BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) - -#define bfd_link_hash_table_free(abfd, hash) \ - BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) - -#define bfd_link_add_symbols(abfd, info) \ - BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) - -#define bfd_link_just_syms(abfd, sec, info) \ - BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) - -#define bfd_final_link(abfd, info) \ - BFD_SEND (abfd, _bfd_final_link, (abfd, info)) - -#define bfd_free_cached_info(abfd) \ - BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) - -#define bfd_get_dynamic_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) - -#define bfd_print_private_bfd_data(abfd, file)\ - BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) - -#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) - -#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ - BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ - dyncount, dynsyms, ret)) - -#define bfd_get_dynamic_reloc_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) - -#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) - -extern bfd_byte *bfd_get_relocated_section_contents - (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, - bfd_boolean, asymbol **); - -bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); - -struct bfd_preserve -{ - void *marker; - void *tdata; - flagword flags; - const struct bfd_arch_info *arch_info; - struct bfd_section *sections; - struct bfd_section *section_last; - unsigned int section_count; - struct bfd_hash_table section_htab; -}; - -bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); - -void bfd_preserve_restore (bfd *, struct bfd_preserve *); - -void bfd_preserve_finish (bfd *, struct bfd_preserve *); - -bfd_vma bfd_emul_get_maxpagesize (const char *); - -void bfd_emul_set_maxpagesize (const char *, bfd_vma); - -bfd_vma bfd_emul_get_commonpagesize (const char *); - -void bfd_emul_set_commonpagesize (const char *, bfd_vma); - -char *bfd_demangle (bfd *, const char *, int); - -/* Extracted from archive.c. */ -symindex bfd_get_next_mapent - (bfd *abfd, symindex previous, carsym **sym); - -bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); - -bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); - -/* Extracted from corefile.c. */ -const char *bfd_core_file_failing_command (bfd *abfd); - -int bfd_core_file_failing_signal (bfd *abfd); - -int bfd_core_file_pid (bfd *abfd); - -bfd_boolean core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -bfd_boolean generic_core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -/* Extracted from targets.c. */ -#define BFD_SEND(bfd, message, arglist) \ - ((*((bfd)->xvec->message)) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND -#define BFD_SEND(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - ((*((bfd)->xvec->message)) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND_FMT -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif - -enum bfd_flavour -{ - bfd_target_unknown_flavour, - bfd_target_aout_flavour, - bfd_target_coff_flavour, - bfd_target_ecoff_flavour, - bfd_target_xcoff_flavour, - bfd_target_elf_flavour, - bfd_target_ieee_flavour, - bfd_target_nlm_flavour, - bfd_target_oasys_flavour, - bfd_target_tekhex_flavour, - bfd_target_srec_flavour, - bfd_target_verilog_flavour, - bfd_target_ihex_flavour, - bfd_target_som_flavour, - bfd_target_os9k_flavour, - bfd_target_versados_flavour, - bfd_target_msdos_flavour, - bfd_target_ovax_flavour, - bfd_target_evax_flavour, - bfd_target_mmo_flavour, - bfd_target_mach_o_flavour, - bfd_target_pef_flavour, - bfd_target_pef_xlib_flavour, - bfd_target_sym_flavour -}; - -enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; - -/* Forward declaration. */ -typedef struct bfd_link_info _bfd_link_info; - -/* Forward declaration. */ -typedef struct flag_info flag_info; - -typedef struct bfd_target -{ - /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ - char *name; - - /* The "flavour" of a back end is a general indication about - the contents of a file. */ - enum bfd_flavour flavour; - - /* The order of bytes within the data area of a file. */ - enum bfd_endian byteorder; - - /* The order of bytes within the header parts of a file. */ - enum bfd_endian header_byteorder; - - /* A mask of all the flags which an executable may have set - - from the set <>, <>, ...<>. */ - flagword object_flags; - - /* A mask of all the flags which a section may have set - from - the set <>, <>, ...<>. */ - flagword section_flags; - - /* The character normally found at the front of a symbol. - (if any), perhaps `_'. */ - char symbol_leading_char; - - /* The pad character for file names within an archive header. */ - char ar_pad_char; - - /* The maximum number of characters in an archive header. */ - unsigned char ar_max_namelen; - - /* How well this target matches, used to select between various - possible targets when more than one target matches. */ - unsigned char match_priority; - - /* Entries for byte swapping for data. These are different from the - other entry points, since they don't take a BFD as the first argument. - Certain other handlers could do the same. */ - bfd_uint64_t (*bfd_getx64) (const void *); - bfd_int64_t (*bfd_getx_signed_64) (const void *); - void (*bfd_putx64) (bfd_uint64_t, void *); - bfd_vma (*bfd_getx32) (const void *); - bfd_signed_vma (*bfd_getx_signed_32) (const void *); - void (*bfd_putx32) (bfd_vma, void *); - bfd_vma (*bfd_getx16) (const void *); - bfd_signed_vma (*bfd_getx_signed_16) (const void *); - void (*bfd_putx16) (bfd_vma, void *); - - /* Byte swapping for the headers. */ - bfd_uint64_t (*bfd_h_getx64) (const void *); - bfd_int64_t (*bfd_h_getx_signed_64) (const void *); - void (*bfd_h_putx64) (bfd_uint64_t, void *); - bfd_vma (*bfd_h_getx32) (const void *); - bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); - void (*bfd_h_putx32) (bfd_vma, void *); - bfd_vma (*bfd_h_getx16) (const void *); - bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); - void (*bfd_h_putx16) (bfd_vma, void *); - - /* Format dependent routines: these are vectors of entry points - within the target vector structure, one for each format to check. */ - - /* Check the format of a file being read. Return a <> or zero. */ - const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); - - /* Set the format of a file being written. */ - bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); - - /* Write cached information into a file being written, at <>. */ - bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); - - - /* Generic entry points. */ -#define BFD_JUMP_TABLE_GENERIC(NAME) \ - NAME##_close_and_cleanup, \ - NAME##_bfd_free_cached_info, \ - NAME##_new_section_hook, \ - NAME##_get_section_contents, \ - NAME##_get_section_contents_in_window - - /* Called when the BFD is being closed to do any necessary cleanup. */ - bfd_boolean (*_close_and_cleanup) (bfd *); - /* Ask the BFD to free all cached information. */ - bfd_boolean (*_bfd_free_cached_info) (bfd *); - /* Called when a new section is created. */ - bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); - /* Read the contents of a section. */ - bfd_boolean (*_bfd_get_section_contents) - (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); - bfd_boolean (*_bfd_get_section_contents_in_window) - (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); - - /* Entry points to copy private data. */ -#define BFD_JUMP_TABLE_COPY(NAME) \ - NAME##_bfd_copy_private_bfd_data, \ - NAME##_bfd_merge_private_bfd_data, \ - _bfd_generic_init_private_section_data, \ - NAME##_bfd_copy_private_section_data, \ - NAME##_bfd_copy_private_symbol_data, \ - NAME##_bfd_copy_private_header_data, \ - NAME##_bfd_set_private_flags, \ - NAME##_bfd_print_private_bfd_data - - /* Called to copy BFD general private data from one object file - to another. */ - bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); - /* Called to merge BFD general private data from one object file - to a common output file when linking. */ - bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); - /* Called to initialize BFD private section data from one object file - to another. */ -#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ - BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) - bfd_boolean (*_bfd_init_private_section_data) - (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); - /* Called to copy BFD private section data from one object file - to another. */ - bfd_boolean (*_bfd_copy_private_section_data) - (bfd *, sec_ptr, bfd *, sec_ptr); - /* Called to copy BFD private symbol data from one symbol - to another. */ - bfd_boolean (*_bfd_copy_private_symbol_data) - (bfd *, asymbol *, bfd *, asymbol *); - /* Called to copy BFD private header data from one object file - to another. */ - bfd_boolean (*_bfd_copy_private_header_data) - (bfd *, bfd *); - /* Called to set private backend flags. */ - bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); - - /* Called to print private BFD data. */ - bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); - - /* Core file entry points. */ -#define BFD_JUMP_TABLE_CORE(NAME) \ - NAME##_core_file_failing_command, \ - NAME##_core_file_failing_signal, \ - NAME##_core_file_matches_executable_p, \ - NAME##_core_file_pid - - char * (*_core_file_failing_command) (bfd *); - int (*_core_file_failing_signal) (bfd *); - bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); - int (*_core_file_pid) (bfd *); - - /* Archive entry points. */ -#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ - NAME##_slurp_armap, \ - NAME##_slurp_extended_name_table, \ - NAME##_construct_extended_name_table, \ - NAME##_truncate_arname, \ - NAME##_write_armap, \ - NAME##_read_ar_hdr, \ - NAME##_write_ar_hdr, \ - NAME##_openr_next_archived_file, \ - NAME##_get_elt_at_index, \ - NAME##_generic_stat_arch_elt, \ - NAME##_update_armap_timestamp - - bfd_boolean (*_bfd_slurp_armap) (bfd *); - bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); - bfd_boolean (*_bfd_construct_extended_name_table) - (bfd *, char **, bfd_size_type *, const char **); - void (*_bfd_truncate_arname) (bfd *, const char *, char *); - bfd_boolean (*write_armap) - (bfd *, unsigned int, struct orl *, unsigned int, int); - void * (*_bfd_read_ar_hdr_fn) (bfd *); - bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *); - bfd * (*openr_next_archived_file) (bfd *, bfd *); -#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) - bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); - int (*_bfd_stat_arch_elt) (bfd *, struct stat *); - bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); - - /* Entry points used for symbols. */ -#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ - NAME##_get_symtab_upper_bound, \ - NAME##_canonicalize_symtab, \ - NAME##_make_empty_symbol, \ - NAME##_print_symbol, \ - NAME##_get_symbol_info, \ - NAME##_bfd_is_local_label_name, \ - NAME##_bfd_is_target_special_symbol, \ - NAME##_get_lineno, \ - NAME##_find_nearest_line, \ - _bfd_generic_find_line, \ - NAME##_find_inliner_info, \ - NAME##_bfd_make_debug_symbol, \ - NAME##_read_minisymbols, \ - NAME##_minisymbol_to_symbol - - long (*_bfd_get_symtab_upper_bound) (bfd *); - long (*_bfd_canonicalize_symtab) - (bfd *, struct bfd_symbol **); - struct bfd_symbol * - (*_bfd_make_empty_symbol) (bfd *); - void (*_bfd_print_symbol) - (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); -#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) - void (*_bfd_get_symbol_info) - (bfd *, struct bfd_symbol *, symbol_info *); -#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) - bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); - bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); - alent * (*_get_lineno) (bfd *, struct bfd_symbol *); - bfd_boolean (*_bfd_find_nearest_line) - (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, - const char **, const char **, unsigned int *); - bfd_boolean (*_bfd_find_line) - (bfd *, struct bfd_symbol **, struct bfd_symbol *, - const char **, unsigned int *); - bfd_boolean (*_bfd_find_inliner_info) - (bfd *, const char **, const char **, unsigned int *); - /* Back-door to allow format-aware applications to create debug symbols - while using BFD for everything else. Currently used by the assembler - when creating COFF files. */ - asymbol * (*_bfd_make_debug_symbol) - (bfd *, void *, unsigned long size); -#define bfd_read_minisymbols(b, d, m, s) \ - BFD_SEND (b, _read_minisymbols, (b, d, m, s)) - long (*_read_minisymbols) - (bfd *, bfd_boolean, void **, unsigned int *); -#define bfd_minisymbol_to_symbol(b, d, m, f) \ - BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) - asymbol * (*_minisymbol_to_symbol) - (bfd *, bfd_boolean, const void *, asymbol *); - - /* Routines for relocs. */ -#define BFD_JUMP_TABLE_RELOCS(NAME) \ - NAME##_get_reloc_upper_bound, \ - NAME##_canonicalize_reloc, \ - NAME##_bfd_reloc_type_lookup, \ - NAME##_bfd_reloc_name_lookup - - long (*_get_reloc_upper_bound) (bfd *, sec_ptr); - long (*_bfd_canonicalize_reloc) - (bfd *, sec_ptr, arelent **, struct bfd_symbol **); - /* See documentation on reloc types. */ - reloc_howto_type * - (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); - reloc_howto_type * - (*reloc_name_lookup) (bfd *, const char *); - - - /* Routines used when writing an object file. */ -#define BFD_JUMP_TABLE_WRITE(NAME) \ - NAME##_set_arch_mach, \ - NAME##_set_section_contents - - bfd_boolean (*_bfd_set_arch_mach) - (bfd *, enum bfd_architecture, unsigned long); - bfd_boolean (*_bfd_set_section_contents) - (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); - - /* Routines used by the linker. */ -#define BFD_JUMP_TABLE_LINK(NAME) \ - NAME##_sizeof_headers, \ - NAME##_bfd_get_relocated_section_contents, \ - NAME##_bfd_relax_section, \ - NAME##_bfd_link_hash_table_create, \ - NAME##_bfd_link_hash_table_free, \ - NAME##_bfd_link_add_symbols, \ - NAME##_bfd_link_just_syms, \ - NAME##_bfd_copy_link_hash_symbol_type, \ - NAME##_bfd_final_link, \ - NAME##_bfd_link_split_section, \ - NAME##_bfd_gc_sections, \ - NAME##_bfd_lookup_section_flags, \ - NAME##_bfd_merge_sections, \ - NAME##_bfd_is_group_section, \ - NAME##_bfd_discard_group, \ - NAME##_section_already_linked, \ - NAME##_bfd_define_common_symbol - - int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *); - bfd_byte * (*_bfd_get_relocated_section_contents) - (bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, bfd_boolean, struct bfd_symbol **); - - bfd_boolean (*_bfd_relax_section) - (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); - - /* Create a hash table for the linker. Different backends store - different information in this table. */ - struct bfd_link_hash_table * - (*_bfd_link_hash_table_create) (bfd *); - - /* Release the memory associated with the linker hash table. */ - void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); - - /* Add symbols from this object file into the hash table. */ - bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); - - /* Indicate that we are only retrieving symbol values from this section. */ - void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); - - /* Copy the symbol type of a linker hash table entry. */ -#define bfd_copy_link_hash_symbol_type(b, t, f) \ - BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) - void (*_bfd_copy_link_hash_symbol_type) - (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); - - /* Do a link based on the link_order structures attached to each - section of the BFD. */ - bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); - - /* Should this section be split up into smaller pieces during linking. */ - bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); - - /* Remove sections that are not referenced from the output. */ - bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); - - /* Sets the bitmask of allowed and disallowed section flags. */ - void (*_bfd_lookup_section_flags) (struct bfd_link_info *, - struct flag_info *); - - /* Attempt to merge SEC_MERGE sections. */ - bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); - - /* Is this section a member of a group? */ - bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); - - /* Discard members of a group. */ - bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); - - /* Check if SEC has been already linked during a reloceatable or - final link. */ - bfd_boolean (*_section_already_linked) (bfd *, asection *, - struct bfd_link_info *); - - /* Define a common symbol. */ - bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *, - struct bfd_link_hash_entry *); - - /* Routines to handle dynamic symbols and relocs. */ -#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ - NAME##_get_dynamic_symtab_upper_bound, \ - NAME##_canonicalize_dynamic_symtab, \ - NAME##_get_synthetic_symtab, \ - NAME##_get_dynamic_reloc_upper_bound, \ - NAME##_canonicalize_dynamic_reloc - - /* Get the amount of memory required to hold the dynamic symbols. */ - long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); - /* Read in the dynamic symbols. */ - long (*_bfd_canonicalize_dynamic_symtab) - (bfd *, struct bfd_symbol **); - /* Create synthetized symbols. */ - long (*_bfd_get_synthetic_symtab) - (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, - struct bfd_symbol **); - /* Get the amount of memory required to hold the dynamic relocs. */ - long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); - /* Read in the dynamic relocs. */ - long (*_bfd_canonicalize_dynamic_reloc) - (bfd *, arelent **, struct bfd_symbol **); - - /* Opposite endian version of this target. */ - const struct bfd_target * alternative_target; - - /* Data for use by back-end routines, which isn't - generic enough to belong in this structure. */ - const void *backend_data; - -} bfd_target; - -bfd_boolean bfd_set_default_target (const char *name); - -const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); - -const bfd_target *bfd_get_target_info (const char *target_name, - bfd *abfd, - bfd_boolean *is_bigendian, - int *underscoring, - const char **def_target_arch); -const char ** bfd_target_list (void); - -const bfd_target *bfd_search_for_target - (int (*search_func) (const bfd_target *, void *), - void *); - -/* Extracted from format.c. */ -bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); - -bfd_boolean bfd_check_format_matches - (bfd *abfd, bfd_format format, char ***matching); - -bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); - -const char *bfd_format_string (bfd_format format); - -/* Extracted from linker.c. */ -bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); - -#define bfd_link_split_section(abfd, sec) \ - BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) - -bfd_boolean bfd_section_already_linked (bfd *abfd, - asection *sec, - struct bfd_link_info *info); - -#define bfd_section_already_linked(abfd, sec, info) \ - BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) - -bfd_boolean bfd_generic_define_common_symbol - (bfd *output_bfd, struct bfd_link_info *info, - struct bfd_link_hash_entry *h); - -#define bfd_define_common_symbol(output_bfd, info, h) \ - BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) - -struct bfd_elf_version_tree * bfd_find_version_for_sym - (struct bfd_elf_version_tree *verdefs, - const char *sym_name, bfd_boolean *hide); - -bfd_boolean bfd_hide_sym_by_version - (struct bfd_elf_version_tree *verdefs, const char *sym_name); - -/* Extracted from simple.c. */ -bfd_byte *bfd_simple_get_relocated_section_contents - (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); - -/* Extracted from compress.c. */ -bfd_boolean bfd_compress_section_contents - (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer, - bfd_size_type uncompressed_size); - -bfd_boolean bfd_get_full_section_contents - (bfd *abfd, asection *section, bfd_byte **ptr); - -bfd_boolean bfd_is_section_compressed - (bfd *abfd, asection *section); - -bfd_boolean bfd_init_section_decompress_status - (bfd *abfd, asection *section); - -bfd_boolean bfd_init_section_compress_status - (bfd *abfd, asection *section); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/contrib/binutils-2.22/bfd/bfd.c b/contrib/binutils-2.22/bfd/bfd.c deleted file mode 100644 index 7c14c7a00a..0000000000 --- a/contrib/binutils-2.22/bfd/bfd.c +++ /dev/null @@ -1,1941 +0,0 @@ -/* Generic BFD library interface and support routines. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - <> - - A BFD has type <>; objects of this type are the - cornerstone of any application using BFD. Using BFD - consists of making references though the BFD and to data in the BFD. - - Here is the structure that defines the type <>. It - contains the major data about the file and pointers - to the rest of the data. - -CODE_FRAGMENT -. -.enum bfd_direction -. { -. no_direction = 0, -. read_direction = 1, -. write_direction = 2, -. both_direction = 3 -. }; -. -.struct bfd -.{ -. {* A unique identifier of the BFD *} -. unsigned int id; -. -. {* The filename the application opened the BFD with. *} -. const char *filename; -. -. {* A pointer to the target jump table. *} -. const struct bfd_target *xvec; -. -. {* The IOSTREAM, and corresponding IO vector that provide access -. to the file backing the BFD. *} -. void *iostream; -. const struct bfd_iovec *iovec; -. -. {* The caching routines use these to maintain a -. least-recently-used list of BFDs. *} -. struct bfd *lru_prev, *lru_next; -. -. {* When a file is closed by the caching routines, BFD retains -. state information on the file here... *} -. ufile_ptr where; -. -. {* File modified time, if mtime_set is TRUE. *} -. long mtime; -. -. {* Reserved for an unimplemented file locking extension. *} -. int ifd; -. -. {* The format which belongs to the BFD. (object, core, etc.) *} -. bfd_format format; -. -. {* The direction with which the BFD was opened. *} -. enum bfd_direction direction; -. -. {* Format_specific flags. *} -. flagword flags; -. -. {* Values that may appear in the flags field of a BFD. These also -. appear in the object_flags field of the bfd_target structure, where -. they indicate the set of flags used by that backend (not all flags -. are meaningful for all object file formats) (FIXME: at the moment, -. the object_flags values have mostly just been copied from backend -. to another, and are not necessarily correct). *} -. -.#define BFD_NO_FLAGS 0x00 -. -. {* BFD contains relocation entries. *} -.#define HAS_RELOC 0x01 -. -. {* BFD is directly executable. *} -.#define EXEC_P 0x02 -. -. {* BFD has line number information (basically used for F_LNNO in a -. COFF header). *} -.#define HAS_LINENO 0x04 -. -. {* BFD has debugging information. *} -.#define HAS_DEBUG 0x08 -. -. {* BFD has symbols. *} -.#define HAS_SYMS 0x10 -. -. {* BFD has local symbols (basically used for F_LSYMS in a COFF -. header). *} -.#define HAS_LOCALS 0x20 -. -. {* BFD is a dynamic object. *} -.#define DYNAMIC 0x40 -. -. {* Text section is write protected (if D_PAGED is not set, this is -. like an a.out NMAGIC file) (the linker sets this by default, but -. clears it for -r or -N). *} -.#define WP_TEXT 0x80 -. -. {* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the -. linker sets this by default, but clears it for -r or -n or -N). *} -.#define D_PAGED 0x100 -. -. {* BFD is relaxable (this means that bfd_relax_section may be able to -. do something) (sometimes bfd_relax_section can do something even if -. this is not set). *} -.#define BFD_IS_RELAXABLE 0x200 -. -. {* This may be set before writing out a BFD to request using a -. traditional format. For example, this is used to request that when -. writing out an a.out object the symbols not be hashed to eliminate -. duplicates. *} -.#define BFD_TRADITIONAL_FORMAT 0x400 -. -. {* This flag indicates that the BFD contents are actually cached -. in memory. If this is set, iostream points to a bfd_in_memory -. struct. *} -.#define BFD_IN_MEMORY 0x800 -. -. {* The sections in this BFD specify a memory page. *} -.#define HAS_LOAD_PAGE 0x1000 -. -. {* This BFD has been created by the linker and doesn't correspond -. to any input file. *} -.#define BFD_LINKER_CREATED 0x2000 -. -. {* This may be set before writing out a BFD to request that it -. be written using values for UIDs, GIDs, timestamps, etc. that -. will be consistent from run to run. *} -.#define BFD_DETERMINISTIC_OUTPUT 0x4000 -. -. {* Compress sections in this BFD. *} -.#define BFD_COMPRESS 0x8000 -. -. {* Decompress sections in this BFD. *} -.#define BFD_DECOMPRESS 0x10000 -. -. {* BFD is a dummy, for plugins. *} -.#define BFD_PLUGIN 0x20000 -. -. {* Flags bits to be saved in bfd_preserve_save. *} -.#define BFD_FLAGS_SAVED \ -. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) -. -. {* Flags bits which are for BFD use only. *} -.#define BFD_FLAGS_FOR_BFD_USE_MASK \ -. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ -. | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) -. -. {* Currently my_archive is tested before adding origin to -. anything. I believe that this can become always an add of -. origin, with origin set to 0 for non archive files. *} -. ufile_ptr origin; -. -. {* The origin in the archive of the proxy entry. This will -. normally be the same as origin, except for thin archives, -. when it will contain the current offset of the proxy in the -. thin archive rather than the offset of the bfd in its actual -. container. *} -. ufile_ptr proxy_origin; -. -. {* A hash table for section names. *} -. struct bfd_hash_table section_htab; -. -. {* Pointer to linked list of sections. *} -. struct bfd_section *sections; -. -. {* The last section on the section list. *} -. struct bfd_section *section_last; -. -. {* The number of sections. *} -. unsigned int section_count; -. -. {* Stuff only useful for object files: -. The start address. *} -. bfd_vma start_address; -. -. {* Used for input and output. *} -. unsigned int symcount; -. -. {* Symbol table for output BFD (with symcount entries). -. Also used by the linker to cache input BFD symbols. *} -. struct bfd_symbol **outsymbols; -. -. {* Used for slurped dynamic symbol tables. *} -. unsigned int dynsymcount; -. -. {* Pointer to structure which contains architecture information. *} -. const struct bfd_arch_info *arch_info; -. -. {* Stuff only useful for archives. *} -. void *arelt_data; -. struct bfd *my_archive; {* The containing archive BFD. *} -. struct bfd *archive_next; {* The next BFD in the archive. *} -. struct bfd *archive_head; {* The first BFD in the archive. *} -. struct bfd *nested_archives; {* List of nested archive in a flattened -. thin archive. *} -. -. {* A chain of BFD structures involved in a link. *} -. struct bfd *link_next; -. -. {* A field used by _bfd_generic_link_add_archive_symbols. This will -. be used only for archive elements. *} -. int archive_pass; -. -. {* Used by the back end to hold private data. *} -. union -. { -. struct aout_data_struct *aout_data; -. struct artdata *aout_ar_data; -. struct _oasys_data *oasys_obj_data; -. struct _oasys_ar_data *oasys_ar_data; -. struct coff_tdata *coff_obj_data; -. struct pe_tdata *pe_obj_data; -. struct xcoff_tdata *xcoff_obj_data; -. struct ecoff_tdata *ecoff_obj_data; -. struct ieee_data_struct *ieee_data; -. struct ieee_ar_data_struct *ieee_ar_data; -. struct srec_data_struct *srec_data; -. struct verilog_data_struct *verilog_data; -. struct ihex_data_struct *ihex_data; -. struct tekhex_data_struct *tekhex_data; -. struct elf_obj_tdata *elf_obj_data; -. struct nlm_obj_tdata *nlm_obj_data; -. struct bout_data_struct *bout_data; -. struct mmo_data_struct *mmo_data; -. struct sun_core_struct *sun_core_data; -. struct sco5_core_struct *sco5_core_data; -. struct trad_core_struct *trad_core_data; -. struct som_data_struct *som_data; -. struct hpux_core_struct *hpux_core_data; -. struct hppabsd_core_struct *hppabsd_core_data; -. struct sgi_core_struct *sgi_core_data; -. struct lynx_core_struct *lynx_core_data; -. struct osf_core_struct *osf_core_data; -. struct cisco_core_struct *cisco_core_data; -. struct versados_data_struct *versados_data; -. struct netbsd_core_struct *netbsd_core_data; -. struct mach_o_data_struct *mach_o_data; -. struct mach_o_fat_data_struct *mach_o_fat_data; -. struct plugin_data_struct *plugin_data; -. struct bfd_pef_data_struct *pef_data; -. struct bfd_pef_xlib_data_struct *pef_xlib_data; -. struct bfd_sym_data_struct *sym_data; -. void *any; -. } -. tdata; -. -. {* Used by the application to hold private data. *} -. void *usrdata; -. -. {* Where all the allocated stuff under this BFD goes. This is a -. struct objalloc *, but we use void * to avoid requiring the inclusion -. of objalloc.h. *} -. void *memory; -. -. {* Is the file descriptor being cached? That is, can it be closed as -. needed, and re-opened when accessed later? *} -. unsigned int cacheable : 1; -. -. {* Marks whether there was a default target specified when the -. BFD was opened. This is used to select which matching algorithm -. to use to choose the back end. *} -. unsigned int target_defaulted : 1; -. -. {* ... and here: (``once'' means at least once). *} -. unsigned int opened_once : 1; -. -. {* Set if we have a locally maintained mtime value, rather than -. getting it from the file each time. *} -. unsigned int mtime_set : 1; -. -. {* Flag set if symbols from this BFD should not be exported. *} -. unsigned int no_export : 1; -. -. {* Remember when output has begun, to stop strange things -. from happening. *} -. unsigned int output_has_begun : 1; -. -. {* Have archive map. *} -. unsigned int has_armap : 1; -. -. {* Set if this is a thin archive. *} -. unsigned int is_thin_archive : 1; -. -. {* Set if only required symbols should be added in the link hash table for -. this object. Used by VMS linkers. *} -. unsigned int selective_search : 1; -.}; -. -*/ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "bfdver.h" -#include "libiberty.h" -#include "demangle.h" -#include "safe-ctype.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "libcoff.h" -#include "libecoff.h" -#undef obj_symbols -#include "elf-bfd.h" - -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif - - -/* provide storage for subsystem, stack and heap data which may have been - passed in on the command line. Ld puts this data into a bfd_link_info - struct which ultimately gets passed in to the bfd. When it arrives, copy - it to the following struct so that the data will be available in coffcode.h - where it is needed. The typedef's used are defined in bfd.h */ - -/* -SECTION - Error reporting - - Most BFD functions return nonzero on success (check their - individual documentation for precise semantics). On an error, - they call <> to set an error condition that callers - can check by calling <>. - If that returns <>, then check - <>. - - The easiest way to report a BFD error to the user is to - use <>. - -SUBSECTION - Type <> - - The values returned by <> are defined by the - enumerated type <>. - -CODE_FRAGMENT -. -.typedef enum bfd_error -.{ -. bfd_error_no_error = 0, -. bfd_error_system_call, -. bfd_error_invalid_target, -. bfd_error_wrong_format, -. bfd_error_wrong_object_format, -. bfd_error_invalid_operation, -. bfd_error_no_memory, -. bfd_error_no_symbols, -. bfd_error_no_armap, -. bfd_error_no_more_archived_files, -. bfd_error_malformed_archive, -. bfd_error_file_not_recognized, -. bfd_error_file_ambiguously_recognized, -. bfd_error_no_contents, -. bfd_error_nonrepresentable_section, -. bfd_error_no_debug_section, -. bfd_error_bad_value, -. bfd_error_file_truncated, -. bfd_error_file_too_big, -. bfd_error_on_input, -. bfd_error_invalid_error_code -.} -.bfd_error_type; -. -*/ - -static bfd_error_type bfd_error = bfd_error_no_error; -static bfd *input_bfd = NULL; -static bfd_error_type input_error = bfd_error_no_error; - -const char *const bfd_errmsgs[] = -{ - N_("No error"), - N_("System call error"), - N_("Invalid bfd target"), - N_("File in wrong format"), - N_("Archive object file in wrong format"), - N_("Invalid operation"), - N_("Memory exhausted"), - N_("No symbols"), - N_("Archive has no index; run ranlib to add one"), - N_("No more archived files"), - N_("Malformed archive"), - N_("File format not recognized"), - N_("File format is ambiguous"), - N_("Section has no contents"), - N_("Nonrepresentable section on output"), - N_("Symbol needs debug section which does not exist"), - N_("Bad value"), - N_("File truncated"), - N_("File too big"), - N_("Error reading %s: %s"), - N_("#") -}; - -/* -FUNCTION - bfd_get_error - -SYNOPSIS - bfd_error_type bfd_get_error (void); - -DESCRIPTION - Return the current BFD error condition. -*/ - -bfd_error_type -bfd_get_error (void) -{ - return bfd_error; -} - -/* -FUNCTION - bfd_set_error - -SYNOPSIS - void bfd_set_error (bfd_error_type error_tag, ...); - -DESCRIPTION - Set the BFD error condition to be @var{error_tag}. - If @var{error_tag} is bfd_error_on_input, then this function - takes two more parameters, the input bfd where the error - occurred, and the bfd_error_type error. -*/ - -void -bfd_set_error (bfd_error_type error_tag, ...) -{ - bfd_error = error_tag; - if (error_tag == bfd_error_on_input) - { - /* This is an error that occurred during bfd_close when - writing an archive, but on one of the input files. */ - va_list ap; - - va_start (ap, error_tag); - input_bfd = va_arg (ap, bfd *); - input_error = (bfd_error_type) va_arg (ap, int); - if (input_error >= bfd_error_on_input) - abort (); - va_end (ap); - } -} - -/* -FUNCTION - bfd_errmsg - -SYNOPSIS - const char *bfd_errmsg (bfd_error_type error_tag); - -DESCRIPTION - Return a string describing the error @var{error_tag}, or - the system error if @var{error_tag} is <>. -*/ - -const char * -bfd_errmsg (bfd_error_type error_tag) -{ -#ifndef errno - extern int errno; -#endif - if (error_tag == bfd_error_on_input) - { - char *buf; - const char *msg = bfd_errmsg (input_error); - - if (asprintf (&buf, _(bfd_errmsgs [error_tag]), input_bfd->filename, msg) - != -1) - return buf; - - /* Ick, what to do on out of memory? */ - return msg; - } - - if (error_tag == bfd_error_system_call) - return xstrerror (errno); - - if (error_tag > bfd_error_invalid_error_code) - error_tag = bfd_error_invalid_error_code; /* sanity check */ - - return _(bfd_errmsgs [error_tag]); -} - -/* -FUNCTION - bfd_perror - -SYNOPSIS - void bfd_perror (const char *message); - -DESCRIPTION - Print to the standard error stream a string describing the - last BFD error that occurred, or the last system error if - the last BFD error was a system call failure. If @var{message} - is non-NULL and non-empty, the error string printed is preceded - by @var{message}, a colon, and a space. It is followed by a newline. -*/ - -void -bfd_perror (const char *message) -{ - fflush (stdout); - if (message == NULL || *message == '\0') - fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ())); - else - fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ())); - fflush (stderr); -} - -/* -SUBSECTION - BFD error handler - - Some BFD functions want to print messages describing the - problem. They call a BFD error handler function. This - function may be overridden by the program. - - The BFD error handler acts like printf. - -CODE_FRAGMENT -. -.typedef void (*bfd_error_handler_type) (const char *, ...); -. -*/ - -/* The program name used when printing BFD error messages. */ - -static const char *_bfd_error_program_name; - -/* This is the default routine to handle BFD error messages. - Like fprintf (stderr, ...), but also handles some extra format specifiers. - - %A section name from section. For group components, print group name too. - %B file name from bfd. For archive components, prints archive too. - - Note - because these two extra format specifiers require special handling - they are scanned for and processed in this function, before calling - vfprintf. This means that the *arguments* for these format specifiers - must be the first ones in the variable argument list, regardless of where - the specifiers appear in the format string. Thus for example calling - this function with a format string of: - - "blah %s blah %A blah %d blah %B" - - would involve passing the arguments as: - - "blah %s blah %A blah %d blah %B", - asection_for_the_%A, - bfd_for_the_%B, - string_for_the_%s, - integer_for_the_%d); - */ - -void -_bfd_default_error_handler (const char *fmt, ...) -{ - va_list ap; - char *bufp; - const char *new_fmt, *p; - size_t avail = 1000; - char buf[1000]; - - /* PR 4992: Don't interrupt output being sent to stdout. */ - fflush (stdout); - - if (_bfd_error_program_name != NULL) - fprintf (stderr, "%s: ", _bfd_error_program_name); - else - fprintf (stderr, "BFD: "); - - va_start (ap, fmt); - new_fmt = fmt; - bufp = buf; - - /* Reserve enough space for the existing format string. */ - avail -= strlen (fmt) + 1; - if (avail > 1000) - _exit (EXIT_FAILURE); - - p = fmt; - while (1) - { - char *q; - size_t len, extra, trim; - - p = strchr (p, '%'); - if (p == NULL || p[1] == '\0') - { - if (new_fmt == buf) - { - len = strlen (fmt); - memcpy (bufp, fmt, len + 1); - } - break; - } - - if (p[1] == 'A' || p[1] == 'B') - { - len = p - fmt; - memcpy (bufp, fmt, len); - bufp += len; - fmt = p + 2; - new_fmt = buf; - - /* If we run out of space, tough, you lose your ridiculously - long file or section name. It's not safe to try to alloc - memory here; We might be printing an out of memory message. */ - if (avail == 0) - { - *bufp++ = '*'; - *bufp++ = '*'; - *bufp = '\0'; - } - else - { - if (p[1] == 'B') - { - bfd *abfd = va_arg (ap, bfd *); - - if (abfd == NULL) - /* Invoking %B with a null bfd pointer is an internal error. */ - abort (); - else if (abfd->my_archive) - snprintf (bufp, avail, "%s(%s)", - abfd->my_archive->filename, abfd->filename); - else - snprintf (bufp, avail, "%s", abfd->filename); - } - else - { - asection *sec = va_arg (ap, asection *); - bfd *abfd; - const char *group = NULL; - struct coff_comdat_info *ci; - - if (sec == NULL) - /* Invoking %A with a null section pointer is an internal error. */ - abort (); - abfd = sec->owner; - if (abfd != NULL - && bfd_get_flavour (abfd) == bfd_target_elf_flavour - && elf_next_in_group (sec) != NULL - && (sec->flags & SEC_GROUP) == 0) - group = elf_group_name (sec); - else if (abfd != NULL - && bfd_get_flavour (abfd) == bfd_target_coff_flavour - && (ci = bfd_coff_get_comdat_section (sec->owner, - sec)) != NULL) - group = ci->name; - if (group != NULL) - snprintf (bufp, avail, "%s[%s]", sec->name, group); - else - snprintf (bufp, avail, "%s", sec->name); - } - len = strlen (bufp); - avail = avail - len + 2; - - /* We need to replace any '%' we printed by "%%". - First count how many. */ - q = bufp; - bufp += len; - extra = 0; - while ((q = strchr (q, '%')) != NULL) - { - ++q; - ++extra; - } - - /* If there isn't room, trim off the end of the string. */ - q = bufp; - bufp += extra; - if (extra > avail) - { - trim = extra - avail; - bufp -= trim; - do - { - if (*--q == '%') - --extra; - } - while (--trim != 0); - *q = '\0'; - avail = extra; - } - avail -= extra; - - /* Now double all '%' chars, shuffling the string as we go. */ - while (extra != 0) - { - while ((q[extra] = *q) != '%') - --q; - q[--extra] = '%'; - --q; - } - } - } - p = p + 2; - } - - vfprintf (stderr, new_fmt, ap); - va_end (ap); - - putc ('\n', stderr); - fflush (stderr); -} - -/* This is a function pointer to the routine which should handle BFD - error messages. It is called when a BFD routine encounters an - error for which it wants to print a message. Going through a - function pointer permits a program linked against BFD to intercept - the messages and deal with them itself. */ - -bfd_error_handler_type _bfd_error_handler = _bfd_default_error_handler; - -/* -FUNCTION - bfd_set_error_handler - -SYNOPSIS - bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); - -DESCRIPTION - Set the BFD error handler function. Returns the previous - function. -*/ - -bfd_error_handler_type -bfd_set_error_handler (bfd_error_handler_type pnew) -{ - bfd_error_handler_type pold; - - pold = _bfd_error_handler; - _bfd_error_handler = pnew; - return pold; -} - -/* -FUNCTION - bfd_set_error_program_name - -SYNOPSIS - void bfd_set_error_program_name (const char *); - -DESCRIPTION - Set the program name to use when printing a BFD error. This - is printed before the error message followed by a colon and - space. The string must not be changed after it is passed to - this function. -*/ - -void -bfd_set_error_program_name (const char *name) -{ - _bfd_error_program_name = name; -} - -/* -FUNCTION - bfd_get_error_handler - -SYNOPSIS - bfd_error_handler_type bfd_get_error_handler (void); - -DESCRIPTION - Return the BFD error handler function. -*/ - -bfd_error_handler_type -bfd_get_error_handler (void) -{ - return _bfd_error_handler; -} - -/* -SECTION - Miscellaneous - -SUBSECTION - Miscellaneous functions -*/ - -/* -FUNCTION - bfd_get_reloc_upper_bound - -SYNOPSIS - long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); - -DESCRIPTION - Return the number of bytes required to store the - relocation information associated with section @var{sect} - attached to bfd @var{abfd}. If an error occurs, return -1. - -*/ - -long -bfd_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) -{ - if (abfd->format != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect)); -} - -/* -FUNCTION - bfd_canonicalize_reloc - -SYNOPSIS - long bfd_canonicalize_reloc - (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); - -DESCRIPTION - Call the back end associated with the open BFD - @var{abfd} and translate the external form of the relocation - information attached to @var{sec} into the internal canonical - form. Place the table into memory at @var{loc}, which has - been preallocated, usually by a call to - <>. Returns the number of relocs, or - -1 on error. - - The @var{syms} table is also needed for horrible internal magic - reasons. - -*/ -long -bfd_canonicalize_reloc (bfd *abfd, - sec_ptr asect, - arelent **location, - asymbol **symbols) -{ - if (abfd->format != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - return BFD_SEND (abfd, _bfd_canonicalize_reloc, - (abfd, asect, location, symbols)); -} - -/* -FUNCTION - bfd_set_reloc - -SYNOPSIS - void bfd_set_reloc - (bfd *abfd, asection *sec, arelent **rel, unsigned int count); - -DESCRIPTION - Set the relocation pointer and count within - section @var{sec} to the values @var{rel} and @var{count}. - The argument @var{abfd} is ignored. - -*/ - -void -bfd_set_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED, - sec_ptr asect, - arelent **location, - unsigned int count) -{ - asect->orelocation = location; - asect->reloc_count = count; -} - -/* -FUNCTION - bfd_set_file_flags - -SYNOPSIS - bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); - -DESCRIPTION - Set the flag word in the BFD @var{abfd} to the value @var{flags}. - - Possible errors are: - o <> - The target bfd was not of object format. - o <> - The target bfd was open for reading. - o <> - - The flag word contained a bit which was not applicable to the - type of file. E.g., an attempt was made to set the <> bit - on a BFD format which does not support demand paging. - -*/ - -bfd_boolean -bfd_set_file_flags (bfd *abfd, flagword flags) -{ - if (abfd->format != bfd_object) - { - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - if (bfd_read_p (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - bfd_get_file_flags (abfd) = flags; - if ((flags & bfd_applicable_file_flags (abfd)) != flags) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - return TRUE; -} - -void -bfd_assert (const char *file, int line) -{ - (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"), - BFD_VERSION_STRING, file, line); -} - -/* A more or less friendly abort message. In libbfd.h abort is - defined to call this function. */ - -void -_bfd_abort (const char *file, int line, const char *fn) -{ - if (fn != NULL) - (*_bfd_error_handler) - (_("BFD %s internal error, aborting at %s line %d in %s\n"), - BFD_VERSION_STRING, file, line, fn); - else - (*_bfd_error_handler) - (_("BFD %s internal error, aborting at %s line %d\n"), - BFD_VERSION_STRING, file, line); - (*_bfd_error_handler) (_("Please report this bug.\n")); - _exit (EXIT_FAILURE); -} - -/* -FUNCTION - bfd_get_arch_size - -SYNOPSIS - int bfd_get_arch_size (bfd *abfd); - -DESCRIPTION - Returns the architecture address size, in bits, as determined - by the object file's format. For ELF, this information is - included in the header. - -RETURNS - Returns the arch size in bits if known, <<-1>> otherwise. -*/ - -int -bfd_get_arch_size (bfd *abfd) -{ - if (abfd->xvec->flavour == bfd_target_elf_flavour) - return get_elf_backend_data (abfd)->s->arch_size; - - return -1; -} - -/* -FUNCTION - bfd_get_sign_extend_vma - -SYNOPSIS - int bfd_get_sign_extend_vma (bfd *abfd); - -DESCRIPTION - Indicates if the target architecture "naturally" sign extends - an address. Some architectures implicitly sign extend address - values when they are converted to types larger than the size - of an address. For instance, bfd_get_start_address() will - return an address sign extended to fill a bfd_vma when this is - the case. - -RETURNS - Returns <<1>> if the target architecture is known to sign - extend addresses, <<0>> if the target architecture is known to - not sign extend addresses, and <<-1>> otherwise. -*/ - -int -bfd_get_sign_extend_vma (bfd *abfd) -{ - char *name; - - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - return get_elf_backend_data (abfd)->sign_extend_vma; - - name = bfd_get_target (abfd); - - /* Return a proper value for DJGPP & PE COFF. - This function is required for DWARF2 support, but there is - no place to store this information in the COFF back end. - Should enough other COFF targets add support for DWARF2, - a place will have to be found. Until then, this hack will do. */ - if (CONST_STRNEQ (name, "coff-go32") - || strcmp (name, "pe-i386") == 0 - || strcmp (name, "pei-i386") == 0 - || strcmp (name, "pe-x86-64") == 0 - || strcmp (name, "pei-x86-64") == 0 - || strcmp (name, "pe-arm-wince-little") == 0 - || strcmp (name, "pei-arm-wince-little") == 0 - || strcmp (name, "aixcoff-rs6000") == 0) - return 1; - - if (CONST_STRNEQ (name, "mach-o")) - return 0; - - bfd_set_error (bfd_error_wrong_format); - return -1; -} - -/* -FUNCTION - bfd_set_start_address - -SYNOPSIS - bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); - -DESCRIPTION - Make @var{vma} the entry point of output BFD @var{abfd}. - -RETURNS - Returns <> on success, <> otherwise. -*/ - -bfd_boolean -bfd_set_start_address (bfd *abfd, bfd_vma vma) -{ - abfd->start_address = vma; - return TRUE; -} - -/* -FUNCTION - bfd_get_gp_size - -SYNOPSIS - unsigned int bfd_get_gp_size (bfd *abfd); - -DESCRIPTION - Return the maximum size of objects to be optimized using the GP - register under MIPS ECOFF. This is typically set by the <<-G>> - argument to the compiler, assembler or linker. -*/ - -unsigned int -bfd_get_gp_size (bfd *abfd) -{ - if (abfd->format == bfd_object) - { - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - return ecoff_data (abfd)->gp_size; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - return elf_gp_size (abfd); - } - return 0; -} - -/* -FUNCTION - bfd_set_gp_size - -SYNOPSIS - void bfd_set_gp_size (bfd *abfd, unsigned int i); - -DESCRIPTION - Set the maximum size of objects to be optimized using the GP - register under ECOFF or MIPS ELF. This is typically set by - the <<-G>> argument to the compiler, assembler or linker. -*/ - -void -bfd_set_gp_size (bfd *abfd, unsigned int i) -{ - /* Don't try to set GP size on an archive or core file! */ - if (abfd->format != bfd_object) - return; - - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - ecoff_data (abfd)->gp_size = i; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - elf_gp_size (abfd) = i; -} - -/* Get the GP value. This is an internal function used by some of the - relocation special_function routines on targets which support a GP - register. */ - -bfd_vma -_bfd_get_gp_value (bfd *abfd) -{ - if (! abfd) - return 0; - if (abfd->format != bfd_object) - return 0; - - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - return ecoff_data (abfd)->gp; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - return elf_gp (abfd); - - return 0; -} - -/* Set the GP value. */ - -void -_bfd_set_gp_value (bfd *abfd, bfd_vma v) -{ - if (! abfd) - abort (); - if (abfd->format != bfd_object) - return; - - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - ecoff_data (abfd)->gp = v; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - elf_gp (abfd) = v; -} - -/* -FUNCTION - bfd_scan_vma - -SYNOPSIS - bfd_vma bfd_scan_vma (const char *string, const char **end, int base); - -DESCRIPTION - Convert, like <>, a numerical expression - @var{string} into a <> integer, and return that integer. - (Though without as many bells and whistles as <>.) - The expression is assumed to be unsigned (i.e., positive). - If given a @var{base}, it is used as the base for conversion. - A base of 0 causes the function to interpret the string - in hex if a leading "0x" or "0X" is found, otherwise - in octal if a leading zero is found, otherwise in decimal. - - If the value would overflow, the maximum <> value is - returned. -*/ - -bfd_vma -bfd_scan_vma (const char *string, const char **end, int base) -{ - bfd_vma value; - bfd_vma cutoff; - unsigned int cutlim; - int overflow; - - /* Let the host do it if possible. */ - if (sizeof (bfd_vma) <= sizeof (unsigned long)) - return strtoul (string, (char **) end, base); - -#ifdef HAVE_STRTOULL - if (sizeof (bfd_vma) <= sizeof (unsigned long long)) - return strtoull (string, (char **) end, base); -#endif - - if (base == 0) - { - if (string[0] == '0') - { - if ((string[1] == 'x') || (string[1] == 'X')) - base = 16; - else - base = 8; - } - } - - if ((base < 2) || (base > 36)) - base = 10; - - if (base == 16 - && string[0] == '0' - && (string[1] == 'x' || string[1] == 'X') - && ISXDIGIT (string[2])) - { - string += 2; - } - - cutoff = (~ (bfd_vma) 0) / (bfd_vma) base; - cutlim = (~ (bfd_vma) 0) % (bfd_vma) base; - value = 0; - overflow = 0; - while (1) - { - unsigned int digit; - - digit = *string; - if (ISDIGIT (digit)) - digit = digit - '0'; - else if (ISALPHA (digit)) - digit = TOUPPER (digit) - 'A' + 10; - else - break; - if (digit >= (unsigned int) base) - break; - if (value > cutoff || (value == cutoff && digit > cutlim)) - overflow = 1; - value = value * base + digit; - ++string; - } - - if (overflow) - value = ~ (bfd_vma) 0; - - if (end != NULL) - *end = string; - - return value; -} - -/* -FUNCTION - bfd_copy_private_header_data - -SYNOPSIS - bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); - -DESCRIPTION - Copy private BFD header information from the BFD @var{ibfd} to the - the BFD @var{obfd}. This copies information that may require - sections to exist, but does not require symbol tables. Return - <> on success, <> on error. - Possible error returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_copy_private_header_data(ibfd, obfd) \ -. BFD_SEND (obfd, _bfd_copy_private_header_data, \ -. (ibfd, obfd)) - -*/ - -/* -FUNCTION - bfd_copy_private_bfd_data - -SYNOPSIS - bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); - -DESCRIPTION - Copy private BFD information from the BFD @var{ibfd} to the - the BFD @var{obfd}. Return <> on success, <> on error. - Possible error returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_copy_private_bfd_data(ibfd, obfd) \ -. BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ -. (ibfd, obfd)) - -*/ - -/* -FUNCTION - bfd_merge_private_bfd_data - -SYNOPSIS - bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); - -DESCRIPTION - Merge private BFD information from the BFD @var{ibfd} to the - the output file BFD @var{obfd} when linking. Return <> - on success, <> on error. Possible error returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_merge_private_bfd_data(ibfd, obfd) \ -. BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ -. (ibfd, obfd)) - -*/ - -/* -FUNCTION - bfd_set_private_flags - -SYNOPSIS - bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); - -DESCRIPTION - Set private BFD flag information in the BFD @var{abfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_set_private_flags(abfd, flags) \ -. BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) - -*/ - -/* -FUNCTION - Other functions - -DESCRIPTION - The following functions exist but have not yet been documented. - -.#define bfd_sizeof_headers(abfd, info) \ -. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) -. -.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ -. BFD_SEND (abfd, _bfd_find_nearest_line, \ -. (abfd, sec, syms, off, file, func, line)) -. -.#define bfd_find_line(abfd, syms, sym, file, line) \ -. BFD_SEND (abfd, _bfd_find_line, \ -. (abfd, syms, sym, file, line)) -. -.#define bfd_find_inliner_info(abfd, file, func, line) \ -. BFD_SEND (abfd, _bfd_find_inliner_info, \ -. (abfd, file, func, line)) -. -.#define bfd_debug_info_start(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) -. -.#define bfd_debug_info_end(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) -. -.#define bfd_debug_info_accumulate(abfd, section) \ -. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) -. -.#define bfd_stat_arch_elt(abfd, stat) \ -. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) -. -.#define bfd_update_armap_timestamp(abfd) \ -. BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) -. -.#define bfd_set_arch_mach(abfd, arch, mach)\ -. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) -. -.#define bfd_relax_section(abfd, section, link_info, again) \ -. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) -. -.#define bfd_gc_sections(abfd, link_info) \ -. BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) -. -.#define bfd_lookup_section_flags(link_info, flag_info) \ -. BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info)) -. -.#define bfd_merge_sections(abfd, link_info) \ -. BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) -. -.#define bfd_is_group_section(abfd, sec) \ -. BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) -. -.#define bfd_discard_group(abfd, sec) \ -. BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) -. -.#define bfd_link_hash_table_create(abfd) \ -. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) -. -.#define bfd_link_hash_table_free(abfd, hash) \ -. BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) -. -.#define bfd_link_add_symbols(abfd, info) \ -. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) -. -.#define bfd_link_just_syms(abfd, sec, info) \ -. BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) -. -.#define bfd_final_link(abfd, info) \ -. BFD_SEND (abfd, _bfd_final_link, (abfd, info)) -. -.#define bfd_free_cached_info(abfd) \ -. BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) -. -.#define bfd_get_dynamic_symtab_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) -. -.#define bfd_print_private_bfd_data(abfd, file)\ -. BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) -. -.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) -. -.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ -. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ -. dyncount, dynsyms, ret)) -. -.#define bfd_get_dynamic_reloc_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) -. -.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) -. -.extern bfd_byte *bfd_get_relocated_section_contents -. (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, -. bfd_boolean, asymbol **); -. - -*/ - -bfd_byte * -bfd_get_relocated_section_contents (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - bfd_boolean relocatable, - asymbol **symbols) -{ - bfd *abfd2; - bfd_byte *(*fn) (bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, bfd_boolean, asymbol **); - - if (link_order->type == bfd_indirect_link_order) - { - abfd2 = link_order->u.indirect.section->owner; - if (abfd2 == NULL) - abfd2 = abfd; - } - else - abfd2 = abfd; - - fn = abfd2->xvec->_bfd_get_relocated_section_contents; - - return (*fn) (abfd, link_info, link_order, data, relocatable, symbols); -} - -/* Record information about an ELF program header. */ - -bfd_boolean -bfd_record_phdr (bfd *abfd, - unsigned long type, - bfd_boolean flags_valid, - flagword flags, - bfd_boolean at_valid, - bfd_vma at, - bfd_boolean includes_filehdr, - bfd_boolean includes_phdrs, - unsigned int count, - asection **secs) -{ - struct elf_segment_map *m, **pm; - bfd_size_type amt; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - return TRUE; - - amt = sizeof (struct elf_segment_map); - amt += ((bfd_size_type) count - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - return FALSE; - - m->p_type = type; - m->p_flags = flags; - m->p_paddr = at; - m->p_flags_valid = flags_valid; - m->p_paddr_valid = at_valid; - m->includes_filehdr = includes_filehdr; - m->includes_phdrs = includes_phdrs; - m->count = count; - if (count > 0) - memcpy (m->sections, secs, count * sizeof (asection *)); - - for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) - ; - *pm = m; - - return TRUE; -} - -#ifdef BFD64 -/* Return true iff this target is 32-bit. */ - -static bfd_boolean -is32bit (bfd *abfd) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - return bed->s->elfclass == ELFCLASS32; - } - - /* For non-ELF targets, use architecture information. */ - return bfd_arch_bits_per_address (abfd) <= 32; -} -#endif - -/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the - target's address size. */ - -void -bfd_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value) -{ -#ifdef BFD64 - if (is32bit (abfd)) - { - sprintf (buf, "%08lx", (unsigned long) value & 0xffffffff); - return; - } -#endif - sprintf_vma (buf, value); -} - -void -bfd_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value) -{ -#ifdef BFD64 - if (is32bit (abfd)) - { - fprintf ((FILE *) stream, "%08lx", (unsigned long) value & 0xffffffff); - return; - } -#endif - fprintf_vma ((FILE *) stream, value); -} - -/* -FUNCTION - bfd_alt_mach_code - -SYNOPSIS - bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); - -DESCRIPTION - - When more than one machine code number is available for the - same machine type, this function can be used to switch between - the preferred one (alternative == 0) and any others. Currently, - only ELF supports this feature, with up to two alternate - machine codes. -*/ - -bfd_boolean -bfd_alt_mach_code (bfd *abfd, int alternative) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - { - int code; - - switch (alternative) - { - case 0: - code = get_elf_backend_data (abfd)->elf_machine_code; - break; - - case 1: - code = get_elf_backend_data (abfd)->elf_machine_alt1; - if (code == 0) - return FALSE; - break; - - case 2: - code = get_elf_backend_data (abfd)->elf_machine_alt2; - if (code == 0) - return FALSE; - break; - - default: - return FALSE; - } - - elf_elfheader (abfd)->e_machine = code; - - return TRUE; - } - - return FALSE; -} - -/* -CODE_FRAGMENT - -.struct bfd_preserve -.{ -. void *marker; -. void *tdata; -. flagword flags; -. const struct bfd_arch_info *arch_info; -. struct bfd_section *sections; -. struct bfd_section *section_last; -. unsigned int section_count; -. struct bfd_hash_table section_htab; -.}; -. -*/ - -/* -FUNCTION - bfd_preserve_save - -SYNOPSIS - bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); - -DESCRIPTION - When testing an object for compatibility with a particular - target back-end, the back-end object_p function needs to set - up certain fields in the bfd on successfully recognizing the - object. This typically happens in a piecemeal fashion, with - failures possible at many points. On failure, the bfd is - supposed to be restored to its initial state, which is - virtually impossible. However, restoring a subset of the bfd - state works in practice. This function stores the subset and - reinitializes the bfd. - -*/ - -bfd_boolean -bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve) -{ - preserve->tdata = abfd->tdata.any; - preserve->arch_info = abfd->arch_info; - preserve->flags = abfd->flags; - preserve->sections = abfd->sections; - preserve->section_last = abfd->section_last; - preserve->section_count = abfd->section_count; - preserve->section_htab = abfd->section_htab; - - if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc, - sizeof (struct section_hash_entry))) - return FALSE; - - abfd->tdata.any = NULL; - abfd->arch_info = &bfd_default_arch_struct; - abfd->flags &= BFD_FLAGS_SAVED; - abfd->sections = NULL; - abfd->section_last = NULL; - abfd->section_count = 0; - - return TRUE; -} - -/* -FUNCTION - bfd_preserve_restore - -SYNOPSIS - void bfd_preserve_restore (bfd *, struct bfd_preserve *); - -DESCRIPTION - This function restores bfd state saved by bfd_preserve_save. - If MARKER is non-NULL in struct bfd_preserve then that block - and all subsequently bfd_alloc'd memory is freed. - -*/ - -void -bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve) -{ - bfd_hash_table_free (&abfd->section_htab); - - abfd->tdata.any = preserve->tdata; - abfd->arch_info = preserve->arch_info; - abfd->flags = preserve->flags; - abfd->section_htab = preserve->section_htab; - abfd->sections = preserve->sections; - abfd->section_last = preserve->section_last; - abfd->section_count = preserve->section_count; - - /* bfd_release frees all memory more recently bfd_alloc'd than - its arg, as well as its arg. */ - if (preserve->marker != NULL) - { - bfd_release (abfd, preserve->marker); - preserve->marker = NULL; - } -} - -/* -FUNCTION - bfd_preserve_finish - -SYNOPSIS - void bfd_preserve_finish (bfd *, struct bfd_preserve *); - -DESCRIPTION - This function should be called when the bfd state saved by - bfd_preserve_save is no longer needed. ie. when the back-end - object_p function returns with success. - -*/ - -void -bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve) -{ - /* It would be nice to be able to free more memory here, eg. old - tdata, but that's not possible since these blocks are sitting - inside bfd_alloc'd memory. The section hash is on a separate - objalloc. */ - bfd_hash_table_free (&preserve->section_htab); -} - -/* -FUNCTION - bfd_emul_get_maxpagesize - -SYNOPSIS - bfd_vma bfd_emul_get_maxpagesize (const char *); - -DESCRIPTION - Returns the maximum page size, in bytes, as determined by - emulation. - -RETURNS - Returns the maximum page size in bytes for ELF, 0 otherwise. -*/ - -bfd_vma -bfd_emul_get_maxpagesize (const char *emul) -{ - const bfd_target *target; - - target = bfd_find_target (emul, NULL); - if (target != NULL - && target->flavour == bfd_target_elf_flavour) - return xvec_get_elf_backend_data (target)->maxpagesize; - - return 0; -} - -static void -bfd_elf_set_pagesize (const bfd_target *target, bfd_vma size, - int offset, const bfd_target *orig_target) -{ - if (target->flavour == bfd_target_elf_flavour) - { - const struct elf_backend_data *bed; - - bed = xvec_get_elf_backend_data (target); - *((bfd_vma *) ((char *) bed + offset)) = size; - } - - if (target->alternative_target - && target->alternative_target != orig_target) - bfd_elf_set_pagesize (target->alternative_target, size, offset, - orig_target); -} - -/* -FUNCTION - bfd_emul_set_maxpagesize - -SYNOPSIS - void bfd_emul_set_maxpagesize (const char *, bfd_vma); - -DESCRIPTION - For ELF, set the maximum page size for the emulation. It is - a no-op for other formats. - -*/ - -void -bfd_emul_set_maxpagesize (const char *emul, bfd_vma size) -{ - const bfd_target *target; - - target = bfd_find_target (emul, NULL); - if (target) - bfd_elf_set_pagesize (target, size, - offsetof (struct elf_backend_data, - maxpagesize), target); -} - -/* -FUNCTION - bfd_emul_get_commonpagesize - -SYNOPSIS - bfd_vma bfd_emul_get_commonpagesize (const char *); - -DESCRIPTION - Returns the common page size, in bytes, as determined by - emulation. - -RETURNS - Returns the common page size in bytes for ELF, 0 otherwise. -*/ - -bfd_vma -bfd_emul_get_commonpagesize (const char *emul) -{ - const bfd_target *target; - - target = bfd_find_target (emul, NULL); - if (target != NULL - && target->flavour == bfd_target_elf_flavour) - return xvec_get_elf_backend_data (target)->commonpagesize; - - return 0; -} - -/* -FUNCTION - bfd_emul_set_commonpagesize - -SYNOPSIS - void bfd_emul_set_commonpagesize (const char *, bfd_vma); - -DESCRIPTION - For ELF, set the common page size for the emulation. It is - a no-op for other formats. - -*/ - -void -bfd_emul_set_commonpagesize (const char *emul, bfd_vma size) -{ - const bfd_target *target; - - target = bfd_find_target (emul, NULL); - if (target) - bfd_elf_set_pagesize (target, size, - offsetof (struct elf_backend_data, - commonpagesize), target); -} - -/* -FUNCTION - bfd_demangle - -SYNOPSIS - char *bfd_demangle (bfd *, const char *, int); - -DESCRIPTION - Wrapper around cplus_demangle. Strips leading underscores and - other such chars that would otherwise confuse the demangler. - If passed a g++ v3 ABI mangled name, returns a buffer allocated - with malloc holding the demangled name. Returns NULL otherwise - and on memory alloc failure. -*/ - -char * -bfd_demangle (bfd *abfd, const char *name, int options) -{ - char *res, *alloc; - const char *pre, *suf; - size_t pre_len; - bfd_boolean skip_lead; - - skip_lead = (abfd != NULL - && *name != '\0' - && bfd_get_symbol_leading_char (abfd) == *name); - if (skip_lead) - ++name; - - /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF - or the MS PE format. These formats have a number of leading '.'s - on at least some symbols, so we remove all dots to avoid - confusing the demangler. */ - pre = name; - while (*name == '.' || *name == '$') - ++name; - pre_len = name - pre; - - /* Strip off @plt and suchlike too. */ - alloc = NULL; - suf = strchr (name, '@'); - if (suf != NULL) - { - alloc = (char *) bfd_malloc (suf - name + 1); - if (alloc == NULL) - return NULL; - memcpy (alloc, name, suf - name); - alloc[suf - name] = '\0'; - name = alloc; - } - - res = cplus_demangle (name, options); - - if (alloc != NULL) - free (alloc); - - if (res == NULL) - { - if (skip_lead) - { - size_t len = strlen (pre) + 1; - alloc = (char *) bfd_malloc (len); - if (alloc == NULL) - return NULL; - memcpy (alloc, pre, len); - return alloc; - } - return NULL; - } - - /* Put back any prefix or suffix. */ - if (pre_len != 0 || suf != NULL) - { - size_t len; - size_t suf_len; - char *final; - - len = strlen (res); - if (suf == NULL) - suf = res + len; - suf_len = strlen (suf) + 1; - final = (char *) bfd_malloc (pre_len + len + suf_len); - if (final != NULL) - { - memcpy (final, pre, pre_len); - memcpy (final + pre_len, res, len); - memcpy (final + pre_len + len, suf, suf_len); - } - free (res); - res = final; - } - - return res; -} diff --git a/contrib/binutils-2.22/bfd/bfdio.c b/contrib/binutils-2.22/bfd/bfdio.c deleted file mode 100644 index 841c781f4b..0000000000 --- a/contrib/binutils-2.22/bfd/bfdio.c +++ /dev/null @@ -1,611 +0,0 @@ -/* Low-level I/O routines for BFDs. - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 - Free Software Foundation, Inc. - - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "libbfd.h" - -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 /* Execute by group. */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 /* Execute by others. */ -#endif - -#ifndef FD_CLOEXEC -#define FD_CLOEXEC 1 -#endif - -file_ptr -real_ftell (FILE *file) -{ -#if defined (HAVE_FTELLO64) - return ftello64 (file); -#elif defined (HAVE_FTELLO) - return ftello (file); -#else - return ftell (file); -#endif -} - -int -real_fseek (FILE *file, file_ptr offset, int whence) -{ -#if defined (HAVE_FSEEKO64) - return fseeko64 (file, offset, whence); -#elif defined (HAVE_FSEEKO) - return fseeko (file, offset, whence); -#else - return fseek (file, offset, whence); -#endif -} - -/* Mark FILE as close-on-exec. Return FILE. FILE may be NULL, in - which case nothing is done. */ -static FILE * -close_on_exec (FILE *file) -{ -#if defined (HAVE_FILENO) && defined (F_GETFD) - if (file) - { - int fd = fileno (file); - int old = fcntl (fd, F_GETFD, 0); - if (old >= 0) - fcntl (fd, F_SETFD, old | FD_CLOEXEC); - } -#endif - return file; -} - -FILE * -real_fopen (const char *filename, const char *modes) -{ -#ifdef VMS - char vms_modes[4]; - char *vms_attr; - - /* On VMS, fopen allows file attributes as optionnal arguments. - We need to use them but we'd better to use the common prototype. - In fopen-vms.h, they are separated from the mode with a comma. - Split here. */ - vms_attr = strchr (modes, ','); - if (vms_attr == NULL) - { - /* No attributes. */ - return close_on_exec (fopen (filename, modes)); - } - else - { - /* Attributes found. Split. */ - size_t modes_len = strlen (modes) + 1; - char attrs[modes_len + 1]; - char *at[3]; - int i; - - memcpy (attrs, modes, modes_len); - at[0] = attrs; - for (i = 0; i < 2; i++) - { - at[i + 1] = strchr (at[i], ','); - BFD_ASSERT (at[i + 1] != NULL); - *(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it. */ - } - return close_on_exec (fopen (filename, at[0], at[1], at[2])); - } -#else /* !VMS */ -#if defined (HAVE_FOPEN64) - return close_on_exec (fopen64 (filename, modes)); -#else - return close_on_exec (fopen (filename, modes)); -#endif -#endif /* !VMS */ -} - -/* -INTERNAL_DEFINITION - struct bfd_iovec - -DESCRIPTION - - The <> contains the internal file I/O class. - Each <> has an instance of this class and all file I/O is - routed through it (it is assumed that the instance implements - all methods listed below). - -.struct bfd_iovec -.{ -. {* To avoid problems with macros, a "b" rather than "f" -. prefix is prepended to each method name. *} -. {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching -. bytes starting at PTR. Return the number of bytes actually -. transfered (a read past end-of-file returns less than NBYTES), -. or -1 (setting <>) if an error occurs. *} -. file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes); -. file_ptr (*bwrite) (struct bfd *abfd, const void *ptr, -. file_ptr nbytes); -. {* Return the current IOSTREAM file offset, or -1 (setting <> -. if an error occurs. *} -. file_ptr (*btell) (struct bfd *abfd); -. {* For the following, on successful completion a value of 0 is returned. -. Otherwise, a value of -1 is returned (and <> is set). *} -. int (*bseek) (struct bfd *abfd, file_ptr offset, int whence); -. int (*bclose) (struct bfd *abfd); -. int (*bflush) (struct bfd *abfd); -. int (*bstat) (struct bfd *abfd, struct stat *sb); -. {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual -. mmap parameter, except that LEN and OFFSET do not need to be page -. aligned. Returns (void *)-1 on failure, mmapped address on success. -. Also write in MAP_ADDR the address of the page aligned buffer and in -. MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and -. MAP_LEN to unmap. *} -. void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, -. int prot, int flags, file_ptr offset, -. void **map_addr, bfd_size_type *map_len); -.}; - -.extern const struct bfd_iovec _bfd_memory_iovec; - -*/ - - -/* Return value is amount read. */ - -bfd_size_type -bfd_bread (void *ptr, bfd_size_type size, bfd *abfd) -{ - size_t nread; - - /* If this is an archive element, don't read past the end of - this element. */ - if (abfd->arelt_data != NULL) - { - size_t maxbytes = ((struct areltdata *) abfd->arelt_data)->parsed_size; - if (abfd->where + size > maxbytes) - { - if (abfd->where >= maxbytes) - return 0; - size = maxbytes - abfd->where; - } - } - - if (abfd->iovec) - nread = abfd->iovec->bread (abfd, ptr, size); - else - nread = 0; - if (nread != (size_t) -1) - abfd->where += nread; - - return nread; -} - -bfd_size_type -bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd) -{ - size_t nwrote; - - if (abfd->iovec) - nwrote = abfd->iovec->bwrite (abfd, ptr, size); - else - nwrote = 0; - - if (nwrote != (size_t) -1) - abfd->where += nwrote; - if (nwrote != size) - { -#ifdef ENOSPC - errno = ENOSPC; -#endif - bfd_set_error (bfd_error_system_call); - } - return nwrote; -} - -file_ptr -bfd_tell (bfd *abfd) -{ - file_ptr ptr; - - if (abfd->iovec) - { - ptr = abfd->iovec->btell (abfd); - - if (abfd->my_archive) - ptr -= abfd->origin; - } - else - ptr = 0; - - abfd->where = ptr; - return ptr; -} - -int -bfd_flush (bfd *abfd) -{ - if (abfd->iovec) - return abfd->iovec->bflush (abfd); - return 0; -} - -/* Returns 0 for success, negative value for failure (in which case - bfd_get_error can retrieve the error code). */ -int -bfd_stat (bfd *abfd, struct stat *statbuf) -{ - int result; - - if (abfd->iovec) - result = abfd->iovec->bstat (abfd, statbuf); - else - result = -1; - - if (result < 0) - bfd_set_error (bfd_error_system_call); - return result; -} - -/* Returns 0 for success, nonzero for failure (in which case bfd_get_error - can retrieve the error code). */ - -int -bfd_seek (bfd *abfd, file_ptr position, int direction) -{ - int result; - file_ptr file_position; - /* For the time being, a BFD may not seek to it's end. The problem - is that we don't easily have a way to recognize the end of an - element in an archive. */ - - BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR); - - if (direction == SEEK_CUR && position == 0) - return 0; - - if (abfd->format != bfd_archive && abfd->my_archive == 0) - { - if (direction == SEEK_SET && (bfd_vma) position == abfd->where) - return 0; - } - else - { - /* We need something smarter to optimize access to archives. - Currently, anything inside an archive is read via the file - handle for the archive. Which means that a bfd_seek on one - component affects the `current position' in the archive, as - well as in any other component. - - It might be sufficient to put a spike through the cache - abstraction, and look to the archive for the file position, - but I think we should try for something cleaner. - - In the meantime, no optimization for archives. */ - } - - file_position = position; - if (direction == SEEK_SET && abfd->my_archive != NULL) - file_position += abfd->origin; - - if (abfd->iovec) - result = abfd->iovec->bseek (abfd, file_position, direction); - else - result = -1; - - if (result != 0) - { - int hold_errno = errno; - - /* Force redetermination of `where' field. */ - bfd_tell (abfd); - - /* An EINVAL error probably means that the file offset was - absurd. */ - if (hold_errno == EINVAL) - bfd_set_error (bfd_error_file_truncated); - else - { - bfd_set_error (bfd_error_system_call); - errno = hold_errno; - } - } - else - { - /* Adjust `where' field. */ - if (direction == SEEK_SET) - abfd->where = position; - else - abfd->where += position; - } - return result; -} - -/* -FUNCTION - bfd_get_mtime - -SYNOPSIS - long bfd_get_mtime (bfd *abfd); - -DESCRIPTION - Return the file modification time (as read from the file system, or - from the archive header for archive members). - -*/ - -long -bfd_get_mtime (bfd *abfd) -{ - struct stat buf; - - if (abfd->mtime_set) - return abfd->mtime; - - if (abfd->iovec == NULL) - return 0; - - if (abfd->iovec->bstat (abfd, &buf) != 0) - return 0; - - abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */ - return buf.st_mtime; -} - -/* -FUNCTION - bfd_get_size - -SYNOPSIS - file_ptr bfd_get_size (bfd *abfd); - -DESCRIPTION - Return the file size (as read from file system) for the file - associated with BFD @var{abfd}. - - The initial motivation for, and use of, this routine is not - so we can get the exact size of the object the BFD applies to, since - that might not be generally possible (archive members for example). - It would be ideal if someone could eventually modify - it so that such results were guaranteed. - - Instead, we want to ask questions like "is this NNN byte sized - object I'm about to try read from file offset YYY reasonable?" - As as example of where we might do this, some object formats - use string tables for which the first <> bytes of the - table contain the size of the table itself, including the size bytes. - If an application tries to read what it thinks is one of these - string tables, without some way to validate the size, and for - some reason the size is wrong (byte swapping error, wrong location - for the string table, etc.), the only clue is likely to be a read - error when it tries to read the table, or a "virtual memory - exhausted" error when it tries to allocate 15 bazillon bytes - of space for the 15 bazillon byte table it is about to read. - This function at least allows us to answer the question, "is the - size reasonable?". -*/ - -file_ptr -bfd_get_size (bfd *abfd) -{ - struct stat buf; - - if (abfd->iovec == NULL) - return 0; - - if (abfd->iovec->bstat (abfd, &buf) != 0) - return 0; - - return buf.st_size; -} - - -/* -FUNCTION - bfd_mmap - -SYNOPSIS - void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, - int prot, int flags, file_ptr offset, - void **map_addr, bfd_size_type *map_len); - -DESCRIPTION - Return mmap()ed region of the file, if possible and implemented. - LEN and OFFSET do not need to be page aligned. The page aligned - address and length are written to MAP_ADDR and MAP_LEN. - -*/ - -void * -bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, - int prot, int flags, file_ptr offset, - void **map_addr, bfd_size_type *map_len) -{ - void *ret = (void *)-1; - - if (abfd->iovec == NULL) - return ret; - - return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset, - map_addr, map_len); -} - -/* Memory file I/O operations. */ - -static file_ptr -memory_bread (bfd *abfd, void *ptr, file_ptr size) -{ - struct bfd_in_memory *bim; - bfd_size_type get; - - bim = (struct bfd_in_memory *) abfd->iostream; - get = size; - if (abfd->where + get > bim->size) - { - if (bim->size < (bfd_size_type) abfd->where) - get = 0; - else - get = bim->size - abfd->where; - bfd_set_error (bfd_error_file_truncated); - } - memcpy (ptr, bim->buffer + abfd->where, (size_t) get); - return get; -} - -static file_ptr -memory_bwrite (bfd *abfd, const void *ptr, file_ptr size) -{ - struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; - - if (abfd->where + size > bim->size) - { - bfd_size_type newsize, oldsize; - - oldsize = (bim->size + 127) & ~(bfd_size_type) 127; - bim->size = abfd->where + size; - /* Round up to cut down on memory fragmentation */ - newsize = (bim->size + 127) & ~(bfd_size_type) 127; - if (newsize > oldsize) - { - bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize); - if (bim->buffer == NULL) - { - bim->size = 0; - return 0; - } - if (newsize > bim->size) - memset (bim->buffer + bim->size, 0, newsize - bim->size); - } - } - memcpy (bim->buffer + abfd->where, ptr, (size_t) size); - return size; -} - -static file_ptr -memory_btell (bfd *abfd) -{ - return abfd->where; -} - -static int -memory_bseek (bfd *abfd, file_ptr position, int direction) -{ - file_ptr nwhere; - struct bfd_in_memory *bim; - - bim = (struct bfd_in_memory *) abfd->iostream; - - if (direction == SEEK_SET) - nwhere = position; - else - nwhere = abfd->where + position; - - if (nwhere < 0) - { - abfd->where = 0; - errno = EINVAL; - return -1; - } - - if ((bfd_size_type)nwhere > bim->size) - { - if (abfd->direction == write_direction - || abfd->direction == both_direction) - { - bfd_size_type newsize, oldsize; - - oldsize = (bim->size + 127) & ~(bfd_size_type) 127; - bim->size = nwhere; - /* Round up to cut down on memory fragmentation */ - newsize = (bim->size + 127) & ~(bfd_size_type) 127; - if (newsize > oldsize) - { - bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize); - if (bim->buffer == NULL) - { - errno = EINVAL; - bim->size = 0; - return -1; - } - memset (bim->buffer + oldsize, 0, newsize - oldsize); - } - } - else - { - abfd->where = bim->size; - errno = EINVAL; - bfd_set_error (bfd_error_file_truncated); - return -1; - } - } - return 0; -} - -static int -memory_bclose (struct bfd *abfd) -{ - struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; - - if (bim->buffer != NULL) - free (bim->buffer); - free (bim); - abfd->iostream = NULL; - - return TRUE; -} - -static int -memory_bflush (bfd *abfd ATTRIBUTE_UNUSED) -{ - return 0; -} - -static int -memory_bstat (bfd *abfd, struct stat *statbuf) -{ - struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; - - memset (statbuf, 0, sizeof (*statbuf)); - statbuf->st_size = bim->size; - - return 0; -} - -static void * -memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED, - bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED, - void **map_addr ATTRIBUTE_UNUSED, - bfd_size_type *map_len ATTRIBUTE_UNUSED) -{ - return (void *)-1; -} - -const struct bfd_iovec _bfd_memory_iovec = -{ - &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek, - &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap -}; diff --git a/contrib/binutils-2.22/bfd/bfdver.h b/contrib/binutils-2.22/bfd/bfdver.h deleted file mode 100644 index 5e2b3c379f..0000000000 --- a/contrib/binutils-2.22/bfd/bfdver.h +++ /dev/null @@ -1,4 +0,0 @@ -#define BFD_VERSION_DATE 20111121 -#define BFD_VERSION 222000000 -#define BFD_VERSION_STRING "(GNU Binutils) " "2.22" -#define REPORT_BUGS_TO "" diff --git a/contrib/binutils-2.22/bfd/bfdwin.c b/contrib/binutils-2.22/bfd/bfdwin.c deleted file mode 100644 index 4103e9c2f5..0000000000 --- a/contrib/binutils-2.22/bfd/bfdwin.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Support for memory-mapped windows into a BFD. - Copyright 1995, 1996, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" - -#include "bfd.h" -#include "libbfd.h" - -/* Currently, if USE_MMAP is undefined, none of the window stuff is - used. Enabled by --with-mmap. */ - -#ifdef USE_MMAP - -#undef HAVE_MPROTECT /* code's not tested yet */ - -#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE -#include -#endif - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -static int debug_windows; - -/* The idea behind the next and refcount fields is that one mapped - region can suffice for multiple read-only windows or multiple - non-overlapping read-write windows. It's not implemented yet - though. */ - -/* -INTERNAL_DEFINITION - -.struct _bfd_window_internal { -. struct _bfd_window_internal *next; -. void *data; -. bfd_size_type size; -. int refcount : 31; {* should be enough... *} -. unsigned mapped : 1; {* 1 = mmap, 0 = malloc *} -.}; -*/ - -void -bfd_init_window (bfd_window *windowp) -{ - windowp->data = 0; - windowp->i = 0; - windowp->size = 0; -} - -void -bfd_free_window (bfd_window *windowp) -{ - bfd_window_internal *i = windowp->i; - windowp->i = 0; - windowp->data = 0; - if (i == 0) - return; - i->refcount--; - if (debug_windows) - fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n", - windowp, windowp->data, (unsigned long) windowp->size, windowp->i); - if (i->refcount != 0) - return; - - if (i->mapped) - { -#ifdef HAVE_MMAP - munmap (i->data, i->size); - goto no_free; -#else - abort (); -#endif - } -#ifdef HAVE_MPROTECT - mprotect (i->data, i->size, PROT_READ | PROT_WRITE); -#endif - free (i->data); -#ifdef HAVE_MMAP - no_free: -#endif - i->data = 0; - /* There should be no more references to i at this point. */ - free (i); -} - -static int ok_to_map = 1; - -bfd_boolean -bfd_get_file_window (bfd *abfd, - file_ptr offset, - bfd_size_type size, - bfd_window *windowp, - bfd_boolean writable) -{ - static size_t pagesize; - bfd_window_internal *i = windowp->i; - bfd_size_type size_to_alloc = size; - - if (debug_windows) - fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)", - abfd, (long) offset, (long) size, - windowp, windowp->data, (unsigned long) windowp->size, - windowp->i, writable); - - /* Make sure we know the page size, so we can be friendly to mmap. */ - if (pagesize == 0) - pagesize = getpagesize (); - if (pagesize == 0) - abort (); - - if (i == NULL) - { - i = bfd_zmalloc (sizeof (bfd_window_internal)); - if (i == NULL) - return FALSE; - i->data = NULL; - } -#ifdef HAVE_MMAP - if (ok_to_map - && (i->data == NULL || i->mapped == 1) - && (abfd->flags & BFD_IN_MEMORY) == 0) - { - file_ptr file_offset, offset2; - size_t real_size; - int fd; - - /* Find the real file and the real offset into it. */ - while (abfd->my_archive != NULL) - { - offset += abfd->origin; - abfd = abfd->my_archive; - } - - /* Seek into the file, to ensure it is open if cacheable. */ - if (abfd->iostream == NULL - && (abfd->iovec == NULL - || abfd->iovec->bseek (abfd, offset, SEEK_SET) != 0)) - goto free_and_fail; - - fd = fileno ((FILE *) abfd->iostream); - /* Compute offsets and size for mmap and for the user's data. */ - offset2 = offset % pagesize; - if (offset2 < 0) - abort (); - file_offset = offset - offset2; - real_size = offset + size - file_offset; - real_size = real_size + pagesize - 1; - real_size -= real_size % pagesize; - - /* If we're re-using a memory region, make sure it's big enough. */ - if (i->data != NULL && i->size < size) - { - munmap (i->data, i->size); - i->data = NULL; - } - i->data = mmap (i->data, real_size, - writable ? PROT_WRITE | PROT_READ : PROT_READ, - (writable - ? MAP_FILE | MAP_PRIVATE - : MAP_FILE | MAP_SHARED), - fd, file_offset); - if (i->data == (void *) -1) - { - /* An error happened. Report it, or try using malloc, or - something. */ - bfd_set_error (bfd_error_system_call); - windowp->data = 0; - if (debug_windows) - fprintf (stderr, "\t\tmmap failed!\n"); - goto free_and_fail; - } - if (debug_windows) - fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n", - (long) real_size, i->data, (long) offset2); - i->size = real_size; - windowp->data = (bfd_byte *) i->data + offset2; - windowp->size = size; - i->mapped = 1; - i->refcount = 1; - windowp->i = i; - return TRUE; - } - else if (debug_windows) - { - if (ok_to_map) - fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"), - (unsigned long) i->data, (int) i->mapped); - else - fprintf (stderr, _("not mapping: env var not set\n")); - } -#else - ok_to_map = 0; -#endif - -#ifdef HAVE_MPROTECT - if (!writable) - { - size_to_alloc += pagesize - 1; - size_to_alloc -= size_to_alloc % pagesize; - } -#endif - if (debug_windows) - fprintf (stderr, "\n\t%s(%6ld)", - i->data ? "realloc" : " malloc", (long) size_to_alloc); - i->data = bfd_realloc_or_free (i->data, size_to_alloc); - if (debug_windows) - fprintf (stderr, "\t-> %p\n", i->data); - if (i->data == NULL) - { - if (size_to_alloc == 0) - { - windowp->i = i; - return TRUE; - } - goto free_and_fail; - } - i->refcount = 1; - if (bfd_seek (abfd, offset, SEEK_SET) != 0) - goto free_and_fail; - i->size = bfd_bread (i->data, size, abfd); - if (i->size != size) - goto free_and_fail; - i->mapped = 0; -#ifdef HAVE_MPROTECT - if (!writable) - { - if (debug_windows) - fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data, - (long) i->size); - mprotect (i->data, i->size, PROT_READ); - } -#endif - windowp->data = i->data; - windowp->size = i->size; - windowp->i = i; - return TRUE; - - free_and_fail: - /* We have a bfd_window_internal, but an error occurred. Free it. */ - free (i); - return FALSE; -} - -#endif /* USE_MMAP */ diff --git a/contrib/binutils-2.22/bfd/binary.c b/contrib/binutils-2.22/bfd/binary.c deleted file mode 100644 index 700c862f93..0000000000 --- a/contrib/binutils-2.22/bfd/binary.c +++ /dev/null @@ -1,369 +0,0 @@ -/* BFD back-end for binary objects. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2009, 2011 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support, - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* This is a BFD backend which may be used to write binary objects. - It may only be used for output, not input. The intention is that - this may be used as an output format for objcopy in order to - generate raw binary data. - - This is very simple. The only complication is that the real data - will start at some address X, and in some cases we will not want to - include X zeroes just to get to that point. Since the start - address is not meaningful for this object file format, we use it - instead to indicate the number of zeroes to skip at the start of - the file. objcopy cooperates by specially setting the start - address to zero by default. */ - -#include "sysdep.h" -#include "bfd.h" -#include "safe-ctype.h" -#include "libbfd.h" - -/* Any bfd we create by reading a binary file has three symbols: - a start symbol, an end symbol, and an absolute length symbol. */ -#define BIN_SYMS 3 - -/* Create a binary object. Invoked via bfd_set_format. */ - -static bfd_boolean -binary_mkobject (bfd *abfd ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Any file may be considered to be a binary file, provided the target - was not defaulted. That is, it must be explicitly specified as - being binary. */ - -static const bfd_target * -binary_object_p (bfd *abfd) -{ - struct stat statbuf; - asection *sec; - flagword flags; - - if (abfd->target_defaulted) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - abfd->symcount = BIN_SYMS; - - /* Find the file size. */ - if (bfd_stat (abfd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* One data section. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS; - sec = bfd_make_section_with_flags (abfd, ".data", flags); - if (sec == NULL) - return NULL; - sec->vma = 0; - sec->size = statbuf.st_size; - sec->filepos = 0; - - abfd->tdata.any = (void *) sec; - - return abfd->xvec; -} - -#define binary_close_and_cleanup _bfd_generic_close_and_cleanup -#define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define binary_new_section_hook _bfd_generic_new_section_hook - -/* Get contents of the only section. */ - -static bfd_boolean -binary_get_section_contents (bfd *abfd, - asection *section ATTRIBUTE_UNUSED, - void * location, - file_ptr offset, - bfd_size_type count) -{ - if (bfd_seek (abfd, offset, SEEK_SET) != 0 - || bfd_bread (location, count, abfd) != count) - return FALSE; - return TRUE; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -binary_get_symtab_upper_bound (bfd *abfd ATTRIBUTE_UNUSED) -{ - return (BIN_SYMS + 1) * sizeof (asymbol *); -} - -/* Create a symbol name based on the bfd's filename. */ - -static char * -mangle_name (bfd *abfd, char *suffix) -{ - bfd_size_type size; - char *buf; - char *p; - - size = (strlen (bfd_get_filename (abfd)) - + strlen (suffix) - + sizeof "_binary__"); - - buf = (char *) bfd_alloc (abfd, size); - if (buf == NULL) - return ""; - - sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix); - - /* Change any non-alphanumeric characters to underscores. */ - for (p = buf; *p; p++) - if (! ISALNUM (*p)) - *p = '_'; - - return buf; -} - -/* Return the symbol table. */ - -static long -binary_canonicalize_symtab (bfd *abfd, asymbol **alocation) -{ - asection *sec = (asection *) abfd->tdata.any; - asymbol *syms; - unsigned int i; - bfd_size_type amt = BIN_SYMS * sizeof (asymbol); - - syms = (asymbol *) bfd_alloc (abfd, amt); - if (syms == NULL) - return -1; - - /* Start symbol. */ - syms[0].the_bfd = abfd; - syms[0].name = mangle_name (abfd, "start"); - syms[0].value = 0; - syms[0].flags = BSF_GLOBAL; - syms[0].section = sec; - syms[0].udata.p = NULL; - - /* End symbol. */ - syms[1].the_bfd = abfd; - syms[1].name = mangle_name (abfd, "end"); - syms[1].value = sec->size; - syms[1].flags = BSF_GLOBAL; - syms[1].section = sec; - syms[1].udata.p = NULL; - - /* Size symbol. */ - syms[2].the_bfd = abfd; - syms[2].name = mangle_name (abfd, "size"); - syms[2].value = sec->size; - syms[2].flags = BSF_GLOBAL; - syms[2].section = bfd_abs_section_ptr; - syms[2].udata.p = NULL; - - for (i = 0; i < BIN_SYMS; i++) - *alocation++ = syms++; - *alocation = NULL; - - return BIN_SYMS; -} - -#define binary_make_empty_symbol _bfd_generic_make_empty_symbol -#define binary_print_symbol _bfd_nosymbols_print_symbol - -/* Get information about a symbol. */ - -static void -binary_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, - asymbol *symbol, - symbol_info *ret) -{ - bfd_symbol_info (symbol, ret); -} - -#define binary_bfd_is_local_label_name bfd_generic_is_local_label_name -#define binary_get_lineno _bfd_nosymbols_get_lineno -#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line -#define binary_find_inliner_info _bfd_nosymbols_find_inliner_info -#define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define binary_read_minisymbols _bfd_generic_read_minisymbols -#define binary_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define binary_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) - -/* Set the architecture of a binary file. */ -#define binary_set_arch_mach _bfd_generic_set_arch_mach - -/* Write section contents of a binary file. */ - -static bfd_boolean -binary_set_section_contents (bfd *abfd, - asection *sec, - const void * data, - file_ptr offset, - bfd_size_type size) -{ - if (size == 0) - return TRUE; - - if (! abfd->output_has_begun) - { - bfd_boolean found_low; - bfd_vma low; - asection *s; - - /* The lowest section LMA sets the virtual address of the start - of the file. We use this to set the file position of all the - sections. */ - found_low = FALSE; - low = 0; - for (s = abfd->sections; s != NULL; s = s->next) - if (((s->flags - & (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD)) - == (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC)) - && (s->size > 0) - && (! found_low || s->lma < low)) - { - low = s->lma; - found_low = TRUE; - } - - for (s = abfd->sections; s != NULL; s = s->next) - { - s->filepos = s->lma - low; - - /* Skip following warning check for sections that will not - occupy file space. */ - if ((s->flags - & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD)) - != (SEC_HAS_CONTENTS | SEC_ALLOC) - || (s->size == 0)) - continue; - - /* If attempting to generate a binary file from a bfd with - LMA's all over the place, huge (sparse?) binary files may - result. This condition attempts to detect this situation - and print a warning. Better heuristics would be nice to - have. */ - - if (s->filepos < 0) - (*_bfd_error_handler) - (_("Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."), - bfd_get_section_name (abfd, s), - (unsigned long) s->filepos); - } - - abfd->output_has_begun = TRUE; - } - - /* We don't want to output anything for a section that is neither - loaded nor allocated. The contents of such a section are not - meaningful in the binary format. */ - if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0) - return TRUE; - if ((sec->flags & SEC_NEVER_LOAD) != 0) - return TRUE; - - return _bfd_generic_set_section_contents (abfd, sec, data, offset, size); -} - -/* No space is required for header information. */ - -static int -binary_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - return 0; -} - -#define binary_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define binary_bfd_relax_section bfd_generic_relax_section -#define binary_bfd_gc_sections bfd_generic_gc_sections -#define binary_bfd_lookup_section_flags bfd_generic_lookup_section_flags -#define binary_bfd_merge_sections bfd_generic_merge_sections -#define binary_bfd_is_group_section bfd_generic_is_group_section -#define binary_bfd_discard_group bfd_generic_discard_group -#define binary_section_already_linked _bfd_generic_section_already_linked -#define binary_bfd_define_common_symbol bfd_generic_define_common_symbol -#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#define binary_bfd_link_just_syms _bfd_generic_link_just_syms -#define binary_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -#define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define binary_bfd_final_link _bfd_generic_final_link -#define binary_bfd_link_split_section _bfd_generic_link_split_section -#define binary_get_section_contents_in_window _bfd_generic_get_section_contents_in_window - -const bfd_target binary_vec = -{ - "binary", /* name */ - bfd_target_unknown_flavour, /* flavour */ - BFD_ENDIAN_UNKNOWN, /* byteorder */ - BFD_ENDIAN_UNKNOWN, /* header_byteorder */ - EXEC_P, /* object_flags */ - (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA - | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */ - 0, /* symbol_leading_char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 255, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - { /* bfd_check_format */ - _bfd_dummy_target, - binary_object_p, - _bfd_dummy_target, - _bfd_dummy_target, - }, - { /* bfd_set_format */ - bfd_false, - binary_mkobject, - bfd_false, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - bfd_true, - bfd_false, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (binary), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (binary), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (binary), - BFD_JUMP_TABLE_LINK (binary), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; diff --git a/contrib/binutils-2.22/bfd/cache.c b/contrib/binutils-2.22/bfd/cache.c deleted file mode 100644 index 5ddbbe470a..0000000000 --- a/contrib/binutils-2.22/bfd/cache.c +++ /dev/null @@ -1,619 +0,0 @@ -/* BFD library -- caching of file descriptors. - - Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, - 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. - - Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - File caching - - The file caching mechanism is embedded within BFD and allows - the application to open as many BFDs as it wants without - regard to the underlying operating system's file descriptor - limit (often as low as 20 open files). The module in - <> maintains a least recently used list of - <> files, and exports the name - <>, which runs around and makes sure that - the required BFD is open. If not, then it chooses a file to - close, closes it and opens the one wanted, returning its file - handle. - -SUBSECTION - Caching functions -*/ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "libiberty.h" -#include "bfd_stdint.h" - -#ifdef HAVE_MMAP -#include -#endif - -/* In some cases we can optimize cache operation when reopening files. - For instance, a flush is entirely unnecessary if the file is already - closed, so a flush would use CACHE_NO_OPEN. Similarly, a seek using - SEEK_SET or SEEK_END need not first seek to the current position. - For stat we ignore seek errors, just in case the file has changed - while we weren't looking. If it has, then it's possible that the - file is shorter and we don't want a seek error to prevent us doing - the stat. */ -enum cache_flag { - CACHE_NORMAL = 0, - CACHE_NO_OPEN = 1, - CACHE_NO_SEEK = 2, - CACHE_NO_SEEK_ERROR = 4 -}; - -/* The maximum number of files which the cache will keep open at - one time. */ - -#define BFD_CACHE_MAX_OPEN 10 - -/* The number of BFD files we have open. */ - -static int open_files; - -/* Zero, or a pointer to the topmost BFD on the chain. This is - used by the <> macro in @file{libbfd.h} to - determine when it can avoid a function call. */ - -static bfd *bfd_last_cache = NULL; - -/* Insert a BFD into the cache. */ - -static void -insert (bfd *abfd) -{ - if (bfd_last_cache == NULL) - { - abfd->lru_next = abfd; - abfd->lru_prev = abfd; - } - else - { - abfd->lru_next = bfd_last_cache; - abfd->lru_prev = bfd_last_cache->lru_prev; - abfd->lru_prev->lru_next = abfd; - abfd->lru_next->lru_prev = abfd; - } - bfd_last_cache = abfd; -} - -/* Remove a BFD from the cache. */ - -static void -snip (bfd *abfd) -{ - abfd->lru_prev->lru_next = abfd->lru_next; - abfd->lru_next->lru_prev = abfd->lru_prev; - if (abfd == bfd_last_cache) - { - bfd_last_cache = abfd->lru_next; - if (abfd == bfd_last_cache) - bfd_last_cache = NULL; - } -} - -/* Close a BFD and remove it from the cache. */ - -static bfd_boolean -bfd_cache_delete (bfd *abfd) -{ - bfd_boolean ret; - - if (fclose ((FILE *) abfd->iostream) == 0) - ret = TRUE; - else - { - ret = FALSE; - bfd_set_error (bfd_error_system_call); - } - - snip (abfd); - - abfd->iostream = NULL; - --open_files; - - return ret; -} - -/* We need to open a new file, and the cache is full. Find the least - recently used cacheable BFD and close it. */ - -static bfd_boolean -close_one (void) -{ - register bfd *to_kill; - - if (bfd_last_cache == NULL) - to_kill = NULL; - else - { - for (to_kill = bfd_last_cache->lru_prev; - ! to_kill->cacheable; - to_kill = to_kill->lru_prev) - { - if (to_kill == bfd_last_cache) - { - to_kill = NULL; - break; - } - } - } - - if (to_kill == NULL) - { - /* There are no open cacheable BFD's. */ - return TRUE; - } - - to_kill->where = real_ftell ((FILE *) to_kill->iostream); - - return bfd_cache_delete (to_kill); -} - -/* Check to see if the required BFD is the same as the last one - looked up. If so, then it can use the stream in the BFD with - impunity, since it can't have changed since the last lookup; - otherwise, it has to perform the complicated lookup function. */ - -#define bfd_cache_lookup(x, flag) \ - ((x) == bfd_last_cache \ - ? (FILE *) (bfd_last_cache->iostream) \ - : bfd_cache_lookup_worker (x, flag)) - -/* Called when the macro <> fails to find a - quick answer. Find a file descriptor for @var{abfd}. If - necessary, it open it. If there are already more than - <> files open, it tries to close one first, to - avoid running out of file descriptors. It will return NULL - if it is unable to (re)open the @var{abfd}. */ - -static FILE * -bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag) -{ - bfd *orig_bfd = abfd; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); - - if (abfd->my_archive) - abfd = abfd->my_archive; - - if (abfd->iostream != NULL) - { - /* Move the file to the start of the cache. */ - if (abfd != bfd_last_cache) - { - snip (abfd); - insert (abfd); - } - return (FILE *) abfd->iostream; - } - - if (flag & CACHE_NO_OPEN) - return NULL; - - if (bfd_open_file (abfd) == NULL) - ; - else if (!(flag & CACHE_NO_SEEK) - && real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0 - && !(flag & CACHE_NO_SEEK_ERROR)) - bfd_set_error (bfd_error_system_call); - else - return (FILE *) abfd->iostream; - - (*_bfd_error_handler) (_("reopening %B: %s\n"), - orig_bfd, bfd_errmsg (bfd_get_error ())); - return NULL; -} - -static file_ptr -cache_btell (struct bfd *abfd) -{ - FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN); - if (f == NULL) - return abfd->where; - return real_ftell (f); -} - -static int -cache_bseek (struct bfd *abfd, file_ptr offset, int whence) -{ - FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL); - if (f == NULL) - return -1; - return real_fseek (f, offset, whence); -} - -/* Note that archive entries don't have streams; they share their parent's. - This allows someone to play with the iostream behind BFD's back. - - Also, note that the origin pointer points to the beginning of a file's - contents (0 for non-archive elements). For archive entries this is the - first octet in the file, NOT the beginning of the archive header. */ - -static file_ptr -cache_bread_1 (struct bfd *abfd, void *buf, file_ptr nbytes) -{ - FILE *f; - file_ptr nread; - /* FIXME - this looks like an optimization, but it's really to cover - up for a feature of some OSs (not solaris - sigh) that - ld/pe-dll.c takes advantage of (apparently) when it creates BFDs - internally and tries to link against them. BFD seems to be smart - enough to realize there are no symbol records in the "file" that - doesn't exist but attempts to read them anyway. On Solaris, - attempting to read zero bytes from a NULL file results in a core - dump, but on other platforms it just returns zero bytes read. - This makes it to something reasonable. - DJ */ - if (nbytes == 0) - return 0; - - f = bfd_cache_lookup (abfd, CACHE_NORMAL); - if (f == NULL) - return 0; - -#if defined (__VAX) && defined (VMS) - /* Apparently fread on Vax VMS does not keep the record length - information. */ - nread = read (fileno (f), buf, nbytes); - /* Set bfd_error if we did not read as much data as we expected. If - the read failed due to an error set the bfd_error_system_call, - else set bfd_error_file_truncated. */ - if (nread == (file_ptr)-1) - { - bfd_set_error (bfd_error_system_call); - return -1; - } -#else - nread = fread (buf, 1, nbytes, f); - /* Set bfd_error if we did not read as much data as we expected. If - the read failed due to an error set the bfd_error_system_call, - else set bfd_error_file_truncated. */ - if (nread < nbytes && ferror (f)) - { - bfd_set_error (bfd_error_system_call); - return -1; - } -#endif - if (nread < nbytes) - /* This may or may not be an error, but in case the calling code - bails out because of it, set the right error code. */ - bfd_set_error (bfd_error_file_truncated); - return nread; -} - -static file_ptr -cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes) -{ - file_ptr nread = 0; - - /* Some filesystems are unable to handle reads that are too large - (for instance, NetApp shares with oplocks turned off). To avoid - hitting this limitation, we read the buffer in chunks of 8MB max. */ - while (nread < nbytes) - { - const file_ptr max_chunk_size = 0x800000; - file_ptr chunk_size = nbytes - nread; - file_ptr chunk_nread; - - if (chunk_size > max_chunk_size) - chunk_size = max_chunk_size; - - chunk_nread = cache_bread_1 (abfd, (char *) buf + nread, chunk_size); - - /* Update the nread count. - - We just have to be careful of the case when cache_bread_1 returns - a negative count: If this is our first read, then set nread to - that negative count in order to return that negative value to the - caller. Otherwise, don't add it to our total count, or we would - end up returning a smaller number of bytes read than we actually - did. */ - if (nread == 0 || chunk_nread > 0) - nread += chunk_nread; - - if (chunk_nread < chunk_size) - break; - } - - return nread; -} - -static file_ptr -cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes) -{ - file_ptr nwrite; - FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL); - - if (f == NULL) - return 0; - nwrite = fwrite (where, 1, nbytes, f); - if (nwrite < nbytes && ferror (f)) - { - bfd_set_error (bfd_error_system_call); - return -1; - } - return nwrite; -} - -static int -cache_bclose (struct bfd *abfd) -{ - return bfd_cache_close (abfd); -} - -static int -cache_bflush (struct bfd *abfd) -{ - int sts; - FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN); - - if (f == NULL) - return 0; - sts = fflush (f); - if (sts < 0) - bfd_set_error (bfd_error_system_call); - return sts; -} - -static int -cache_bstat (struct bfd *abfd, struct stat *sb) -{ - int sts; - FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); - - if (f == NULL) - return -1; - sts = fstat (fileno (f), sb); - if (sts < 0) - bfd_set_error (bfd_error_system_call); - return sts; -} - -static void * -cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, - void *addr ATTRIBUTE_UNUSED, - bfd_size_type len ATTRIBUTE_UNUSED, - int prot ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, - file_ptr offset ATTRIBUTE_UNUSED, - void **map_addr ATTRIBUTE_UNUSED, - bfd_size_type *map_len ATTRIBUTE_UNUSED) -{ - void *ret = (void *) -1; - - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); -#ifdef HAVE_MMAP - else - { - static uintptr_t pagesize_m1; - FILE *f; - file_ptr pg_offset; - bfd_size_type pg_len; - - f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); - if (f == NULL) - return ret; - - if (pagesize_m1 == 0) - pagesize_m1 = getpagesize () - 1; - - /* Handle archive members. */ - if (abfd->my_archive != NULL) - offset += abfd->origin; - - /* Align. */ - pg_offset = offset & ~pagesize_m1; - pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1; - - ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset); - if (ret == (void *) -1) - bfd_set_error (bfd_error_system_call); - else - { - *map_addr = ret; - *map_len = pg_len; - ret += offset & pagesize_m1; - } - } -#endif - - return ret; -} - -static const struct bfd_iovec cache_iovec = -{ - &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek, - &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap -}; - -/* -INTERNAL_FUNCTION - bfd_cache_init - -SYNOPSIS - bfd_boolean bfd_cache_init (bfd *abfd); - -DESCRIPTION - Add a newly opened BFD to the cache. -*/ - -bfd_boolean -bfd_cache_init (bfd *abfd) -{ - BFD_ASSERT (abfd->iostream != NULL); - if (open_files >= BFD_CACHE_MAX_OPEN) - { - if (! close_one ()) - return FALSE; - } - abfd->iovec = &cache_iovec; - insert (abfd); - ++open_files; - return TRUE; -} - -/* -INTERNAL_FUNCTION - bfd_cache_close - -SYNOPSIS - bfd_boolean bfd_cache_close (bfd *abfd); - -DESCRIPTION - Remove the BFD @var{abfd} from the cache. If the attached file is open, - then close it too. - -RETURNS - <> is returned if closing the file fails, <> is - returned if all is well. -*/ - -bfd_boolean -bfd_cache_close (bfd *abfd) -{ - if (abfd->iovec != &cache_iovec) - return TRUE; - - if (abfd->iostream == NULL) - /* Previously closed. */ - return TRUE; - - return bfd_cache_delete (abfd); -} - -/* -FUNCTION - bfd_cache_close_all - -SYNOPSIS - bfd_boolean bfd_cache_close_all (void); - -DESCRIPTION - Remove all BFDs from the cache. If the attached file is open, - then close it too. - -RETURNS - <> is returned if closing one of the file fails, <> is - returned if all is well. -*/ - -bfd_boolean -bfd_cache_close_all () -{ - bfd_boolean ret = TRUE; - - while (bfd_last_cache != NULL) - ret &= bfd_cache_close (bfd_last_cache); - - return ret; -} - -/* -INTERNAL_FUNCTION - bfd_open_file - -SYNOPSIS - FILE* bfd_open_file (bfd *abfd); - -DESCRIPTION - Call the OS to open a file for @var{abfd}. Return the <> - (possibly <>) that results from this operation. Set up the - BFD so that future accesses know the file is open. If the <> - returned is <>, then it won't have been put in the - cache, so it won't have to be removed from it. -*/ - -FILE * -bfd_open_file (bfd *abfd) -{ - abfd->cacheable = TRUE; /* Allow it to be closed later. */ - - if (open_files >= BFD_CACHE_MAX_OPEN) - { - if (! close_one ()) - return NULL; - } - - switch (abfd->direction) - { - case read_direction: - case no_direction: - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RB); - break; - case both_direction: - case write_direction: - if (abfd->opened_once) - { - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RUB); - if (abfd->iostream == NULL) - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); - } - else - { - /* Create the file. - - Some operating systems won't let us overwrite a running - binary. For them, we want to unlink the file first. - - However, gcc 2.95 will create temporary files using - O_EXCL and tight permissions to prevent other users from - substituting other .o files during the compilation. gcc - will then tell the assembler to use the newly created - file as an output file. If we unlink the file here, we - open a brief window when another user could still - substitute a file. - - So we unlink the output file if and only if it has - non-zero size. */ -#ifndef __MSDOS__ - /* Don't do this for MSDOS: it doesn't care about overwriting - a running binary, but if this file is already open by - another BFD, we will be in deep trouble if we delete an - open file. In fact, objdump does just that if invoked with - the --info option. */ - struct stat s; - - if (stat (abfd->filename, &s) == 0 && s.st_size != 0) - unlink_if_ordinary (abfd->filename); -#endif - abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); - abfd->opened_once = TRUE; - } - break; - } - - if (abfd->iostream == NULL) - bfd_set_error (bfd_error_system_call); - else - { - if (! bfd_cache_init (abfd)) - return NULL; - } - - return (FILE *) abfd->iostream; -} diff --git a/contrib/binutils-2.22/bfd/coffgen.c b/contrib/binutils-2.22/bfd/coffgen.c deleted file mode 100644 index bbb0acc1c6..0000000000 --- a/contrib/binutils-2.22/bfd/coffgen.c +++ /dev/null @@ -1,2468 +0,0 @@ -/* Support for the generic parts of COFF, for BFD. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* Most of this hacked by Steve Chamberlain, sac@cygnus.com. - Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ - -/* This file contains COFF code that is not dependent on any - particular COFF target. There is only one version of this file in - libbfd.a, so no target specific code may be put in here. Or, to - put it another way, - - ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE ********** - - If you need to add some target specific behaviour, add a new hook - function to bfd_coff_backend_data. - - Some of these functions are also called by the ECOFF routines. - Those functions may not use any COFF specific information, such as - coff_data (abfd). */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* Take a section header read from a coff file (in HOST byte order), - and make a BFD "section" out of it. This is used by ECOFF. */ - -static bfd_boolean -make_a_section_from_file (bfd *abfd, - struct internal_scnhdr *hdr, - unsigned int target_index) -{ - asection *return_section; - char *name; - bfd_boolean result = TRUE; - flagword flags; - - name = NULL; - - /* Handle long section names as in PE. On reading, we want to - accept long names if the format permits them at all, regardless - of the current state of the flag that dictates if we would generate - them in outputs; this construct checks if that is the case by - attempting to set the flag, without changing its state; the call - will fail for formats that do not support long names at all. */ - if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd)) - && hdr->s_name[0] == '/') - { - char buf[SCNNMLEN]; - long strindex; - char *p; - const char *strings; - - /* Flag that this BFD uses long names, even though the format might - expect them to be off by default. This won't directly affect the - format of any output BFD created from this one, but the information - can be used to decide what to do. */ - bfd_coff_set_long_section_names (abfd, TRUE); - memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1); - buf[SCNNMLEN - 1] = '\0'; - strindex = strtol (buf, &p, 10); - if (*p == '\0' && strindex >= 0) - { - strings = _bfd_coff_read_string_table (abfd); - if (strings == NULL) - return FALSE; - /* FIXME: For extra safety, we should make sure that - strindex does not run us past the end, but right now we - don't know the length of the string table. */ - strings += strindex; - name = (char *) bfd_alloc (abfd, - (bfd_size_type) strlen (strings) + 1); - if (name == NULL) - return FALSE; - strcpy (name, strings); - } - } - - if (name == NULL) - { - /* Assorted wastage to null-terminate the name, thanks AT&T! */ - name = (char *) bfd_alloc (abfd, - (bfd_size_type) sizeof (hdr->s_name) + 1); - if (name == NULL) - return FALSE; - strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); - name[sizeof (hdr->s_name)] = 0; - } - - return_section = bfd_make_section_anyway (abfd, name); - if (return_section == NULL) - return FALSE; - - return_section->vma = hdr->s_vaddr; - return_section->lma = hdr->s_paddr; - return_section->size = hdr->s_size; - return_section->filepos = hdr->s_scnptr; - return_section->rel_filepos = hdr->s_relptr; - return_section->reloc_count = hdr->s_nreloc; - - bfd_coff_set_alignment_hook (abfd, return_section, hdr); - - return_section->line_filepos = hdr->s_lnnoptr; - - return_section->lineno_count = hdr->s_nlnno; - return_section->userdata = NULL; - return_section->next = NULL; - return_section->target_index = target_index; - - if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section, - & flags)) - result = FALSE; - - return_section->flags = flags; - - /* At least on i386-coff, the line number count for a shared library - section must be ignored. */ - if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) - return_section->lineno_count = 0; - - if (hdr->s_nreloc != 0) - return_section->flags |= SEC_RELOC; - /* FIXME: should this check 'hdr->s_size > 0'. */ - if (hdr->s_scnptr != 0) - return_section->flags |= SEC_HAS_CONTENTS; - - return result; -} - -/* Read in a COFF object and make it into a BFD. This is used by - ECOFF as well. */ - -static const bfd_target * -coff_real_object_p (bfd *abfd, - unsigned nscns, - struct internal_filehdr *internal_f, - struct internal_aouthdr *internal_a) -{ - flagword oflags = abfd->flags; - bfd_vma ostart = bfd_get_start_address (abfd); - void * tdata; - void * tdata_save; - bfd_size_type readsize; /* Length of file_info. */ - unsigned int scnhsz; - char *external_sections; - - if (!(internal_f->f_flags & F_RELFLG)) - abfd->flags |= HAS_RELOC; - if ((internal_f->f_flags & F_EXEC)) - abfd->flags |= EXEC_P; - if (!(internal_f->f_flags & F_LNNO)) - abfd->flags |= HAS_LINENO; - if (!(internal_f->f_flags & F_LSYMS)) - abfd->flags |= HAS_LOCALS; - - /* FIXME: How can we set D_PAGED correctly? */ - if ((internal_f->f_flags & F_EXEC) != 0) - abfd->flags |= D_PAGED; - - bfd_get_symcount (abfd) = internal_f->f_nsyms; - if (internal_f->f_nsyms) - abfd->flags |= HAS_SYMS; - - if (internal_a != (struct internal_aouthdr *) NULL) - bfd_get_start_address (abfd) = internal_a->entry; - else - bfd_get_start_address (abfd) = 0; - - /* Set up the tdata area. ECOFF uses its own routine, and overrides - abfd->flags. */ - tdata_save = abfd->tdata.any; - tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a); - if (tdata == NULL) - goto fail2; - - scnhsz = bfd_coff_scnhsz (abfd); - readsize = (bfd_size_type) nscns * scnhsz; - external_sections = (char *) bfd_alloc (abfd, readsize); - if (!external_sections) - goto fail; - - if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize) - goto fail; - - /* Set the arch/mach *before* swapping in sections; section header swapping - may depend on arch/mach info. */ - if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f)) - goto fail; - - /* Now copy data as required; construct all asections etc. */ - if (nscns != 0) - { - unsigned int i; - for (i = 0; i < nscns; i++) - { - struct internal_scnhdr tmp; - bfd_coff_swap_scnhdr_in (abfd, - (void *) (external_sections + i * scnhsz), - (void *) & tmp); - if (! make_a_section_from_file (abfd, &tmp, i + 1)) - goto fail; - } - } - - return abfd->xvec; - - fail: - bfd_release (abfd, tdata); - fail2: - abfd->tdata.any = tdata_save; - abfd->flags = oflags; - bfd_get_start_address (abfd) = ostart; - return (const bfd_target *) NULL; -} - -/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is - not a COFF file. This is also used by ECOFF. */ - -const bfd_target * -coff_object_p (bfd *abfd) -{ - bfd_size_type filhsz; - bfd_size_type aoutsz; - unsigned int nscns; - void * filehdr; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - /* Figure out how much to read. */ - filhsz = bfd_coff_filhsz (abfd); - aoutsz = bfd_coff_aoutsz (abfd); - - filehdr = bfd_alloc (abfd, filhsz); - if (filehdr == NULL) - return NULL; - if (bfd_bread (filehdr, filhsz, abfd) != filhsz) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - bfd_release (abfd, filehdr); - return NULL; - } - bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f); - bfd_release (abfd, filehdr); - - /* The XCOFF format has two sizes for the f_opthdr. SMALL_AOUTSZ - (less than aoutsz) used in object files and AOUTSZ (equal to - aoutsz) in executables. The bfd_coff_swap_aouthdr_in function - expects this header to be aoutsz bytes in length, so we use that - value in the call to bfd_alloc below. But we must be careful to - only read in f_opthdr bytes in the call to bfd_bread. We should - also attempt to catch corrupt or non-COFF binaries with a strange - value for f_opthdr. */ - if (! bfd_coff_bad_format_hook (abfd, &internal_f) - || internal_f.f_opthdr > aoutsz) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - nscns = internal_f.f_nscns; - - if (internal_f.f_opthdr) - { - void * opthdr; - - opthdr = bfd_alloc (abfd, aoutsz); - if (opthdr == NULL) - return NULL; - if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) - != internal_f.f_opthdr) - { - bfd_release (abfd, opthdr); - return NULL; - } - bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a); - bfd_release (abfd, opthdr); - } - - return coff_real_object_p (abfd, nscns, &internal_f, - (internal_f.f_opthdr != 0 - ? &internal_a - : (struct internal_aouthdr *) NULL)); -} - -/* Get the BFD section from a COFF symbol section number. */ - -asection * -coff_section_from_bfd_index (bfd *abfd, int section_index) -{ - struct bfd_section *answer = abfd->sections; - - if (section_index == N_ABS) - return bfd_abs_section_ptr; - if (section_index == N_UNDEF) - return bfd_und_section_ptr; - if (section_index == N_DEBUG) - return bfd_abs_section_ptr; - - while (answer) - { - if (answer->target_index == section_index) - return answer; - answer = answer->next; - } - - /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a - has a bad symbol table in biglitpow.o. */ - return bfd_und_section_ptr; -} - -/* Get the upper bound of a COFF symbol table. */ - -long -coff_get_symtab_upper_bound (bfd *abfd) -{ - if (!bfd_coff_slurp_symbol_table (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *)); -} - -/* Canonicalize a COFF symbol table. */ - -long -coff_canonicalize_symtab (bfd *abfd, asymbol **alocation) -{ - unsigned int counter; - coff_symbol_type *symbase; - coff_symbol_type **location = (coff_symbol_type **) alocation; - - if (!bfd_coff_slurp_symbol_table (abfd)) - return -1; - - symbase = obj_symbols (abfd); - counter = bfd_get_symcount (abfd); - while (counter-- > 0) - *location++ = symbase++; - - *location = NULL; - - return bfd_get_symcount (abfd); -} - -/* Get the name of a symbol. The caller must pass in a buffer of size - >= SYMNMLEN + 1. */ - -const char * -_bfd_coff_internal_syment_name (bfd *abfd, - const struct internal_syment *sym, - char *buf) -{ - /* FIXME: It's not clear this will work correctly if sizeof - (_n_zeroes) != 4. */ - if (sym->_n._n_n._n_zeroes != 0 - || sym->_n._n_n._n_offset == 0) - { - memcpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - return buf; - } - else - { - const char *strings; - - BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE); - strings = obj_coff_strings (abfd); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (abfd); - if (strings == NULL) - return NULL; - } - return strings + sym->_n._n_n._n_offset; - } -} - -/* Read in and swap the relocs. This returns a buffer holding the - relocs for section SEC in file ABFD. If CACHE is TRUE and - INTERNAL_RELOCS is NULL, the relocs read in will be saved in case - the function is called again. If EXTERNAL_RELOCS is not NULL, it - is a buffer large enough to hold the unswapped relocs. If - INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold - the swapped relocs. If REQUIRE_INTERNAL is TRUE, then the return - value must be INTERNAL_RELOCS. The function returns NULL on error. */ - -struct internal_reloc * -_bfd_coff_read_internal_relocs (bfd *abfd, - asection *sec, - bfd_boolean cache, - bfd_byte *external_relocs, - bfd_boolean require_internal, - struct internal_reloc *internal_relocs) -{ - bfd_size_type relsz; - bfd_byte *free_external = NULL; - struct internal_reloc *free_internal = NULL; - bfd_byte *erel; - bfd_byte *erel_end; - struct internal_reloc *irel; - bfd_size_type amt; - - if (sec->reloc_count == 0) - return internal_relocs; /* Nothing to do. */ - - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->relocs != NULL) - { - if (! require_internal) - return coff_section_data (abfd, sec)->relocs; - memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs, - sec->reloc_count * sizeof (struct internal_reloc)); - return internal_relocs; - } - - relsz = bfd_coff_relsz (abfd); - - amt = sec->reloc_count * relsz; - if (external_relocs == NULL) - { - free_external = (bfd_byte *) bfd_malloc (amt); - if (free_external == NULL) - goto error_return; - external_relocs = free_external; - } - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || bfd_bread (external_relocs, amt, abfd) != amt) - goto error_return; - - if (internal_relocs == NULL) - { - amt = sec->reloc_count; - amt *= sizeof (struct internal_reloc); - free_internal = (struct internal_reloc *) bfd_malloc (amt); - if (free_internal == NULL) - goto error_return; - internal_relocs = free_internal; - } - - /* Swap in the relocs. */ - erel = external_relocs; - erel_end = erel + relsz * sec->reloc_count; - irel = internal_relocs; - for (; erel < erel_end; erel += relsz, irel++) - bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel); - - if (free_external != NULL) - { - free (free_external); - free_external = NULL; - } - - if (cache && free_internal != NULL) - { - if (coff_section_data (abfd, sec) == NULL) - { - amt = sizeof (struct coff_section_tdata); - sec->used_by_bfd = bfd_zalloc (abfd, amt); - if (sec->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, sec)->contents = NULL; - } - coff_section_data (abfd, sec)->relocs = free_internal; - } - - return internal_relocs; - - error_return: - if (free_external != NULL) - free (free_external); - if (free_internal != NULL) - free (free_internal); - return NULL; -} - -/* Set lineno_count for the output sections of a COFF file. */ - -int -coff_count_linenumbers (bfd *abfd) -{ - unsigned int limit = bfd_get_symcount (abfd); - unsigned int i; - int total = 0; - asymbol **p; - asection *s; - - if (limit == 0) - { - /* This may be from the backend linker, in which case the - lineno_count in the sections is correct. */ - for (s = abfd->sections; s != NULL; s = s->next) - total += s->lineno_count; - return total; - } - - for (s = abfd->sections; s != NULL; s = s->next) - BFD_ASSERT (s->lineno_count == 0); - - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *q_maybe = *p; - - if (bfd_family_coff (bfd_asymbol_bfd (q_maybe))) - { - coff_symbol_type *q = coffsymbol (q_maybe); - - /* The AIX 4.1 compiler can sometimes generate line numbers - attached to debugging symbols. We try to simply ignore - those here. */ - if (q->lineno != NULL - && q->symbol.section->owner != NULL) - { - /* This symbol has line numbers. Increment the owning - section's linenumber count. */ - alent *l = q->lineno; - - do - { - asection * sec = q->symbol.section->output_section; - - /* Do not try to update fields in read-only sections. */ - if (! bfd_is_const_section (sec)) - sec->lineno_count ++; - - ++total; - ++l; - } - while (l->line_number != 0); - } - } - } - - return total; -} - -/* Takes a bfd and a symbol, returns a pointer to the coff specific - area of the symbol if there is one. */ - -coff_symbol_type * -coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED, - asymbol *symbol) -{ - if (!bfd_family_coff (bfd_asymbol_bfd (symbol))) - return (coff_symbol_type *) NULL; - - if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL) - return (coff_symbol_type *) NULL; - - return (coff_symbol_type *) symbol; -} - -static void -fixup_symbol_value (bfd *abfd, - coff_symbol_type *coff_symbol_ptr, - struct internal_syment *syment) -{ - /* Normalize the symbol flags. */ - if (coff_symbol_ptr->symbol.section - && bfd_is_com_section (coff_symbol_ptr->symbol.section)) - { - /* A common symbol is undefined with a value. */ - syment->n_scnum = N_UNDEF; - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0 - && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0) - { - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if (bfd_is_und_section (coff_symbol_ptr->symbol.section)) - { - syment->n_scnum = N_UNDEF; - syment->n_value = 0; - } - /* FIXME: Do we need to handle the absolute section here? */ - else - { - if (coff_symbol_ptr->symbol.section) - { - syment->n_scnum = - coff_symbol_ptr->symbol.section->output_section->target_index; - - syment->n_value = (coff_symbol_ptr->symbol.value - + coff_symbol_ptr->symbol.section->output_offset); - if (! obj_pe (abfd)) - { - syment->n_value += (syment->n_sclass == C_STATLAB) - ? coff_symbol_ptr->symbol.section->output_section->lma - : coff_symbol_ptr->symbol.section->output_section->vma; - } - } - else - { - BFD_ASSERT (0); - /* This can happen, but I don't know why yet (steve@cygnus.com) */ - syment->n_scnum = N_ABS; - syment->n_value = coff_symbol_ptr->symbol.value; - } - } -} - -/* Run through all the symbols in the symbol table and work out what - their indexes into the symbol table will be when output. - - Coff requires that each C_FILE symbol points to the next one in the - chain, and that the last one points to the first external symbol. We - do that here too. */ - -bfd_boolean -coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) -{ - unsigned int symbol_count = bfd_get_symcount (bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int native_index = 0; - struct internal_syment *last_file = NULL; - unsigned int symbol_index; - - /* COFF demands that undefined symbols come after all other symbols. - Since we don't need to impose this extra knowledge on all our - client programs, deal with that here. Sort the symbol table; - just move the undefined symbols to the end, leaving the rest - alone. The O'Reilly book says that defined global symbols come - at the end before the undefined symbols, so we do that here as - well. */ - /* @@ Do we have some condition we could test for, so we don't always - have to do this? I don't think relocatability is quite right, but - I'm not certain. [raeburn:19920508.1711EST] */ - { - asymbol **newsyms; - unsigned int i; - bfd_size_type amt; - - amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); - newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt); - if (!newsyms) - return FALSE; - bfd_ptr->outsymbols = newsyms; - for (i = 0; i < symbol_count; i++) - if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0 - || (!bfd_is_und_section (symbol_ptr_ptr[i]->section) - && !bfd_is_com_section (symbol_ptr_ptr[i]->section) - && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0 - || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) - == 0)))) - *newsyms++ = symbol_ptr_ptr[i]; - - for (i = 0; i < symbol_count; i++) - if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 - && !bfd_is_und_section (symbol_ptr_ptr[i]->section) - && (bfd_is_com_section (symbol_ptr_ptr[i]->section) - || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0 - && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK)) - != 0)))) - *newsyms++ = symbol_ptr_ptr[i]; - - *first_undef = newsyms - bfd_ptr->outsymbols; - - for (i = 0; i < symbol_count; i++) - if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0 - && bfd_is_und_section (symbol_ptr_ptr[i]->section)) - *newsyms++ = symbol_ptr_ptr[i]; - *newsyms = (asymbol *) NULL; - symbol_ptr_ptr = bfd_ptr->outsymbols; - } - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; - if (coff_symbol_ptr && coff_symbol_ptr->native) - { - combined_entry_type *s = coff_symbol_ptr->native; - int i; - - if (s->u.syment.n_sclass == C_FILE) - { - if (last_file != NULL) - last_file->n_value = native_index; - last_file = &(s->u.syment); - } - else - /* Modify the symbol values according to their section and - type. */ - fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment)); - - for (i = 0; i < s->u.syment.n_numaux + 1; i++) - s[i].offset = native_index++; - } - else - native_index++; - } - - obj_conv_table_size (bfd_ptr) = native_index; - - return TRUE; -} - -/* Run thorough the symbol table again, and fix it so that all - pointers to entries are changed to the entries' index in the output - symbol table. */ - -void -coff_mangle_symbols (bfd *bfd_ptr) -{ - unsigned int symbol_count = bfd_get_symcount (bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int symbol_index; - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = - coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - - if (coff_symbol_ptr && coff_symbol_ptr->native) - { - int i; - combined_entry_type *s = coff_symbol_ptr->native; - - if (s->fix_value) - { - /* FIXME: We should use a union here. */ - s->u.syment.n_value = - (bfd_hostptr_t) ((combined_entry_type *) - ((bfd_hostptr_t) s->u.syment.n_value))->offset; - s->fix_value = 0; - } - if (s->fix_line) - { - /* The value is the offset into the line number entries - for the symbol's section. On output, the symbol's - section should be N_DEBUG. */ - s->u.syment.n_value = - (coff_symbol_ptr->symbol.section->output_section->line_filepos - + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr)); - coff_symbol_ptr->symbol.section = - coff_section_from_bfd_index (bfd_ptr, N_DEBUG); - BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING); - } - for (i = 0; i < s->u.syment.n_numaux; i++) - { - combined_entry_type *a = s + i + 1; - if (a->fix_tag) - { - a->u.auxent.x_sym.x_tagndx.l = - a->u.auxent.x_sym.x_tagndx.p->offset; - a->fix_tag = 0; - } - if (a->fix_end) - { - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; - a->fix_end = 0; - } - if (a->fix_scnlen) - { - a->u.auxent.x_csect.x_scnlen.l = - a->u.auxent.x_csect.x_scnlen.p->offset; - a->fix_scnlen = 0; - } - } - } - } -} - -static void -coff_fix_symbol_name (bfd *abfd, - asymbol *symbol, - combined_entry_type *native, - bfd_size_type *string_size_p, - asection **debug_string_section_p, - bfd_size_type *debug_string_size_p) -{ - unsigned int name_length; - union internal_auxent *auxent; - char *name = (char *) (symbol->name); - - if (name == NULL) - { - /* COFF symbols always have names, so we'll make one up. */ - symbol->name = "strange"; - name = (char *) symbol->name; - } - name_length = strlen (name); - - if (native->u.syment.n_sclass == C_FILE - && native->u.syment.n_numaux > 0) - { - unsigned int filnmlen; - - if (bfd_coff_force_symnames_in_strings (abfd)) - { - native->u.syment._n._n_n._n_offset = - (*string_size_p + STRING_SIZE_SIZE); - native->u.syment._n._n_n._n_zeroes = 0; - *string_size_p += 6; /* strlen(".file") + 1 */ - } - else - strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); - - auxent = &(native + 1)->u.auxent; - - filnmlen = bfd_coff_filnmlen (abfd); - - if (bfd_coff_long_filenames (abfd)) - { - if (name_length <= filnmlen) - strncpy (auxent->x_file.x_fname, name, filnmlen); - else - { - auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; - auxent->x_file.x_n.x_zeroes = 0; - *string_size_p += name_length + 1; - } - } - else - { - strncpy (auxent->x_file.x_fname, name, filnmlen); - if (name_length > filnmlen) - name[filnmlen] = '\0'; - } - } - else - { - if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd)) - /* This name will fit into the symbol neatly. */ - strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN); - - else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment)) - { - native->u.syment._n._n_n._n_offset = (*string_size_p - + STRING_SIZE_SIZE); - native->u.syment._n._n_n._n_zeroes = 0; - *string_size_p += name_length + 1; - } - else - { - file_ptr filepos; - bfd_byte buf[4]; - int prefix_len = bfd_coff_debug_string_prefix_length (abfd); - - /* This name should be written into the .debug section. For - some reason each name is preceded by a two byte length - and also followed by a null byte. FIXME: We assume that - the .debug section has already been created, and that it - is large enough. */ - if (*debug_string_section_p == (asection *) NULL) - *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug"); - filepos = bfd_tell (abfd); - if (prefix_len == 4) - bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf); - else - bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf); - - if (!bfd_set_section_contents (abfd, - *debug_string_section_p, - (void *) buf, - (file_ptr) *debug_string_size_p, - (bfd_size_type) prefix_len) - || !bfd_set_section_contents (abfd, - *debug_string_section_p, - (void *) symbol->name, - (file_ptr) (*debug_string_size_p - + prefix_len), - (bfd_size_type) name_length + 1)) - abort (); - if (bfd_seek (abfd, filepos, SEEK_SET) != 0) - abort (); - native->u.syment._n._n_n._n_offset = - *debug_string_size_p + prefix_len; - native->u.syment._n._n_n._n_zeroes = 0; - *debug_string_size_p += name_length + 1 + prefix_len; - } - } -} - -/* We need to keep track of the symbol index so that when we write out - the relocs we can get the index for a symbol. This method is a - hack. FIXME. */ - -#define set_index(symbol, idx) ((symbol)->udata.i = (idx)) - -/* Write a symbol out to a COFF file. */ - -static bfd_boolean -coff_write_symbol (bfd *abfd, - asymbol *symbol, - combined_entry_type *native, - bfd_vma *written, - bfd_size_type *string_size_p, - asection **debug_string_section_p, - bfd_size_type *debug_string_size_p) -{ - unsigned int numaux = native->u.syment.n_numaux; - int type = native->u.syment.n_type; - int n_sclass = (int) native->u.syment.n_sclass; - asection *output_section = symbol->section->output_section - ? symbol->section->output_section - : symbol->section; - void * buf; - bfd_size_type symesz; - - if (native->u.syment.n_sclass == C_FILE) - symbol->flags |= BSF_DEBUGGING; - - if (symbol->flags & BSF_DEBUGGING - && bfd_is_abs_section (symbol->section)) - native->u.syment.n_scnum = N_DEBUG; - - else if (bfd_is_abs_section (symbol->section)) - native->u.syment.n_scnum = N_ABS; - - else if (bfd_is_und_section (symbol->section)) - native->u.syment.n_scnum = N_UNDEF; - - else - native->u.syment.n_scnum = - output_section->target_index; - - coff_fix_symbol_name (abfd, symbol, native, string_size_p, - debug_string_section_p, debug_string_size_p); - - symesz = bfd_coff_symesz (abfd); - buf = bfd_alloc (abfd, symesz); - if (!buf) - return FALSE; - bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); - if (bfd_bwrite (buf, symesz, abfd) != symesz) - return FALSE; - bfd_release (abfd, buf); - - if (native->u.syment.n_numaux > 0) - { - bfd_size_type auxesz; - unsigned int j; - - auxesz = bfd_coff_auxesz (abfd); - buf = bfd_alloc (abfd, auxesz); - if (!buf) - return FALSE; - for (j = 0; j < native->u.syment.n_numaux; j++) - { - bfd_coff_swap_aux_out (abfd, - &((native + j + 1)->u.auxent), - type, n_sclass, (int) j, - native->u.syment.n_numaux, - buf); - if (bfd_bwrite (buf, auxesz, abfd) != auxesz) - return FALSE; - } - bfd_release (abfd, buf); - } - - /* Store the index for use when we write out the relocs. */ - set_index (symbol, *written); - - *written += numaux + 1; - return TRUE; -} - -/* Write out a symbol to a COFF file that does not come from a COFF - file originally. This symbol may have been created by the linker, - or we may be linking a non COFF file to a COFF file. */ - -static bfd_boolean -coff_write_alien_symbol (bfd *abfd, - asymbol *symbol, - bfd_vma *written, - bfd_size_type *string_size_p, - asection **debug_string_section_p, - bfd_size_type *debug_string_size_p) -{ - combined_entry_type *native; - combined_entry_type dummy; - asection *output_section = symbol->section->output_section - ? symbol->section->output_section - : symbol->section; - - native = &dummy; - native->u.syment.n_type = T_NULL; - native->u.syment.n_flags = 0; - if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (bfd_is_com_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (symbol->flags & BSF_DEBUGGING) - { - /* There isn't much point to writing out a debugging symbol - unless we are prepared to convert it into COFF debugging - format. So, we just ignore them. We must clobber the symbol - name to keep it from being put in the string table. */ - symbol->name = ""; - return TRUE; - } - else - { - native->u.syment.n_scnum = output_section->target_index; - native->u.syment.n_value = (symbol->value - + symbol->section->output_offset); - if (! obj_pe (abfd)) - native->u.syment.n_value += output_section->vma; - - /* Copy the any flags from the file header into the symbol. - FIXME: Why? */ - { - coff_symbol_type *c = coff_symbol_from (abfd, symbol); - if (c != (coff_symbol_type *) NULL) - native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; - } - } - - native->u.syment.n_type = 0; - if (symbol->flags & BSF_LOCAL) - native->u.syment.n_sclass = C_STAT; - else if (symbol->flags & BSF_WEAK) - native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; - else - native->u.syment.n_sclass = C_EXT; - native->u.syment.n_numaux = 0; - - return coff_write_symbol (abfd, symbol, native, written, string_size_p, - debug_string_section_p, debug_string_size_p); -} - -/* Write a native symbol to a COFF file. */ - -static bfd_boolean -coff_write_native_symbol (bfd *abfd, - coff_symbol_type *symbol, - bfd_vma *written, - bfd_size_type *string_size_p, - asection **debug_string_section_p, - bfd_size_type *debug_string_size_p) -{ - combined_entry_type *native = symbol->native; - alent *lineno = symbol->lineno; - - /* If this symbol has an associated line number, we must store the - symbol index in the line number field. We also tag the auxent to - point to the right place in the lineno table. */ - if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL) - { - unsigned int count = 0; - - lineno[count].u.offset = *written; - if (native->u.syment.n_numaux) - { - union internal_auxent *a = &((native + 1)->u.auxent); - - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = - symbol->symbol.section->output_section->moving_line_filepos; - } - - /* Count and relocate all other linenumbers. */ - count++; - while (lineno[count].line_number != 0) - { - lineno[count].u.offset += - (symbol->symbol.section->output_section->vma - + symbol->symbol.section->output_offset); - count++; - } - symbol->done_lineno = TRUE; - - if (! bfd_is_const_section (symbol->symbol.section->output_section)) - symbol->symbol.section->output_section->moving_line_filepos += - count * bfd_coff_linesz (abfd); - } - - return coff_write_symbol (abfd, &(symbol->symbol), native, written, - string_size_p, debug_string_section_p, - debug_string_size_p); -} - -static void -null_error_handler (const char * fmt ATTRIBUTE_UNUSED, ...) -{ -} - -/* Write out the COFF symbols. */ - -bfd_boolean -coff_write_symbols (bfd *abfd) -{ - bfd_size_type string_size; - asection *debug_string_section; - bfd_size_type debug_string_size; - unsigned int i; - unsigned int limit = bfd_get_symcount (abfd); - bfd_vma written = 0; - asymbol **p; - - string_size = 0; - debug_string_section = NULL; - debug_string_size = 0; - - /* If this target supports long section names, they must be put into - the string table. This is supported by PE. This code must - handle section names just as they are handled in - coff_write_object_contents. */ - if (bfd_coff_long_section_names (abfd)) - { - asection *o; - - for (o = abfd->sections; o != NULL; o = o->next) - { - size_t len; - - len = strlen (o->name); - if (len > SCNNMLEN) - string_size += len + 1; - } - } - - /* Seek to the right place. */ - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return FALSE; - - /* Output all the symbols we have. */ - written = 0; - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *symbol = *p; - coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); - - if (c_symbol == (coff_symbol_type *) NULL - || c_symbol->native == (combined_entry_type *) NULL) - { - if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, - &debug_string_section, - &debug_string_size)) - return FALSE; - } - else - { - if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL) - { - bfd_error_handler_type current_error_handler; - enum coff_symbol_classification sym_class; - unsigned char *n_sclass; - - /* Suppress error reporting by bfd_coff_classify_symbol. - Error messages can be generated when we are processing a local - symbol which has no associated section and we do not have to - worry about this, all we need to know is that it is local. */ - current_error_handler = bfd_set_error_handler (null_error_handler); - sym_class = bfd_coff_classify_symbol (abfd, - &c_symbol->native->u.syment); - (void) bfd_set_error_handler (current_error_handler); - - n_sclass = &c_symbol->native->u.syment.n_sclass; - - /* If the symbol class has been changed (eg objcopy/ld script/etc) - we cannot retain the existing sclass from the original symbol. - Weak symbols only have one valid sclass, so just set it always. - If it is not local class and should be, set it C_STAT. - If it is global and not classified as global, or if it is - weak (which is also classified as global), set it C_EXT. */ - - if (symbol->flags & BSF_WEAK) - *n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT; - else if (symbol->flags & BSF_LOCAL && sym_class != COFF_SYMBOL_LOCAL) - *n_sclass = C_STAT; - else if (symbol->flags & BSF_GLOBAL - && (sym_class != COFF_SYMBOL_GLOBAL -#ifdef COFF_WITH_PE - || *n_sclass == C_NT_WEAK -#endif - || *n_sclass == C_WEAKEXT)) - c_symbol->native->u.syment.n_sclass = C_EXT; - } - - if (!coff_write_native_symbol (abfd, c_symbol, &written, - &string_size, &debug_string_section, - &debug_string_size)) - return FALSE; - } - } - - obj_raw_syment_count (abfd) = written; - - /* Now write out strings. */ - if (string_size != 0) - { - unsigned int size = string_size + STRING_SIZE_SIZE; - bfd_byte buffer[STRING_SIZE_SIZE]; - -#if STRING_SIZE_SIZE == 4 - H_PUT_32 (abfd, size, buffer); -#else - #error Change H_PUT_32 -#endif - if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) - != sizeof (buffer)) - return FALSE; - - /* Handle long section names. This code must handle section - names just as they are handled in coff_write_object_contents. */ - if (bfd_coff_long_section_names (abfd)) - { - asection *o; - - for (o = abfd->sections; o != NULL; o = o->next) - { - size_t len; - - len = strlen (o->name); - if (len > SCNNMLEN) - { - if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) - != len + 1) - return FALSE; - } - } - } - - for (p = abfd->outsymbols, i = 0; - i < limit; - i++, p++) - { - asymbol *q = *p; - size_t name_length = strlen (q->name); - coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); - size_t maxlen; - - /* Figure out whether the symbol name should go in the string - table. Symbol names that are short enough are stored - directly in the syment structure. File names permit a - different, longer, length in the syment structure. On - XCOFF, some symbol names are stored in the .debug section - rather than in the string table. */ - - if (c_symbol == NULL - || c_symbol->native == NULL) - /* This is not a COFF symbol, so it certainly is not a - file name, nor does it go in the .debug section. */ - maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; - - else if (bfd_coff_symname_in_debug (abfd, - &c_symbol->native->u.syment)) - /* This symbol name is in the XCOFF .debug section. - Don't write it into the string table. */ - maxlen = name_length; - - else if (c_symbol->native->u.syment.n_sclass == C_FILE - && c_symbol->native->u.syment.n_numaux > 0) - { - if (bfd_coff_force_symnames_in_strings (abfd)) - { - if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) - return FALSE; - } - maxlen = bfd_coff_filnmlen (abfd); - } - else - maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; - - if (name_length > maxlen) - { - if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1, - abfd) != name_length + 1) - return FALSE; - } - } - } - else - { - /* We would normally not write anything here, but we'll write - out 4 so that any stupid coff reader which tries to read the - string table even when there isn't one won't croak. */ - unsigned int size = STRING_SIZE_SIZE; - bfd_byte buffer[STRING_SIZE_SIZE]; - -#if STRING_SIZE_SIZE == 4 - H_PUT_32 (abfd, size, buffer); -#else - #error Change H_PUT_32 -#endif - if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd) - != STRING_SIZE_SIZE) - return FALSE; - } - - /* Make sure the .debug section was created to be the correct size. - We should create it ourselves on the fly, but we don't because - BFD won't let us write to any section until we know how large all - the sections are. We could still do it by making another pass - over the symbols. FIXME. */ - BFD_ASSERT (debug_string_size == 0 - || (debug_string_section != (asection *) NULL - && (BFD_ALIGN (debug_string_size, - 1 << debug_string_section->alignment_power) - == debug_string_section->size))); - - return TRUE; -} - -bfd_boolean -coff_write_linenumbers (bfd *abfd) -{ - asection *s; - bfd_size_type linesz; - void * buff; - - linesz = bfd_coff_linesz (abfd); - buff = bfd_alloc (abfd, linesz); - if (!buff) - return FALSE; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (s->lineno_count) - { - asymbol **q = abfd->outsymbols; - if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0) - return FALSE; - /* Find all the linenumbers in this section. */ - while (*q) - { - asymbol *p = *q; - if (p->section->output_section == s) - { - alent *l = - BFD_SEND (bfd_asymbol_bfd (p), _get_lineno, - (bfd_asymbol_bfd (p), p)); - if (l) - { - /* Found a linenumber entry, output. */ - struct internal_lineno out; - memset ((void *) & out, 0, sizeof (out)); - out.l_lnno = 0; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) - != linesz) - return FALSE; - l++; - while (l->line_number) - { - out.l_lnno = l->line_number; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out (abfd, &out, buff); - if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) - != linesz) - return FALSE; - l++; - } - } - } - q++; - } - } - } - bfd_release (abfd, buff); - return TRUE; -} - -alent * -coff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol) -{ - return coffsymbol (symbol)->lineno; -} - -/* This function transforms the offsets into the symbol table into - pointers to syments. */ - -static void -coff_pointerize_aux (bfd *abfd, - combined_entry_type *table_base, - combined_entry_type *symbol, - unsigned int indaux, - combined_entry_type *auxent) -{ - unsigned int type = symbol->u.syment.n_type; - unsigned int n_sclass = symbol->u.syment.n_sclass; - - if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) - { - if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook) - (abfd, table_base, symbol, indaux, auxent)) - return; - } - - /* Don't bother if this is a file or a section. */ - if (n_sclass == C_STAT && type == T_NULL) - return; - if (n_sclass == C_FILE) - return; - - /* Otherwise patch up. */ -#define N_TMASK coff_data (abfd)->local_n_tmask -#define N_BTSHFT coff_data (abfd)->local_n_btshft - - if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK - || n_sclass == C_FCN) - && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) - { - auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = - table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; - auxent->fix_end = 1; - } - /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can - generate one, so we must be careful to ignore it. */ - if (auxent->u.auxent.x_sym.x_tagndx.l > 0) - { - auxent->u.auxent.x_sym.x_tagndx.p = - table_base + auxent->u.auxent.x_sym.x_tagndx.l; - auxent->fix_tag = 1; - } -} - -/* Allocate space for the ".debug" section, and read it. - We did not read the debug section until now, because - we didn't want to go to the trouble until someone needed it. */ - -static char * -build_debug_section (bfd *abfd) -{ - char *debug_section; - file_ptr position; - bfd_size_type sec_size; - - asection *sect = bfd_get_section_by_name (abfd, ".debug"); - - if (!sect) - { - bfd_set_error (bfd_error_no_debug_section); - return NULL; - } - - sec_size = sect->size; - debug_section = (char *) bfd_alloc (abfd, sec_size); - if (debug_section == NULL) - return NULL; - - /* Seek to the beginning of the `.debug' section and read it. - Save the current position first; it is needed by our caller. - Then read debug section and reset the file pointer. */ - - position = bfd_tell (abfd); - if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0 - || bfd_bread (debug_section, sec_size, abfd) != sec_size - || bfd_seek (abfd, position, SEEK_SET) != 0) - return NULL; - return debug_section; -} - -/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be - \0-terminated, but will not exceed 'maxlen' characters. The copy *will* - be \0-terminated. */ - -static char * -copy_name (bfd *abfd, char *name, size_t maxlen) -{ - size_t len; - char *newname; - - for (len = 0; len < maxlen; ++len) - if (name[len] == '\0') - break; - - if ((newname = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL) - return NULL; - - strncpy (newname, name, len); - newname[len] = '\0'; - return newname; -} - -/* Read in the external symbols. */ - -bfd_boolean -_bfd_coff_get_external_symbols (bfd *abfd) -{ - bfd_size_type symesz; - bfd_size_type size; - void * syms; - - if (obj_coff_external_syms (abfd) != NULL) - return TRUE; - - symesz = bfd_coff_symesz (abfd); - - size = obj_raw_syment_count (abfd) * symesz; - if (size == 0) - return TRUE; - - syms = bfd_malloc (size); - if (syms == NULL) - return FALSE; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_bread (syms, size, abfd) != size) - { - if (syms != NULL) - free (syms); - return FALSE; - } - - obj_coff_external_syms (abfd) = syms; - - return TRUE; -} - -/* Read in the external strings. The strings are not loaded until - they are needed. This is because we have no simple way of - detecting a missing string table in an archive. */ - -const char * -_bfd_coff_read_string_table (bfd *abfd) -{ - char extstrsize[STRING_SIZE_SIZE]; - bfd_size_type strsize; - char *strings; - file_ptr pos; - - if (obj_coff_strings (abfd) != NULL) - return obj_coff_strings (abfd); - - if (obj_sym_filepos (abfd) == 0) - { - bfd_set_error (bfd_error_no_symbols); - return NULL; - } - - pos = obj_sym_filepos (abfd); - pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); - if (bfd_seek (abfd, pos, SEEK_SET) != 0) - return NULL; - - if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd) - != sizeof extstrsize) - { - if (bfd_get_error () != bfd_error_file_truncated) - return NULL; - - /* There is no string table. */ - strsize = STRING_SIZE_SIZE; - } - else - { -#if STRING_SIZE_SIZE == 4 - strsize = H_GET_32 (abfd, extstrsize); -#else - #error Change H_GET_32 -#endif - } - - if (strsize < STRING_SIZE_SIZE) - { - (*_bfd_error_handler) - (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize); - bfd_set_error (bfd_error_bad_value); - return NULL; - } - - strings = (char *) bfd_malloc (strsize); - if (strings == NULL) - return NULL; - - if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd) - != strsize - STRING_SIZE_SIZE) - { - free (strings); - return NULL; - } - - obj_coff_strings (abfd) = strings; - - return strings; -} - -/* Free up the external symbols and strings read from a COFF file. */ - -bfd_boolean -_bfd_coff_free_symbols (bfd *abfd) -{ - if (obj_coff_external_syms (abfd) != NULL - && ! obj_coff_keep_syms (abfd)) - { - free (obj_coff_external_syms (abfd)); - obj_coff_external_syms (abfd) = NULL; - } - if (obj_coff_strings (abfd) != NULL - && ! obj_coff_keep_strings (abfd)) - { - free (obj_coff_strings (abfd)); - obj_coff_strings (abfd) = NULL; - } - return TRUE; -} - -/* Read a symbol table into freshly bfd_allocated memory, swap it, and - knit the symbol names into a normalized form. By normalized here I - mean that all symbols have an n_offset pointer that points to a null- - terminated string. */ - -combined_entry_type * -coff_get_normalized_symtab (bfd *abfd) -{ - combined_entry_type *internal; - combined_entry_type *internal_ptr; - combined_entry_type *symbol_ptr; - combined_entry_type *internal_end; - size_t symesz; - char *raw_src; - char *raw_end; - const char *string_table = NULL; - char *debug_section = NULL; - bfd_size_type size; - - if (obj_raw_syments (abfd) != NULL) - return obj_raw_syments (abfd); - - size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type); - internal = (combined_entry_type *) bfd_zalloc (abfd, size); - if (internal == NULL && size != 0) - return NULL; - internal_end = internal + obj_raw_syment_count (abfd); - - if (! _bfd_coff_get_external_symbols (abfd)) - return NULL; - - raw_src = (char *) obj_coff_external_syms (abfd); - - /* Mark the end of the symbols. */ - symesz = bfd_coff_symesz (abfd); - raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz; - - /* FIXME SOMEDAY. A string table size of zero is very weird, but - probably possible. If one shows up, it will probably kill us. */ - - /* Swap all the raw entries. */ - for (internal_ptr = internal; - raw_src < raw_end; - raw_src += symesz, internal_ptr++) - { - - unsigned int i; - bfd_coff_swap_sym_in (abfd, (void *) raw_src, - (void *) & internal_ptr->u.syment); - symbol_ptr = internal_ptr; - - for (i = 0; - i < symbol_ptr->u.syment.n_numaux; - i++) - { - internal_ptr++; - raw_src += symesz; - bfd_coff_swap_aux_in (abfd, (void *) raw_src, - symbol_ptr->u.syment.n_type, - symbol_ptr->u.syment.n_sclass, - (int) i, symbol_ptr->u.syment.n_numaux, - &(internal_ptr->u.auxent)); - coff_pointerize_aux (abfd, internal, symbol_ptr, i, - internal_ptr); - } - } - - /* Free the raw symbols, but not the strings (if we have them). */ - obj_coff_keep_strings (abfd) = TRUE; - if (! _bfd_coff_free_symbols (abfd)) - return NULL; - - for (internal_ptr = internal; internal_ptr < internal_end; - internal_ptr++) - { - if (internal_ptr->u.syment.n_sclass == C_FILE - && internal_ptr->u.syment.n_numaux > 0) - { - /* Make a file symbol point to the name in the auxent, since - the text ".file" is redundant. */ - if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0) - { - /* The filename is a long one, point into the string table. */ - if (string_table == NULL) - { - string_table = _bfd_coff_read_string_table (abfd); - if (string_table == NULL) - return NULL; - } - - internal_ptr->u.syment._n._n_n._n_offset = - ((bfd_hostptr_t) - (string_table - + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset)); - } - else - { - /* Ordinary short filename, put into memory anyway. The - Microsoft PE tools sometimes store a filename in - multiple AUX entries. */ - if (internal_ptr->u.syment.n_numaux > 1 - && coff_data (abfd)->pe) - internal_ptr->u.syment._n._n_n._n_offset = - ((bfd_hostptr_t) - copy_name (abfd, - (internal_ptr + 1)->u.auxent.x_file.x_fname, - internal_ptr->u.syment.n_numaux * symesz)); - else - internal_ptr->u.syment._n._n_n._n_offset = - ((bfd_hostptr_t) - copy_name (abfd, - (internal_ptr + 1)->u.auxent.x_file.x_fname, - (size_t) bfd_coff_filnmlen (abfd))); - } - } - else - { - if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) - { - /* This is a "short" name. Make it long. */ - size_t i; - char *newstring; - - /* Find the length of this string without walking into memory - that isn't ours. */ - for (i = 0; i < 8; ++i) - if (internal_ptr->u.syment._n._n_name[i] == '\0') - break; - - newstring = (char *) bfd_zalloc (abfd, (bfd_size_type) (i + 1)); - if (newstring == NULL) - return NULL; - strncpy (newstring, internal_ptr->u.syment._n._n_name, i); - internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) newstring; - internal_ptr->u.syment._n._n_n._n_zeroes = 0; - } - else if (internal_ptr->u.syment._n._n_n._n_offset == 0) - internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) ""; - else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)) - { - /* Long name already. Point symbol at the string in the - table. */ - if (string_table == NULL) - { - string_table = _bfd_coff_read_string_table (abfd); - if (string_table == NULL) - return NULL; - } - internal_ptr->u.syment._n._n_n._n_offset = - ((bfd_hostptr_t) - (string_table - + internal_ptr->u.syment._n._n_n._n_offset)); - } - else - { - /* Long name in debug section. Very similar. */ - if (debug_section == NULL) - debug_section = build_debug_section (abfd); - internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) - (debug_section + internal_ptr->u.syment._n._n_n._n_offset); - } - } - internal_ptr += internal_ptr->u.syment.n_numaux; - } - - obj_raw_syments (abfd) = internal; - BFD_ASSERT (obj_raw_syment_count (abfd) - == (unsigned int) (internal_ptr - internal)); - - return internal; -} - -long -coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) -{ - if (bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -asymbol * -coff_make_empty_symbol (bfd *abfd) -{ - bfd_size_type amt = sizeof (coff_symbol_type); - coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt); - - if (new_symbol == NULL) - return NULL; - new_symbol->symbol.section = 0; - new_symbol->native = 0; - new_symbol->lineno = NULL; - new_symbol->done_lineno = FALSE; - new_symbol->symbol.the_bfd = abfd; - - return & new_symbol->symbol; -} - -/* Make a debugging symbol. */ - -asymbol * -coff_bfd_make_debug_symbol (bfd *abfd, - void * ptr ATTRIBUTE_UNUSED, - unsigned long sz ATTRIBUTE_UNUSED) -{ - bfd_size_type amt = sizeof (coff_symbol_type); - coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt); - - if (new_symbol == NULL) - return NULL; - /* @@ The 10 is a guess at a plausible maximum number of aux entries - (but shouldn't be a constant). */ - amt = sizeof (combined_entry_type) * 10; - new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt); - if (!new_symbol->native) - return NULL; - new_symbol->symbol.section = bfd_abs_section_ptr; - new_symbol->symbol.flags = BSF_DEBUGGING; - new_symbol->lineno = NULL; - new_symbol->done_lineno = FALSE; - new_symbol->symbol.the_bfd = abfd; - - return & new_symbol->symbol; -} - -void -coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret) -{ - bfd_symbol_info (symbol, ret); - - if (coffsymbol (symbol)->native != NULL - && coffsymbol (symbol)->native->fix_value) - ret->value = coffsymbol (symbol)->native->u.syment.n_value - - (bfd_hostptr_t) obj_raw_syments (abfd); -} - -/* Return the COFF syment for a symbol. */ - -bfd_boolean -bfd_coff_get_syment (bfd *abfd, - asymbol *symbol, - struct internal_syment *psyment) -{ - coff_symbol_type *csym; - - csym = coff_symbol_from (abfd, symbol); - if (csym == NULL || csym->native == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - *psyment = csym->native->u.syment; - - if (csym->native->fix_value) - psyment->n_value = psyment->n_value - - (bfd_hostptr_t) obj_raw_syments (abfd); - - /* FIXME: We should handle fix_line here. */ - - return TRUE; -} - -/* Return the COFF auxent for a symbol. */ - -bfd_boolean -bfd_coff_get_auxent (bfd *abfd, - asymbol *symbol, - int indx, - union internal_auxent *pauxent) -{ - coff_symbol_type *csym; - combined_entry_type *ent; - - csym = coff_symbol_from (abfd, symbol); - - if (csym == NULL - || csym->native == NULL - || indx >= csym->native->u.syment.n_numaux) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - ent = csym->native + indx + 1; - - *pauxent = ent->u.auxent; - - if (ent->fix_tag) - pauxent->x_sym.x_tagndx.l = - ((combined_entry_type *) pauxent->x_sym.x_tagndx.p - - obj_raw_syments (abfd)); - - if (ent->fix_end) - pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l = - ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p - - obj_raw_syments (abfd)); - - if (ent->fix_scnlen) - pauxent->x_csect.x_scnlen.l = - ((combined_entry_type *) pauxent->x_csect.x_scnlen.p - - obj_raw_syments (abfd)); - - return TRUE; -} - -/* Print out information about COFF symbol. */ - -void -coff_print_symbol (bfd *abfd, - void * filep, - asymbol *symbol, - bfd_print_symbol_type how) -{ - FILE * file = (FILE *) filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - - case bfd_print_symbol_more: - fprintf (file, "coff %s %s", - coffsymbol (symbol)->native ? "n" : "g", - coffsymbol (symbol)->lineno ? "l" : " "); - break; - - case bfd_print_symbol_all: - if (coffsymbol (symbol)->native) - { - bfd_vma val; - unsigned int aux; - combined_entry_type *combined = coffsymbol (symbol)->native; - combined_entry_type *root = obj_raw_syments (abfd); - struct lineno_cache_entry *l = coffsymbol (symbol)->lineno; - - fprintf (file, "[%3ld]", (long) (combined - root)); - - if (! combined->fix_value) - val = (bfd_vma) combined->u.syment.n_value; - else - val = combined->u.syment.n_value - (bfd_hostptr_t) root; - - fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x", - combined->u.syment.n_scnum, - combined->u.syment.n_flags, - combined->u.syment.n_type, - combined->u.syment.n_sclass, - combined->u.syment.n_numaux); - bfd_fprintf_vma (abfd, file, val); - fprintf (file, " %s", symbol->name); - - for (aux = 0; aux < combined->u.syment.n_numaux; aux++) - { - combined_entry_type *auxp = combined + aux + 1; - long tagndx; - - if (auxp->fix_tag) - tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root; - else - tagndx = auxp->u.auxent.x_sym.x_tagndx.l; - - fprintf (file, "\n"); - - if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux)) - continue; - - switch (combined->u.syment.n_sclass) - { - case C_FILE: - fprintf (file, "File "); - break; - - case C_STAT: - if (combined->u.syment.n_type == T_NULL) - /* Probably a section symbol ? */ - { - fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", - (unsigned long) auxp->u.auxent.x_scn.x_scnlen, - auxp->u.auxent.x_scn.x_nreloc, - auxp->u.auxent.x_scn.x_nlinno); - if (auxp->u.auxent.x_scn.x_checksum != 0 - || auxp->u.auxent.x_scn.x_associated != 0 - || auxp->u.auxent.x_scn.x_comdat != 0) - fprintf (file, " checksum 0x%lx assoc %d comdat %d", - auxp->u.auxent.x_scn.x_checksum, - auxp->u.auxent.x_scn.x_associated, - auxp->u.auxent.x_scn.x_comdat); - break; - } - /* Otherwise fall through. */ - case C_EXT: - case C_AIX_WEAKEXT: - if (ISFCN (combined->u.syment.n_type)) - { - long next, llnos; - - if (auxp->fix_end) - next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p - - root); - else - next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; - llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr; - fprintf (file, - "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld", - tagndx, - (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize, - llnos, next); - break; - } - /* Otherwise fall through. */ - default: - fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size, - tagndx); - if (auxp->fix_end) - fprintf (file, " endndx %ld", - ((long) - (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p - - root))); - break; - } - } - - if (l) - { - fprintf (file, "\n%s :", l->u.sym->name); - l++; - while (l->line_number) - { - fprintf (file, "\n%4d : ", l->line_number); - bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma); - l++; - } - } - } - else - { - bfd_print_symbol_vandf (abfd, (void *) file, symbol); - fprintf (file, " %-5s %s %s %s", - symbol->section->name, - coffsymbol (symbol)->native ? "n" : "g", - coffsymbol (symbol)->lineno ? "l" : " ", - symbol->name); - } - } -} - -/* Return whether a symbol name implies a local symbol. In COFF, - local symbols generally start with ``.L''. Most targets use this - function for the is_local_label_name entry point, but some may - override it. */ - -bfd_boolean -_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, - const char *name) -{ - return name[0] == '.' && name[1] == 'L'; -} - -/* Provided a BFD, a section and an offset (in bytes, not octets) into the - section, calculate and return the name of the source file and the line - nearest to the wanted location. */ - -bfd_boolean -coff_find_nearest_line (bfd *abfd, - asection *section, - asymbol **symbols, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr) -{ - bfd_boolean found; - unsigned int i; - unsigned int line_base; - coff_data_type *cof = coff_data (abfd); - /* Run through the raw syments if available. */ - combined_entry_type *p; - combined_entry_type *pend; - alent *l; - struct coff_section_tdata *sec_data; - bfd_size_type amt; - - /* Before looking through the symbol table, try to use a .stab - section to find the information. */ - if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - &found, filename_ptr, - functionname_ptr, line_ptr, - &coff_data(abfd)->line_info)) - return FALSE; - - if (found) - return TRUE; - - /* Also try examining DWARF2 debugging information. */ - if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr, 0, - &coff_data(abfd)->dwarf2_find_line_info)) - return TRUE; - - *filename_ptr = 0; - *functionname_ptr = 0; - *line_ptr = 0; - - /* Don't try and find line numbers in a non coff file. */ - if (!bfd_family_coff (abfd)) - return FALSE; - - if (cof == NULL) - return FALSE; - - /* Find the first C_FILE symbol. */ - p = cof->raw_syments; - if (!p) - return FALSE; - - pend = p + cof->raw_syment_count; - while (p < pend) - { - if (p->u.syment.n_sclass == C_FILE) - break; - p += 1 + p->u.syment.n_numaux; - } - - if (p < pend) - { - bfd_vma sec_vma; - bfd_vma maxdiff; - - /* Look through the C_FILE symbols to find the best one. */ - sec_vma = bfd_get_section_vma (abfd, section); - *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - maxdiff = (bfd_vma) 0 - (bfd_vma) 1; - while (1) - { - bfd_vma file_addr; - combined_entry_type *p2; - - for (p2 = p + 1 + p->u.syment.n_numaux; - p2 < pend; - p2 += 1 + p2->u.syment.n_numaux) - { - if (p2->u.syment.n_scnum > 0 - && (section - == coff_section_from_bfd_index (abfd, - p2->u.syment.n_scnum))) - break; - if (p2->u.syment.n_sclass == C_FILE) - { - p2 = pend; - break; - } - } - - file_addr = (bfd_vma) p2->u.syment.n_value; - /* PR 11512: Include the section address of the function name symbol. */ - if (p2->u.syment.n_scnum > 0) - file_addr += coff_section_from_bfd_index (abfd, - p2->u.syment.n_scnum)->vma; - /* We use <= MAXDIFF here so that if we get a zero length - file, we actually use the next file entry. */ - if (p2 < pend - && offset + sec_vma >= file_addr - && offset + sec_vma - file_addr <= maxdiff) - { - *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - maxdiff = offset + sec_vma - p2->u.syment.n_value; - } - - /* Avoid endless loops on erroneous files by ensuring that - we always move forward in the file. */ - if (p >= cof->raw_syments + p->u.syment.n_value) - break; - - p = cof->raw_syments + p->u.syment.n_value; - if (p > pend || p->u.syment.n_sclass != C_FILE) - break; - } - } - - /* Now wander though the raw linenumbers of the section. */ - /* If we have been called on this section before, and the offset we - want is further down then we can prime the lookup loop. */ - sec_data = coff_section_data (abfd, section); - if (sec_data != NULL - && sec_data->i > 0 - && offset >= sec_data->offset) - { - i = sec_data->i; - *functionname_ptr = sec_data->function; - line_base = sec_data->line_base; - } - else - { - i = 0; - line_base = 0; - } - - if (section->lineno != NULL) - { - bfd_vma last_value = 0; - - l = §ion->lineno[i]; - - for (; i < section->lineno_count; i++) - { - if (l->line_number == 0) - { - /* Get the symbol this line number points at. */ - coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); - if (coff->symbol.value > offset) - break; - *functionname_ptr = coff->symbol.name; - last_value = coff->symbol.value; - if (coff->native) - { - combined_entry_type *s = coff->native; - s = s + 1 + s->u.syment.n_numaux; - - /* In XCOFF a debugging symbol can follow the - function symbol. */ - if (s->u.syment.n_scnum == N_DEBUG) - s = s + 1 + s->u.syment.n_numaux; - - /* S should now point to the .bf of the function. */ - if (s->u.syment.n_numaux) - { - /* The linenumber is stored in the auxent. */ - union internal_auxent *a = &((s + 1)->u.auxent); - line_base = a->x_sym.x_misc.x_lnsz.x_lnno; - *line_ptr = line_base; - } - } - } - else - { - if (l->u.offset > offset) - break; - *line_ptr = l->line_number + line_base - 1; - } - l++; - } - - /* If we fell off the end of the loop, then assume that this - symbol has no line number info. Otherwise, symbols with no - line number info get reported with the line number of the - last line of the last symbol which does have line number - info. We use 0x100 as a slop to account for cases where the - last line has executable code. */ - if (i >= section->lineno_count - && last_value != 0 - && offset - last_value > 0x100) - { - *functionname_ptr = NULL; - *line_ptr = 0; - } - } - - /* Cache the results for the next call. */ - if (sec_data == NULL && section->owner == abfd) - { - amt = sizeof (struct coff_section_tdata); - section->used_by_bfd = bfd_zalloc (abfd, amt); - sec_data = (struct coff_section_tdata *) section->used_by_bfd; - } - if (sec_data != NULL) - { - sec_data->offset = offset; - sec_data->i = i - 1; - sec_data->function = *functionname_ptr; - sec_data->line_base = line_base; - } - - return TRUE; -} - -bfd_boolean -coff_find_inliner_info (bfd *abfd, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr) -{ - bfd_boolean found; - - found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, - functionname_ptr, line_ptr, - &coff_data(abfd)->dwarf2_find_line_info); - return (found); -} - -int -coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info) -{ - size_t size; - - if (!info->relocatable) - size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); - else - size = bfd_coff_filhsz (abfd); - - size += abfd->section_count * bfd_coff_scnhsz (abfd); - return size; -} - -/* Change the class of a coff symbol held by BFD. */ - -bfd_boolean -bfd_coff_set_symbol_class (bfd * abfd, - asymbol * symbol, - unsigned int symbol_class) -{ - coff_symbol_type * csym; - - csym = coff_symbol_from (abfd, symbol); - if (csym == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - else if (csym->native == NULL) - { - /* This is an alien symbol which no native coff backend data. - We cheat here by creating a fake native entry for it and - then filling in the class. This code is based on that in - coff_write_alien_symbol(). */ - - combined_entry_type * native; - bfd_size_type amt = sizeof (* native); - - native = (combined_entry_type *) bfd_zalloc (abfd, amt); - if (native == NULL) - return FALSE; - - native->u.syment.n_type = T_NULL; - native->u.syment.n_sclass = symbol_class; - - if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (bfd_is_com_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - native->u.syment.n_value = (symbol->value - + symbol->section->output_offset); - if (! obj_pe (abfd)) - native->u.syment.n_value += symbol->section->output_section->vma; - - /* Copy the any flags from the file header into the symbol. - FIXME: Why? */ - native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags; - } - - csym->native = native; - } - else - csym->native->u.syment.n_sclass = symbol_class; - - return TRUE; -} - -struct coff_comdat_info * -bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec) -{ - if (bfd_get_flavour (abfd) == bfd_target_coff_flavour - && coff_section_data (abfd, sec) != NULL) - return coff_section_data (abfd, sec)->comdat; - else - return NULL; -} - -bfd_boolean -_bfd_coff_section_already_linked (bfd *abfd, - asection *sec, - struct bfd_link_info *info) -{ - flagword flags; - const char *name, *key; - struct bfd_section_already_linked *l; - struct bfd_section_already_linked_hash_entry *already_linked_list; - struct coff_comdat_info *s_comdat; - - flags = sec->flags; - if ((flags & SEC_LINK_ONCE) == 0) - return FALSE; - - /* The COFF backend linker doesn't support group sections. */ - if ((flags & SEC_GROUP) != 0) - return FALSE; - - name = bfd_get_section_name (abfd, sec); - s_comdat = bfd_coff_get_comdat_section (abfd, sec); - - if (s_comdat != NULL) - key = s_comdat->name; - else - { - if (CONST_STRNEQ (name, ".gnu.linkonce.") - && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL) - key++; - else - /* FIXME: gcc as of 2011-09 emits sections like .text$, - .xdata$ and .pdata$ only the first of which has a - comdat key. Should these all match the LTO IR key? */ - key = name; - } - - already_linked_list = bfd_section_already_linked_table_lookup (key); - - for (l = already_linked_list->entry; l != NULL; l = l->next) - { - struct coff_comdat_info *l_comdat; - - l_comdat = bfd_coff_get_comdat_section (l->sec->owner, l->sec); - - /* The section names must match, and both sections must be - comdat and have the same comdat name, or both sections must - be non-comdat. LTO IR plugin sections are an exception. They - are always named .gnu.linkonce.t. ( is some string) - and match any comdat section with comdat name of , and - any linkonce section with the same suffix, ie. - .gnu.linkonce.*.. */ - if (((s_comdat != NULL) == (l_comdat != NULL) - && strcmp (name, l->sec->name) == 0) - || (l->sec->owner->flags & BFD_PLUGIN) != 0) - { - /* The section has already been linked. See if we should - issue a warning. */ - return _bfd_handle_already_linked (sec, l, info); - } - } - - /* This is the first section with this name. Record it. */ - if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) - info->callbacks->einfo (_("%F%P: already_linked_table: %E\n")); - return FALSE; -} diff --git a/contrib/binutils-2.22/bfd/compress.c b/contrib/binutils-2.22/bfd/compress.c deleted file mode 100644 index a82a8bc9e3..0000000000 --- a/contrib/binutils-2.22/bfd/compress.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Compressed section support (intended for debug sections). - Copyright 2008, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "config.h" -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#ifdef HAVE_ZLIB_H -#include -#endif - -#ifdef HAVE_ZLIB_H -static bfd_boolean -decompress_contents (bfd_byte *compressed_buffer, - bfd_size_type compressed_size, - bfd_byte *uncompressed_buffer, - bfd_size_type uncompressed_size) -{ - z_stream strm; - int rc; - - /* It is possible the section consists of several compressed - buffers concatenated together, so we uncompress in a loop. */ - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - strm.avail_in = compressed_size - 12; - strm.next_in = (Bytef*) compressed_buffer + 12; - strm.avail_out = uncompressed_size; - - rc = inflateInit (&strm); - while (strm.avail_in > 0) - { - if (rc != Z_OK) - return FALSE; - strm.next_out = ((Bytef*) uncompressed_buffer - + (uncompressed_size - strm.avail_out)); - rc = inflate (&strm, Z_FINISH); - if (rc != Z_STREAM_END) - return FALSE; - rc = inflateReset (&strm); - } - rc = inflateEnd (&strm); - return rc == Z_OK && strm.avail_out == 0; -} -#endif - -/* -FUNCTION - bfd_compress_section_contents - -SYNOPSIS - bfd_boolean bfd_compress_section_contents - (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer, - bfd_size_type uncompressed_size); - -DESCRIPTION - - Compress data of the size specified in @var{uncompressed_size} - and pointed to by @var{uncompressed_buffer} using zlib and store - as the contents field. This function assumes the contents - field was allocated using bfd_malloc() or equivalent. If zlib - is not installed on this machine, the input is unmodified. - - Return @code{TRUE} if the full section contents is compressed - successfully. -*/ - -bfd_boolean -bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr sec ATTRIBUTE_UNUSED, - bfd_byte *uncompressed_buffer ATTRIBUTE_UNUSED, - bfd_size_type uncompressed_size ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -#else - uLong compressed_size; - bfd_byte *compressed_buffer; - - compressed_size = compressBound (uncompressed_size) + 12; - compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size); - - if (compressed_buffer == NULL) - return FALSE; - - if (compress ((Bytef*) compressed_buffer + 12, - &compressed_size, - (const Bytef*) uncompressed_buffer, - uncompressed_size) != Z_OK) - { - free (compressed_buffer); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* Write the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - memcpy (compressed_buffer, "ZLIB", 4); - compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8; - compressed_buffer[4] = uncompressed_size; - compressed_size += 12; - - /* Free the uncompressed contents if we compress in place. */ - if (uncompressed_buffer == sec->contents) - free (uncompressed_buffer); - - sec->contents = compressed_buffer; - sec->size = compressed_size; - sec->compress_status = COMPRESS_SECTION_DONE; - - return TRUE; -#endif /* HAVE_ZLIB_H */ -} - -/* -FUNCTION - bfd_get_full_section_contents - -SYNOPSIS - bfd_boolean bfd_get_full_section_contents - (bfd *abfd, asection *section, bfd_byte **ptr); - -DESCRIPTION - Read all data from @var{section} in BFD @var{abfd}, decompress - if needed, and store in @var{*ptr}. If @var{*ptr} is NULL, - return @var{*ptr} with memory malloc'd by this function. - - Return @code{TRUE} if the full section contents is retrieved - successfully. -*/ - -bfd_boolean -bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr) -{ - bfd_size_type sz; - bfd_byte *p = *ptr; -#ifdef HAVE_ZLIB_H - bfd_boolean ret; - bfd_size_type compressed_size; - bfd_size_type uncompressed_size; - bfd_size_type rawsize; - bfd_byte *compressed_buffer; - bfd_byte *uncompressed_buffer; -#endif - - if (abfd->direction != write_direction && sec->rawsize != 0) - sz = sec->rawsize; - else - sz = sec->size; - if (sz == 0) - return TRUE; - - switch (sec->compress_status) - { - case COMPRESS_SECTION_NONE: - if (p == NULL) - { - p = (bfd_byte *) bfd_malloc (sz); - if (p == NULL) - return FALSE; - } - if (!bfd_get_section_contents (abfd, sec, p, 0, sz)) - { - if (*ptr != p) - free (p); - return FALSE; - } - *ptr = p; - return TRUE; - - case DECOMPRESS_SECTION_SIZED: -#ifndef HAVE_ZLIB_H - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -#else - /* Read in the full compressed section contents. */ - uncompressed_size = sec->size; - compressed_size = sec->compressed_size; - compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size); - if (compressed_buffer == NULL) - return FALSE; - rawsize = sec->rawsize; - /* Clear rawsize, set size to compressed size and set compress_status - to COMPRESS_SECTION_NONE. If the compressed size is bigger than - the uncompressed size, bfd_get_section_contents will fail. */ - sec->rawsize = 0; - sec->size = compressed_size; - sec->compress_status = COMPRESS_SECTION_NONE; - ret = bfd_get_section_contents (abfd, sec, compressed_buffer, - 0, compressed_size); - /* Restore rawsize and size. */ - sec->rawsize = rawsize; - sec->size = uncompressed_size; - sec->compress_status = DECOMPRESS_SECTION_SIZED; - if (!ret) - goto fail_compressed; - - uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size); - if (uncompressed_buffer == NULL) - goto fail_compressed; - - if (!decompress_contents (compressed_buffer, compressed_size, - uncompressed_buffer, uncompressed_size)) - { - bfd_set_error (bfd_error_bad_value); - free (uncompressed_buffer); - fail_compressed: - free (compressed_buffer); - return FALSE; - } - - free (compressed_buffer); - sec->contents = uncompressed_buffer; - sec->compress_status = COMPRESS_SECTION_DONE; - /* Fall thru */ -#endif - - case COMPRESS_SECTION_DONE: - if (p == NULL) - { - p = (bfd_byte *) bfd_malloc (sz); - if (p == NULL) - return FALSE; - *ptr = p; - } - memcpy (p, sec->contents, sz); - return TRUE; - - default: - abort (); - } -} - -/* -FUNCTION - bfd_is_section_compressed - -SYNOPSIS - bfd_boolean bfd_is_section_compressed - (bfd *abfd, asection *section); - -DESCRIPTION - Return @code{TRUE} if @var{section} is compressed. -*/ - -bfd_boolean -bfd_is_section_compressed (bfd *abfd, sec_ptr sec) -{ - bfd_byte compressed_buffer [12]; - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - return (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12) - && CONST_STRNEQ ((char*) compressed_buffer, "ZLIB")); -} - -/* -FUNCTION - bfd_init_section_decompress_status - -SYNOPSIS - bfd_boolean bfd_init_section_decompress_status - (bfd *abfd, asection *section); - -DESCRIPTION - Record compressed section size, update section size with - decompressed size and set compress_status to - DECOMPRESS_SECTION_SIZED. - - Return @code{FALSE} if the section is not a valid compressed - section or zlib is not installed on this machine. Otherwise, - return @code{TRUE}. -*/ - -bfd_boolean -bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr sec ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -#else - bfd_byte compressed_buffer [12]; - bfd_size_type uncompressed_size; - - if (sec->rawsize != 0 - || sec->contents != NULL - || sec->compress_status != COMPRESS_SECTION_NONE - || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB")) - { - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; - - sec->compressed_size = sec->size; - sec->size = uncompressed_size; - sec->compress_status = DECOMPRESS_SECTION_SIZED; - - return TRUE; -#endif -} - -/* -FUNCTION - bfd_init_section_compress_status - -SYNOPSIS - bfd_boolean bfd_init_section_compress_status - (bfd *abfd, asection *section); - -DESCRIPTION - If open for read, compress section, update section size with - compressed size and set compress_status to COMPRESS_SECTION_DONE. - - Return @code{FALSE} if the section is not a valid compressed - section or zlib is not installed on this machine. Otherwise, - return @code{TRUE}. -*/ - -bfd_boolean -bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr sec ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -#else - bfd_size_type uncompressed_size; - bfd_byte *uncompressed_buffer; - bfd_boolean ret; - - /* Error if not opened for read. */ - if (abfd->direction != read_direction - || sec->size == 0 - || sec->rawsize != 0 - || sec->contents != NULL - || sec->compress_status != COMPRESS_SECTION_NONE) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* Read in the full section contents and compress it. */ - uncompressed_size = sec->size; - uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size); - if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer, - 0, uncompressed_size)) - ret = FALSE; - else - ret = bfd_compress_section_contents (abfd, sec, - uncompressed_buffer, - uncompressed_size); - - free (uncompressed_buffer); - return ret; -#endif -} diff --git a/contrib/binutils-2.22/bfd/config.bfd b/contrib/binutils-2.22/bfd/config.bfd deleted file mode 100644 index 3b9872a2a4..0000000000 --- a/contrib/binutils-2.22/bfd/config.bfd +++ /dev/null @@ -1,1616 +0,0 @@ -# config.bfd -# Convert a canonical host type into a BFD host type. -# Set shell variable targ to canonical target name, and run -# using ``. config.bfd''. -# Sets the following shell variables: -# targ_defvec Default vector for this target -# targ_selvecs Vectors to build for this target -# targ64_selvecs Vectors to build if --enable-64-bit-bfd is given -# or if host is 64 bit. -# targ_archs Architectures for this target -# targ_cflags $(CFLAGS) for this target (FIXME: pretty bogus) -# targ_underscore Whether underscores are used: yes or no - -# Part of this file is processed by targmatch.sed to generate the -# targmatch.h file. The #ifdef and #endif lines that appear below are -# copied directly into targmatch.h. - -# The binutils c++filt program wants to know whether underscores are -# stripped or not. That is why we set targ_underscore. c++filt uses -# this information to choose a default. This information is -# duplicated in the symbol_leading_char field of the BFD target -# vector, but c++filt does not deal with object files and is not -# linked against libbfd.a. It is not terribly important that c++filt -# get this right; it is just convenient. - -targ_defvec= -targ_selvecs= -targ64_selvecs= -targ_cflags= -targ_underscore=no - -# Catch obsolete configurations. -case $targ in - null) - if test "x$enable_obsolete" != xyes; then - echo "*** Configuration $targ is obsolete." >&2 - echo "*** Specify --enable-obsolete to build it anyway." >&2 - echo "*** Support will be REMOVED in the next major release of BINUTILS," >&2 - echo "*** unless a maintainer comes forward." >&2 - exit 1 - fi;; -esac - -case $targ in - m68*-apple-aux* | \ - m68*-apollo-* | \ - m68*-bull-sysv* | \ - m68*-*-rtemscoff* | \ - maxq-*-coff | \ - i960-*-rtems* | \ - or32-*-rtems* | \ - m68*-*-lynxos* | \ - sparc-*-lynxos* | \ - vax-*-vms* | \ - arm-*-oabi | \ - a29k-* | \ - hppa*-*-rtems* | \ - *-go32-rtems* | \ - i[3-7]86*-*-rtemscoff* | \ - mips*el-*-rtems* | \ - powerpcle-*-rtems* | \ - sparc*-*-rtemsaout* | \ - null) - echo "*** Configuration $targ is obsolete." >&2 - echo "*** Support has been REMOVED." >&2 - exit 1 - ;; -esac - -targ_cpu=`echo $targ | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -case "${targ_cpu}" in -alpha*) targ_archs=bfd_alpha_arch ;; -am34*|am33_2.0*) targ_archs=bfd_mn10300_arch ;; -arm*) targ_archs=bfd_arm_arch ;; -bfin*) targ_archs=bfd_bfin_arch ;; -c30*) targ_archs=bfd_tic30_arch ;; -c4x*) targ_archs=bfd_tic4x_arch ;; -c54x*) targ_archs=bfd_tic54x_arch ;; -cr16*) targ_archs=bfd_cr16_arch ;; -crisv32) targ_archs=bfd_cris_arch ;; -crx*) targ_archs=bfd_crx_arch ;; -dlx*) targ_archs=bfd_dlx_arch ;; -fido*) targ_archs=bfd_m68k_arch ;; -hppa*) targ_archs=bfd_hppa_arch ;; -i[3-7]86) targ_archs=bfd_i386_arch ;; -i370) targ_archs=bfd_i370_arch ;; -lm32) targ_archs=bfd_lm32_arch ;; -m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch" ;; -m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch" ;; -m68*) targ_archs=bfd_m68k_arch ;; -m88*) targ_archs=bfd_m88k_arch ;; -microblaze*) targ_archs=bfd_microblaze_arch ;; -mips*) targ_archs=bfd_mips_arch ;; -or32*) targ_archs=bfd_or32_arch ;; -pdp11*) targ_archs=bfd_pdp11_arch ;; -pj*) targ_archs="bfd_pj_arch bfd_i386_arch";; -powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; -rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;; -s390*) targ_archs=bfd_s390_arch ;; -sh*) targ_archs=bfd_sh_arch ;; -sparc*) targ_archs=bfd_sparc_arch ;; -spu*) targ_archs=bfd_spu_arch ;; -tilegx*) targ_archs=bfd_tilegx_arch ;; -tilepro*) targ_archs=bfd_tilepro_arch ;; -v850*) targ_archs=bfd_v850_arch ;; -x86_64*) targ_archs=bfd_i386_arch ;; -xtensa*) targ_archs=bfd_xtensa_arch ;; -z80|r800) targ_archs=bfd_z80_arch ;; -z8k*) targ_archs=bfd_z8k_arch ;; -*) targ_archs=bfd_${targ_cpu}_arch ;; -esac - - -# WHEN ADDING ENTRIES TO THIS MATRIX: -# Make sure that the left side always has two dashes. Otherwise you -# can get spurious matches. Even for unambiguous cases, do this as a -# convention, else the table becomes a real mess to understand and maintain. -# -# Keep obsolete entries above the START comment, to keep them out of -# targmatch.h. - -case "${targ}" in - mips*-dec-bsd*) - echo "This target is obsolete and has been removed." - exit 1 - ;; - - mips*-*-mach3*) - echo "This target is obsolete and has been removed." - exit 1 - ;; - - mips*-*-pe*) - echo "This target is obsolete and has been removed." - exit 1 - ;; - - plugin) - targ_defvec=plugin_vec - targ_selvecs="plugin_vec" - ;; - -# START OF targmatch.h -#ifdef BFD64 - alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) - targ_defvec=bfd_elf64_alpha_freebsd_vec - targ_selvecs="bfd_elf64_alpha_vec ecoffalpha_little_vec" - want64=true - # FreeBSD <= 4.0 supports only the old nonstandard way of ABI labelling. - case "${targ}" in - alpha*-*-freebsd3* | alpha*-*-freebsd4 | alpha*-*-freebsd4.0*) - targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;; - esac - ;; - alpha*-*-netbsd* | alpha*-*-openbsd*) - targ_defvec=bfd_elf64_alpha_vec - targ_selvecs=ecoffalpha_little_vec - want64=true - ;; - alpha*-*-netware*) - targ_defvec=ecoffalpha_little_vec - targ_selvecs=nlm32_alpha_vec - want64=true - ;; - alpha*-*-linuxecoff*) - targ_defvec=ecoffalpha_little_vec - targ_selvecs=bfd_elf64_alpha_vec - want64=true - ;; - alpha*-*-linux-* | alpha*-*-elf*) - targ_defvec=bfd_elf64_alpha_vec - targ_selvecs=ecoffalpha_little_vec - want64=true - ;; - alpha*-*-*vms*) - targ_defvec=vms_alpha_vec - targ_selvecs=vms_lib_txt_vec - want64=true - ;; - alpha*-*-*) - targ_defvec=ecoffalpha_little_vec - want64=true - ;; - ia64*-*-freebsd* | ia64*-*-netbsd* | ia64*-*-linux-* | ia64*-*-elf* | ia64*-*-kfreebsd*-gnu) - targ_defvec=bfd_elf64_ia64_little_vec - targ_selvecs="bfd_elf64_ia64_big_vec bfd_pei_ia64_vec" - want64=true - ;; - ia64*-*-hpux*) - targ_defvec=bfd_elf32_ia64_hpux_big_vec - targ_selvecs="bfd_elf64_ia64_hpux_big_vec" - want64=true - ;; - ia64*-*-*vms*) - targ_defvec=bfd_elf64_ia64_vms_vec - targ_selvecs=vms_lib_txt_vec - want64=true - ;; - sparc64-*-freebsd* | sparc64-*-kfreebsd*-gnu) - targ_defvec=bfd_elf64_sparc_freebsd_vec - targ_selvecs="bfd_elf64_sparc_vec bfd_elf32_sparc_vec sunos_big_vec" - ;; - sparc64-*-netbsd* | sparc64-*-openbsd*) - targ_defvec=bfd_elf64_sparc_vec - targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec" - want64=true - ;; -#endif /* BFD64 */ - - am34-*-linux* | am33_2.0-*-linux*) - targ_defvec=bfd_elf32_am33lin_vec - ;; - - arc-*-elf*) - targ_defvec=bfd_elf32_littlearc_vec - targ_selvecs=bfd_elf32_bigarc_vec - ;; - - armeb-*-netbsdelf*) - targ_defvec=bfd_elf32_bigarm_vec - targ_selvecs="bfd_elf32_littlearm_vec armnetbsd_vec" - ;; - arm-*-netbsdelf*) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs="bfd_elf32_bigarm_vec armnetbsd_vec" - ;; - arm-*-netbsd* | arm-*-openbsd*) - targ_defvec=armnetbsd_vec - targ_selvecs="bfd_elf32_littlearm_vec bfd_elf32_bigarm_vec" - targ_underscore=yes - targ_cflags=-D__QNXTARGET__ - ;; - arm-*-nto* | nto*arm*) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs=bfd_elf32_bigarm_vec - ;; - arm-*-riscix*) - targ_defvec=riscix_vec - ;; - arm-epoc-pe*) - targ_defvec=arm_epoc_pe_little_vec - targ_selvecs="arm_epoc_pe_little_vec arm_epoc_pe_big_vec arm_epoc_pei_little_vec arm_epoc_pei_big_vec" - targ_underscore=no - targ_cflags=-DARM_COFF_BUGFIX - ;; - arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*) - targ_defvec=arm_wince_pe_little_vec - targ_selvecs="arm_wince_pe_little_vec arm_wince_pe_big_vec arm_wince_pei_little_vec arm_wince_pei_big_vec" - targ_underscore=no - targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX" - ;; - arm-*-pe*) - targ_defvec=armpe_little_vec - targ_selvecs="armpe_little_vec armpe_big_vec armpei_little_vec armpei_big_vec" - targ_underscore=yes - ;; - arm-*-aout | armel-*-aout) - targ_defvec=aout_arm_little_vec - targ_selvecs=aout_arm_big_vec - ;; - armeb-*-aout) - targ_defvec=aout_arm_big_vec - targ_selvecs=aout_arm_little_vec - ;; - arm-*-coff) - targ_defvec=armcoff_little_vec - targ_selvecs=armcoff_big_vec - targ_underscore=yes - ;; - arm-*-rtems*) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs=bfd_elf32_bigarm_vec - ;; - armeb-*-elf | arm*b-*-linux-*) - targ_defvec=bfd_elf32_bigarm_vec - targ_selvecs=bfd_elf32_littlearm_vec - ;; - arm-*-kaos*) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs=bfd_elf32_bigarm_vec - ;; - arm-*-elf | arm-*-freebsd* | arm*-*-linux-* | arm*-*-conix* | \ - arm*-*-uclinux* | arm-*-kfreebsd*-gnu | \ - arm*-*-eabi* ) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs=bfd_elf32_bigarm_vec - ;; - arm*-*-vxworks | arm*-*-windiss) - targ_defvec=bfd_elf32_littlearm_vxworks_vec - targ_selvecs=bfd_elf32_bigarm_vxworks_vec - ;; - arm*-*-symbianelf*) - targ_defvec=bfd_elf32_littlearm_symbian_vec - targ_selvecs=bfd_elf32_bigarm_symbian_vec - ;; - arm9e-*-elf) - targ_defvec=bfd_elf32_littlearm_vec - targ_selvecs=bfd_elf32_bigarm_vec - ;; - - avr-*-*) - targ_defvec=bfd_elf32_avr_vec - ;; - - bfin-*-*) - targ_defvec=bfd_elf32_bfin_vec - targ_selvecs=bfd_elf32_bfinfdpic_vec - targ_underscore=yes - ;; - - c30-*-*aout* | tic30-*-*aout*) - targ_defvec=tic30_aout_vec - ;; - c30-*-*coff* | tic30-*-*coff*) - targ_defvec=tic30_coff_vec - ;; - - c4x-*-*coff* | tic4x-*-*coff* | tic4x-*-rtems*) - targ_defvec=tic4x_coff1_vec - targ_selvecs="tic4x_coff1_beh_vec tic4x_coff2_vec tic4x_coff2_beh_vec tic4x_coff0_vec tic4x_coff0_beh_vec" - targ_underscore=yes - ;; - - c54x*-*-*coff* | tic54x-*-*coff*) - targ_defvec=tic54x_coff1_vec - targ_selvecs="tic54x_coff1_beh_vec tic54x_coff2_vec tic54x_coff2_beh_vec tic54x_coff0_vec tic54x_coff0_beh_vec" - targ_underscore=yes - ;; - - cr16-*-elf*) - targ_defvec=bfd_elf32_cr16_vec - targ_underscore=yes - ;; - - cr16c-*-elf*) - targ_defvec=bfd_elf32_cr16c_vec - targ_underscore=yes - ;; - - cris-*-* | crisv32-*-*) - targ_defvec=cris_aout_vec - targ_selvecs="bfd_elf32_us_cris_vec bfd_elf32_cris_vec ieee_vec" - targ_underscore=yes # Note: not true for bfd_elf32_cris_vec. - ;; - - crx-*-elf*) - targ_defvec=bfd_elf32_crx_vec - targ_underscore=yes - ;; - - d10v-*-*) - targ_defvec=bfd_elf32_d10v_vec - ;; - - dlx-*-elf*) - targ_defvec=bfd_elf32_dlx_big_vec - targ_selvecs="bfd_elf32_dlx_big_vec" - ;; - - d30v-*-*) - targ_defvec=bfd_elf32_d30v_vec - ;; - - fido-*-elf* ) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs="m68kcoff_vec ieee_vec" - ;; - - fr30-*-elf) - targ_defvec=bfd_elf32_fr30_vec - ;; - - frv-*-elf) - targ_defvec=bfd_elf32_frv_vec - targ_selvecs=bfd_elf32_frvfdpic_vec - ;; - - frv-*-*linux*) - targ_defvec=bfd_elf32_frvfdpic_vec - targ_selvecs=bfd_elf32_frv_vec - ;; - - moxie-*-elf | moxie-*-rtems | moxie-*-uclinux) - targ_defvec=bfd_elf32_moxie_vec - ;; - - h8300*-*-rtemscoff*) - targ_defvec=h8300coff_vec - targ_underscore=yes - ;; - - h8300*-*-elf | h8300*-*-rtems*) - targ_defvec=bfd_elf32_h8300_vec - targ_underscore=yes - ;; - - h8300*-*-*) - targ_defvec=h8300coff_vec - targ_underscore=yes - ;; - - h8500-*-*) - targ_defvec=h8500coff_vec - targ_underscore=yes - ;; - -#ifdef BFD64 - hppa*64*-*-linux-*) - targ_defvec=bfd_elf64_hppa_linux_vec - targ_selvecs=bfd_elf64_hppa_vec - want64=true - ;; - hppa*64*-*-hpux11*) - targ_defvec=bfd_elf64_hppa_vec - targ_selvecs=bfd_elf64_hppa_linux_vec - targ_cflags=-DHPUX_LARGE_AR_IDS - want64=true - ;; -#endif - - hppa*-*-linux-*) - targ_defvec=bfd_elf32_hppa_linux_vec - targ_selvecs=bfd_elf32_hppa_vec - ;; - hppa*-*-netbsd*) - targ_defvec=bfd_elf32_hppa_nbsd_vec - targ_selvecs="bfd_elf32_hppa_vec bfd_elf32_hppa_linux_vec" - ;; - hppa*-*-*elf* | hppa*-*-lites* | hppa*-*-sysv4* | hppa*-*-openbsd*) - targ_defvec=bfd_elf32_hppa_vec - targ_selvecs=bfd_elf32_hppa_linux_vec - ;; - - hppa*-*-bsd*) - targ_defvec=som_vec - targ_selvecs=bfd_elf32_hppa_vec - ;; - hppa*-*-hpux* | hppa*-*-hiux* | hppa*-*-mpeix*) - targ_defvec=som_vec - ;; - hppa*-*-osf*) - targ_defvec=som_vec - targ_selvecs=bfd_elf32_hppa_vec - ;; - - i370-*-*) - targ_defvec=bfd_elf32_i370_vec - targ_selvecs="bfd_elf32_i370_vec" - ;; - i[3-7]86-*-sco3.2v5*coff) - targ_defvec=i386coff_vec - targ_selvecs=bfd_elf32_i386_vec - ;; - i[3-7]86-*-sysv4* | i[3-7]86-*-unixware* | \ - i[3-7]86-*-elf | i[3-7]86-*-sco3.2v5* | \ - i[3-7]86-*-dgux* | i[3-7]86-*-sysv5*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386coff_vec - ;; - i[3-7]86-*-solaris2*) - targ_defvec=bfd_elf32_i386_sol2_vec - targ_selvecs="i386coff_vec" - targ64_selvecs="bfd_elf64_x86_64_sol2_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - want64=true - ;; -#ifdef BFD64 - x86_64-*-solaris2*) - targ_defvec=bfd_elf32_i386_sol2_vec - targ_selvecs="bfd_elf64_x86_64_sol2_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec i386coff_vec" - want64=true - ;; -#endif - i[3-7]86-*-kaos*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=bfd_elf32_i386_vec - ;; - i[3-7]86-*-nto*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386coff_vec - ;; - i[3-7]86-*-aros*) - targ_defvec=bfd_elf32_i386_vec - ;; - i[3-7]86-*-chorus*) - targ_defvec=bfd_elf32_i386_vec - ;; - i[3-7]86-*-dicos*) - targ_defvec=bfd_elf32_i386_vec - targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - ;; - *-*-msdosdjgpp* | *-*-go32* ) - targ_defvec=go32coff_vec - targ_selvecs="go32stubbedcoff_vec i386aout_vec" - ;; - i[3-7]86-*-sysv* | i[3-7]86-*-isc* | i[3-7]86-*-sco* | i[3-7]86-*-coff | \ - i[3-7]86-*-aix*) - targ_defvec=i386coff_vec - ;; - i[3-7]86-*-rtems*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386coff_vec i386aout_vec" - ;; - i[3-7]86-*-darwin* | i[3-7]86-*-macos10* | i[3-7]86-*-rhapsody*) - targ_defvec=mach_o_i386_vec - targ_selvecs="mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" - targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch" - ;; - i[3-7]86-sequent-bsd*) - targ_defvec=i386dynix_vec - targ_underscore=yes - ;; - i[3-7]86-*-bsd*) - targ_defvec=i386bsd_vec - targ_underscore=yes - ;; - i[3-7]86-*-dragonfly*) - targ_defvec=bfd_elf32_i386_vec - targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - ;; - i[3-7]86-*-freebsdaout* | i[3-7]86-*-freebsd[12].* | \ - i[3-7]86-*-freebsd[12]) - targ_defvec=i386freebsd_vec - targ_selvecs=i386bsd_vec - targ_underscore=yes - ;; - i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu) - targ_defvec=bfd_elf32_i386_freebsd_vec - targ_selvecs="bfd_elf32_i386_vec i386pei_vec i386coff_vec" - targ64_selvecs="bfd_elf64_x86_64_freebsd_vec bfd_elf64_x86_64_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_l1om_freebsd_vec bfd_elf64_k1om_vec bfd_elf64_k1om_freebsd_vec" - # FreeBSD <= 4.0 supports only the old nonstandard way of ABI labelling. - case "${targ}" in - i[3-7]86-*-freebsd3* | i[3-7]86-*-freebsd4 | i[3-7]86-*-freebsd4.0*) - targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;; - esac - ;; - i[3-7]86-*-netbsdelf* | i[3-7]86-*-netbsd*-gnu* | i[3-7]86-*-knetbsd*-gnu) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386netbsd_vec - targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - ;; - i[3-7]86-*-netbsdpe*) - targ_defvec=i386pe_vec - targ_selvecs="i386pe_vec i386pei_vec bfd_elf32_i386_vec" - ;; - i[3-7]86-*-netbsdaout* | i[3-7]86-*-netbsd* | \ - i[3-7]86-*-openbsd[0-2].* | i[3-7]86-*-openbsd3.[0-3]) - targ_defvec=i386netbsd_vec - targ_selvecs="bfd_elf32_i386_vec i386bsd_vec" - targ_underscore=yes - ;; - i[3-7]86-*-openbsd*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386netbsd_vec - ;; - i[3-7]86-*-netware*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="nlm32_i386_vec i386coff_vec i386aout_vec" - ;; - i[3-7]86-*-linux*aout*) - targ_defvec=i386linux_vec - targ_selvecs=bfd_elf32_i386_vec - targ_underscore=yes - ;; - i[3-7]86-*-linux-*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386linux_vec i386pei_vec" - targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf32_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - ;; - i[3-7]86-*-nacl*) - targ_defvec=bfd_elf32_i386_nacl_vec - targ_selvecs="bfd_elf32_i386_vec" - ;; -#ifdef BFD64 - x86_64-*-darwin*) - targ_defvec=mach_o_x86_64_vec - targ_selvecs="mach_o_i386_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" - targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch" - want64=true - ;; - x86_64-*-dicos*) - targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - want64=true - ;; - x86_64-*-elf*) - targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec i386coff_vec" - want64=true - ;; - x86_64-*-dragonfly*) - targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - want64=true - ;; - x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) - targ_defvec=bfd_elf64_x86_64_freebsd_vec - targ_selvecs="bfd_elf32_i386_freebsd_vec i386coff_vec i386pei_vec x86_64pei_vec bfd_elf32_i386_vec bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_l1om_freebsd_vec bfd_elf64_k1om_vec bfd_elf64_k1om_freebsd_vec" - want64=true - ;; - x86_64-*-netbsd* | x86_64-*-openbsd*) - targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec i386netbsd_vec i386coff_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - want64=true - ;; - x86_64-*-linux-*) - targ_defvec=bfd_elf64_x86_64_vec - targ_selvecs="bfd_elf32_i386_vec bfd_elf32_x86_64_vec i386linux_vec i386pei_vec x86_64pei_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec" - want64=true - ;; - x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep) - targ_defvec=x86_64pe_vec - targ_selvecs="x86_64pe_vec x86_64pei_vec bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec i386pe_vec i386pei_vec bfd_elf32_i386_vec" - want64=true - targ_underscore=no - ;; -#endif - i[3-7]86-*-lynxos*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386lynx_coff_vec i386lynx_aout_vec" - ;; - i[3-7]86-*-gnu*) - targ_defvec=bfd_elf32_i386_vec - ;; - i[3-7]86-*-mach* | i[3-7]86-*-osf1mk*) - targ_defvec=i386mach3_vec - targ_cflags=-DSTAT_FOR_EXEC - targ_underscore=yes - ;; - i[3-7]86-*-os9k) - targ_defvec=i386os9k_vec - ;; - i[3-7]86-*-msdos*) - targ_defvec=i386aout_vec - targ_selvecs=i386msdos_vec - ;; - i[3-7]86-*-moss*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386msdos_vec i386aout_vec" - ;; - i[3-7]86-*-beospe*) - targ_defvec=i386pe_vec - targ_selvecs="i386pe_vec i386pei_vec" - ;; - i[3-7]86-*-beoself* | i[3-7]86-*-beos*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs="i386pe_vec i386pei_vec" - ;; - i[3-7]86-*-interix*) - targ_defvec=i386pei_vec - targ_selvecs="i386pe_vec" - # FIXME: This should eventually be checked at runtime. - targ_cflags=-DSTRICT_PE_FORMAT - ;; - i[3-7]86-*-rdos*) - targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386coff_vec - ;; - i[3-7]86-*-mingw32* | i[3-7]86-*-cygwin* | i[3-7]86-*-winnt | i[3-7]86-*-pe) - targ_defvec=i386pe_vec - targ_selvecs="i386pe_vec i386pei_vec bfd_elf32_i386_vec" - targ_underscore=yes - ;; - i[3-7]86-none-*) - targ_defvec=i386coff_vec - ;; - i[3-7]86-*-aout* | i[3-7]86*-*-vsta*) - targ_defvec=i386aout_vec - ;; - i[3-7]86-*-vxworks*) - targ_defvec=bfd_elf32_i386_vxworks_vec - targ_underscore=yes - ;; - i[3-7]86-*-chaos) - targ_defvec=bfd_elf32_i386_vec - targ_selfvecs=i386chaos_vec - ;; - - i860-*-mach3* | i860-*-osf1* | i860-*-coff*) - targ_defvec=i860coff_vec - ;; - i860-stardent-sysv4* | i860-stardent-elf*) - targ_defvec=bfd_elf32_i860_little_vec - targ_selvecs="bfd_elf32_i860_vec bfd_elf32_i860_little_vec" - ;; - i860-*-sysv4* | i860-*-elf*) - targ_defvec=bfd_elf32_i860_vec - ;; - - i960-*-vxworks4* | i960-*-vxworks5.0) - targ_defvec=b_out_vec_little_host - targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec ieee_vec" - targ_underscore=yes - ;; - i960-*-vxworks5.* | i960-*-coff* | i960-*-sysv*) - targ_defvec=icoff_little_vec - targ_selvecs="icoff_big_vec b_out_vec_little_host b_out_vec_big_host ieee_vec" - targ_underscore=yes - ;; - i960-*-vxworks* | i960-*-aout* | i960-*-bout* | i960-*-nindy*) - targ_defvec=b_out_vec_little_host - targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec ieee_vec" - targ_underscore=yes - ;; - i960-*-elf*) - targ_defvec=bfd_elf32_i960_vec - targ_selvecs="icoff_little_vec icoff_big_vec" - ;; - - ip2k-*-elf) - targ_defvec=bfd_elf32_ip2k_vec - ;; - - iq2000-*-elf) - targ_defvec=bfd_elf32_iq2000_vec - ;; - - lm32-*-elf | lm32-*-rtems*) - targ_defvec=bfd_elf32_lm32_vec - targ_selvecs=bfd_elf32_lm32fdpic_vec - ;; - - lm32-*-*linux*) - targ_defvec=bfd_elf32_lm32fdpic_vec - targ_selvecs=bfd_elf32_lm32_vec - ;; - - m32c-*-elf | m32c-*-rtems*) - targ_defvec=bfd_elf32_m32c_vec - ;; - - m32r*le-*-linux*) - targ_defvec=bfd_elf32_m32rlelin_vec - targ_selvecs="bfd_elf32_m32rlin_vec bfd_elf32_m32rlelin_vec" - ;; - m32r*-*-linux*) - targ_defvec=bfd_elf32_m32rlin_vec - targ_selvecs="bfd_elf32_m32rlin_vec bfd_elf32_m32rlelin_vec" - ;; - m32r*le-*-*) - targ_defvec=bfd_elf32_m32rle_vec - targ_selvecs="bfd_elf32_m32r_vec bfd_elf32_m32rle_vec" - ;; - m32r-*-*) - targ_defvec=bfd_elf32_m32r_vec - ;; - - m68hc11-*-* | m6811-*-*) - targ_defvec=bfd_elf32_m68hc11_vec - targ_selvecs="bfd_elf32_m68hc11_vec bfd_elf32_m68hc12_vec" - ;; - m68hc12-*-* | m6812-*-*) - targ_defvec=bfd_elf32_m68hc12_vec - targ_selvecs="bfd_elf32_m68hc11_vec bfd_elf32_m68hc12_vec" - ;; - - m68*-motorola-sysv*) - targ_defvec=m68ksysvcoff_vec - ;; - m68*-hp-bsd*) - targ_defvec=hp300bsd_vec - targ_underscore=yes - ;; - m68*-*-aout*) - targ_defvec=aout0_big_vec - # We include cisco_core_big_vec here, rather than making a separate cisco - # configuration, so that cisco-core.c gets routinely tested at - # least for compilation. - targ_selvecs="cisco_core_big_vec ieee_vec" - targ_underscore=yes - ;; - m68*-*-elf* | m68*-*-sysv4* | m68*-*-uclinux*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs="m68kcoff_vec ieee_vec" - ;; - m68*-*-rtems*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs="m68kcoff_vec versados_vec ieee_vec aout0_big_vec" - ;; - m68*-*-coff* | m68*-*-sysv*) - targ_defvec=m68kcoff_vec - targ_selvecs="m68kcoff_vec versados_vec ieee_vec" - ;; - m68*-*-hpux*) - targ_defvec=hp300hpux_vec - targ_underscore=yes - ;; - m68*-*-linux*aout*) - targ_defvec=m68klinux_vec - targ_selvecs=bfd_elf32_m68k_vec - targ_underscore=yes - ;; - m68*-*-linux-*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=m68klinux_vec - ;; - m68*-*-gnu*) - targ_defvec=bfd_elf32_m68k_vec - # targ_selvecs=m68kmach3_vec - # targ_cflags=-DSTAT_FOR_EXEC - ;; - m68*-hp*-netbsd*) - targ_defvec=m68k4knetbsd_vec - targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec" - targ_underscore=yes - ;; - m68*-*-netbsdelf*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs="m68knetbsd_vec m68k4knetbsd_vec hp300bsd_vec sunos_big_vec" - ;; - m68*-*-netbsdaout* | m68*-*-netbsd*) - targ_defvec=m68knetbsd_vec - targ_selvecs="m68k4knetbsd_vec bfd_elf32_m68k_vec hp300bsd_vec sunos_big_vec" - targ_underscore=yes - ;; - m68*-*-openbsd*) - targ_defvec=m68knetbsd_vec - targ_selvecs="m68k4knetbsd_vec hp300bsd_vec sunos_big_vec" - targ_underscore=yes - ;; - m68*-*-sunos* | m68*-*-os68k* | m68*-*-vxworks* | m68*-netx-* | \ - m68*-*-bsd* | m68*-*-vsta*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - m68*-ericsson-*) - targ_defvec=sunos_big_vec - targ_selvecs="m68kcoff_vec versados_vec tekhex_vec" - targ_underscore=yes - ;; - m68*-cbm-*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=m68kcoff_vec - ;; - m68*-*-psos*) - targ_defvec=bfd_elf32_m68k_vec - targ_selvecs=ieee_vec - targ_underscore=yes - ;; - - m88*-harris-cxux* | m88*-*-dgux* | m88*-*-sysv4*) - targ_defvec=bfd_elf32_m88k_vec - targ_selvecs=m88kbcs_vec - ;; - m88*-*-mach3*) - targ_defvec=m88kmach3_vec - targ_cflags=-DSTAT_FOR_EXEC - ;; - m88*-*-openbsd*) - targ_defvec=m88kopenbsd_vec - targ_underscore=yes - ;; - m88*-*-*) - targ_defvec=m88kbcs_vec - targ_underscore=yes - ;; - - mcore-*-elf) - targ_defvec=bfd_elf32_mcore_big_vec - targ_selvecs="bfd_elf32_mcore_big_vec bfd_elf32_mcore_little_vec" - ;; - mcore-*-pe) - targ_defvec=mcore_pe_big_vec - targ_selvecs="mcore_pe_big_vec mcore_pe_little_vec mcore_pei_big_vec mcore_pei_little_vec" - ;; - - mep-*-elf) - targ_defvec=bfd_elf32_mep_vec - targ_selvecs=bfd_elf32_mep_little_vec - ;; - - microblaze*-*) - targ_defvec=bfd_elf32_microblaze_vec - ;; - - mips*-big-*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips*el-*-netbsd*) - targ_defvec=bfd_elf32_tradlittlemips_vec - targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec ecoff_little_vec ecoff_big_vec" - ;; - mips*-*-netbsd*) - targ_defvec=bfd_elf32_tradbigmips_vec - targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec ecoff_big_vec ecoff_little_vec" - ;; - mips*-dec-* | mips*el-*-ecoff*) - targ_defvec=ecoff_little_vec - targ_selvecs=ecoff_big_vec - ;; - mips*-*-ecoff*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; -#ifdef BFD64 - mips*-*-irix6*) - targ_defvec=bfd_elf32_nbigmips_vec - targ_selvecs="bfd_elf32_nlittlemips_vec bfd_elf32_bigmips_vec bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - want64=true - ;; -#endif - mips*-*-irix5*) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec" - ;; - mips*-sgi-* | mips*-*-bsd*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; - mips*-*-lnews*) - targ_defvec=ecoff_biglittle_vec - targ_selvecs="ecoff_little_vec ecoff_big_vec" - ;; - mips*-*-sysv4*) - targ_defvec=bfd_elf32_tradbigmips_vec - targ_selvecs="bfd_elf32_tradlittlemips_vec ecoff_big_vec ecoff_little_vec" - ;; - mips*-*-sysv* | mips*-*-riscos*) - targ_defvec=ecoff_big_vec - targ_selvecs=ecoff_little_vec - ;; -#ifdef BFD64 - mips*el-*-vxworks*) - targ_defvec=bfd_elf32_littlemips_vxworks_vec - targ_selvecs="bfd_elf32_littlemips_vec bfd_elf32_bigmips_vxworks_vec bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - want64=true - ;; - mips*-*-vxworks*) - targ_defvec=bfd_elf32_bigmips_vxworks_vec - targ_selvecs="bfd_elf32_bigmips_vec bfd_elf32_littlemips_vxworks_vec bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - want64=true - ;; -#endif - mips*el-sde-elf*) - targ_defvec=bfd_elf32_tradlittlemips_vec - targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; - mips*-sde-elf*) - targ_defvec=bfd_elf32_tradbigmips_vec - targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; - mips*el-*-elf* | mips*el-*-vxworks* | mips*-*-chorus*) - targ_defvec=bfd_elf32_littlemips_vec - targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - ;; - mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks | mips*-*-windiss) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - ;; - mips*-*-none) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" - ;; -#ifdef BFD64 - mips64*-*-openbsd*) - targ_defvec=bfd_elf64_tradbigmips_vec - targ_selvecs="bfd_elf32_ntradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; -#endif - mips*el-*-openbsd*) - targ_defvec=bfd_elf32_littlemips_vec - targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_little_vec ecoff_big_vec" - ;; - mips*-*-openbsd*) - targ_defvec=bfd_elf32_bigmips_vec - targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_big_vec ecoff_little_vec" - ;; -#ifdef BFD64 - mips64*el-*-linux*) - targ_defvec=bfd_elf32_ntradlittlemips_vec - targ_selvecs="bfd_elf32_ntradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec" - want64=true - ;; - mips64*-*-linux*) - targ_defvec=bfd_elf32_ntradbigmips_vec - targ_selvecs="bfd_elf32_ntradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; -#endif - mips*el-*-linux*) - targ_defvec=bfd_elf32_tradlittlemips_vec - targ_selvecs="bfd_elf32_tradbigmips_vec ecoff_little_vec ecoff_big_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf64_tradbigmips_vec" - want64=true - ;; - mips*-*-linux*) - targ_defvec=bfd_elf32_tradbigmips_vec - targ_selvecs="bfd_elf32_tradlittlemips_vec ecoff_big_vec ecoff_little_vec bfd_elf32_ntradbigmips_vec bfd_elf64_tradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; -#ifdef BFD64 - mips64*el-*-freebsd* | mips64*el-*-kfreebsd*-gnu) - # FreeBSD vectors - targ_defvec=bfd_elf32_ntradlittlemips_freebsd_vec - targ_selvecs="bfd_elf32_ntradbigmips_freebsd_vec bfd_elf32_tradlittlemips_freebsd_vec bfd_elf32_tradbigmips_freebsd_vec bfd_elf64_tradlittlemips_freebsd_vec bfd_elf64_tradbigmips_freebsd_vec" - # Generic vectors - targ_selvecs="${targ_selvecs} bfd_elf32_ntradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec" - want64=true - ;; - mips64*-*-freebsd* | mips64*-*-kfreebsd*-gnu) - # FreeBSD vectors - targ_defvec=bfd_elf32_ntradbigmips_freebsd_vec - targ_selvecs="bfd_elf32_ntradlittlemips_freebsd_vec bfd_elf32_tradbigmips_freebsd_vec bfd_elf32_tradlittlemips_freebsd_vec bfd_elf64_tradbigmips_freebsd_vec bfd_elf64_tradlittlemips_freebsd_vec" - # Generic vectors - targ_selvecs="${targ_selvecs} bfd_elf32_ntradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; -#endif - mips*el-*-freebsd* | mips*el-*-kfreebsd*-gnu) - # FreeBSD vectors - targ_defvec=bfd_elf32_tradlittlemips_freebsd_vec - targ_selvecs="bfd_elf32_tradbigmips_freebsd_vec bfd_elf32_ntradlittlemips_freebsd_vec bfd_elf64_tradlittlemips_freebsd_vec bfd_elf32_ntradbigmips_freebsd_vec bfd_elf64_tradbigmips_freebsd_vec" - # Generic vectors - targ_selvecs="${targ_selvecs} bfd_elf32_tradlittlemips_vec bfd_elf32_tradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf64_tradbigmips_vec" - want64=true - ;; - mips*-*-freebsd* | mips*-*-kfreebsd*-gnu) - # FreeBSD vectors - targ_defvec=bfd_elf32_tradbigmips_freebsd_vec - targ_selvecs="bfd_elf32_tradlittlemips_freebsd_vec bfd_elf32_ntradbigmips_freebsd_vec bfd_elf64_tradbigmips_freebsd_vec bfd_elf32_ntradlittlemips_freebsd_vec bfd_elf64_tradlittlemips_freebsd_vec" - # Generic vectors - targ_selvecs="${targ_selvecs} bfd_elf32_tradbigmips_vec bfd_elf32_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf64_tradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradlittlemips_vec" - want64=true - ;; -#ifdef BFD64 - mmix-*-*) - targ_defvec=bfd_elf64_mmix_vec - targ_selvecs=bfd_mmo_vec - want64=true - ;; -#endif - mn10200-*-*) - targ_defvec=bfd_elf32_mn10200_vec - ;; - - mn10300-*-*) - targ_defvec=bfd_elf32_mn10300_vec - targ_underscore=yes - ;; - - mt-*-elf) - targ_defvec=bfd_elf32_mt_vec - ;; - - msp430-*-*) - targ_defvec=bfd_elf32_msp430_vec - ;; - - ns32k-pc532-mach* | ns32k-pc532-ux*) - targ_defvec=pc532machaout_vec - targ_underscore=yes - ;; - ns32k-*-netbsd* | ns32k-*-lites* | ns32k-*-openbsd*) - targ_defvec=pc532netbsd_vec - targ_underscore=yes - ;; - - openrisc-*-elf) - targ_defvec=bfd_elf32_openrisc_vec - ;; - - or32-*-coff) - targ_defvec=or32coff_big_vec - targ_underscore=yes - ;; - - or32-*-elf) - targ_defvec=bfd_elf32_or32_big_vec - ;; - - pdp11-*-*) - targ_defvec=pdp11_aout_vec - targ_underscore=yes - ;; - - pj-*-*) - targ_defvec=bfd_elf32_pj_vec - targ_selvecs="bfd_elf32_pj_vec bfd_elf32_pjl_vec" - ;; - - pjl-*-*) - targ_defvec=bfd_elf32_pjl_vec - targ_selvecs="bfd_elf32_pjl_vec bfd_elf32_pj_vec bfd_elf32_i386_vec" - ;; - - powerpc-*-aix5.[01] | rs6000-*-aix5.[01]) - targ_defvec=rs6000coff_vec - targ_selvecs="aix5coff64_vec" - want64=true - ;; -#ifdef BFD64 - powerpc64-*-aix5.[01] | rs6000-*-aix5.[01]) - targ_defvec=aix5coff64_vec - targ_selvecs="rs6000coff_vec" - want64=true - ;; -#endif - powerpc-*-aix[5-9]* | rs6000-*-aix[5-9]*) - targ_cflags=-DAIX_WEAK_SUPPORT - targ_defvec=rs6000coff_vec - targ_selvecs="aix5coff64_vec" - want64=true - ;; -#ifdef BFD64 - powerpc64-*-aix[5-9]* | rs6000-*-aix[5-9]*) - targ_cflags=-DAIX_WEAK_SUPPORT - targ_defvec=aix5coff64_vec - targ_selvecs="rs6000coff_vec" - want64=true - ;; -#endif - - powerpc-*-aix* | powerpc-*-beos* | rs6000-*-*) - targ_defvec=rs6000coff_vec - targ64_selvecs=rs6000coff64_vec - case "${targ}" in - *-*-aix4.[3456789]* | *-*-aix[56789]*) - want64=true;; - *) - targ_cflags=-DSMALL_ARCHIVE;; - esac - ;; -#ifdef BFD64 - powerpc64-*-aix*) - targ_defvec=rs6000coff64_vec - targ_selvecs=rs6000coff_vec - want64=true - ;; - powerpc64-*-elf* | powerpc-*-elf64* | powerpc64-*-linux* | \ - powerpc64-*-*bsd*) - targ_defvec=bfd_elf64_powerpc_vec - targ_selvecs="bfd_elf64_powerpcle_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" - want64=true - ;; - powerpc64le-*-elf* | powerpcle-*-elf64*) - targ_defvec=bfd_elf64_powerpcle_vec - targ_selvecs="bfd_elf64_powerpc_vec bfd_elf32_powerpcle_vec bfd_elf32_powerpc_vec rs6000coff_vec rs6000coff64_vec aix5coff64_vec" - want64=true - ;; -#endif - powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \ - powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \ - powerpc-*-chorus*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec" - targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec" - ;; - powerpc-*-kaos*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="bfd_elf32_powerpcle_vec ppcboot_vec" - targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec" - ;; - powerpc-*-darwin* | powerpc-*-macos10* | powerpc-*-rhapsody*) - targ_defvec=mach_o_be_vec - targ_selvecs="mach_o_be_vec mach_o_le_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" - targ_archs="$targ_archs bfd_i386_arch" - ;; - powerpc-*-macos*) - targ_defvec=pmac_xcoff_vec - ;; - powerpc-*-lynxos*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="rs6000coff_vec" - targ_cflags=-DSMALL_ARCHIVE - ;; - powerpc-*-netware*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="nlm32_powerpc_vec rs6000coff_vec" - ;; - powerpc-*-nto*) - targ_defvec=bfd_elf32_powerpc_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec" - ;; - powerpc-*-vxworks* | powerpc-*-windiss*) - targ_defvec=bfd_elf32_powerpc_vxworks_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec ppcboot_vec" - targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec" - ;; - powerpcle-*-nto*) - targ_defvec=bfd_elf32_powerpcle_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec" - ;; - powerpcle-*-elf* | powerpcle-*-sysv4* | powerpcle-*-eabi* | \ - powerpcle-*-solaris2* | powerpcle-*-linux-* | powerpcle-*-vxworks*) - targ_defvec=bfd_elf32_powerpcle_vec - targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec" - targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec" - ;; - powerpcle-*-pe | powerpcle-*-winnt* | powerpcle-*-cygwin*) - targ_defvec=bfd_powerpcle_pe_vec - targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec" - ;; - - rx-*-elf) - targ_defvec=bfd_elf32_rx_le_vec - targ_selvecs="bfd_elf32_rx_be_vec bfd_elf32_rx_le_vec bfd_elf32_rx_be_ns_vec" - ;; - - s390-*-linux*) - targ_defvec=bfd_elf32_s390_vec - targ64_selvecs=bfd_elf64_s390_vec - want64=true - ;; -#ifdef BFD64 - s390x-*-linux*) - targ_defvec=bfd_elf64_s390_vec - targ_selvecs=bfd_elf32_s390_vec - want64=true - ;; - s390x-*-tpf*) - targ_defvec=bfd_elf64_s390_vec - want64=true - ;; - - score*-*-elf*) - targ_defvec=bfd_elf32_bigscore_vec - targ_selvecs=bfd_elf32_littlescore_vec - ;; - - sh64l*-*-elf*) - targ_defvec=bfd_elf32_sh64l_vec - targ_selvecs="bfd_elf32_sh64_vec bfd_elf64_sh64l_vec bfd_elf64_sh64_vec bfd_elf32_shl_vec bfd_elf32_sh_vec" - targ_underscore=yes - want64=true - ;; - sh64-*-elf*) - targ_defvec=bfd_elf32_sh64_vec - targ_selvecs="bfd_elf32_sh64l_vec bfd_elf64_sh64_vec bfd_elf64_sh64l_vec bfd_elf32_sh_vec bfd_elf32_shl_vec" - targ_underscore=yes - want64=true - ;; - sh64eb-*-linux*) - targ_defvec=bfd_elf32_sh64blin_vec - targ_selvecs="bfd_elf32_sh64lin_vec bfd_elf64_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf32_shblin_vec bfd_elf32_shlin_vec" - want64=true - ;; - sh64-*-linux*) - targ_defvec=bfd_elf32_sh64lin_vec - targ_selvecs="bfd_elf32_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf64_sh64blin_vec bfd_elf32_shlin_vec bfd_elf32_shblin_vec" - want64=true - ;; - sh-*-linux*) - targ_defvec=bfd_elf32_shblin_vec - targ_selvecs="bfd_elf32_shlin_vec bfd_elf32_sh64lin_vec bfd_elf32_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf64_sh64blin_vec" - want64=true - ;; -#endif /* BFD64 */ - - sh*eb-*-linux*) - targ_defvec=bfd_elf32_shblin_vec - targ_selvecs=bfd_elf32_shlin_vec - ;; - sh*-*-linux*) - targ_defvec=bfd_elf32_shlin_vec - targ_selvecs=bfd_elf32_shblin_vec - ;; - - sh-*-uclinux* | sh[12]-*-uclinux*) - targ_defvec=bfd_elf32_sh_vec - targ_selvecs="bfd_elf32_shl_vec bfd_elf32_shblin_vec bfd_elf32_shlin_vec bfd_elf32_shfd_vec bfd_elf32_shbfd_vec" -#ifdef BFD64 - targ_selvecs="${targ_selvecs} bfd_elf32_sh64lin_vec bfd_elf32_sh64blin_vec bfd_elf64_sh64lin_vec bfd_elf64_sh64blin_vec" -#endif - ;; - -#ifdef BFD64 - sh5le-*-netbsd*) - targ_defvec=bfd_elf32_sh64lnbsd_vec - targ_selvecs="bfd_elf32_sh64nbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec bfd_elf32_shnbsd_vec bfd_elf32_shlnbsd_vec" - want64=true - ;; - sh5-*-netbsd*) - targ_defvec=bfd_elf32_sh64nbsd_vec - targ_selvecs="bfd_elf32_sh64lnbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec bfd_elf32_shnbsd_vec bfd_elf32_shlnbsd_vec" - want64=true - ;; - - sh64le-*-netbsd*) - targ_defvec=bfd_elf64_sh64lnbsd_vec - targ_selvecs="bfd_elf64_sh64nbsd_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf32_shnbsd_vec bfd_elf32_shlnbsd_vec" - want64=true - ;; - sh64-*-netbsd*) - targ_defvec=bfd_elf64_sh64nbsd_vec - targ_selvecs="bfd_elf64_sh64lnbsd_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf32_shnbsd_vec bfd_elf32_shlnbsd_vec" - want64=true - ;; - - sh*l*-*-netbsdelf*) - targ_defvec=bfd_elf32_shlnbsd_vec - targ_selvecs="bfd_elf32_shnbsd_vec shcoff_vec shlcoff_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec" - want64=true - ;; - sh-*-netbsdelf*) - targ_defvec=bfd_elf32_shnbsd_vec - targ_selvecs="bfd_elf32_shlnbsd_vec shcoff_vec shlcoff_vec bfd_elf32_sh64lnbsd_vec bfd_elf32_sh64nbsd_vec bfd_elf64_sh64lnbsd_vec bfd_elf64_sh64nbsd_vec" - want64=true - ;; -#endif - - sh*-*-netbsdelf*) - targ_defvec=bfd_elf32_shnbsd_vec - targ_selvecs="bfd_elf32_shlnbsd_vec shcoff_vec shlcoff_vec" - ;; - sh*-*-symbianelf*) - targ_defvec=bfd_elf32_shl_symbian_vec - targ_selvecs="shlcoff_vec shlcoff_small_vec" - targ_underscore=yes - ;; - -#ifdef BFD64 - shl*-*-elf* | sh[1234]l*-*-elf* | sh3el*-*-elf* | shl*-*-kaos*) - targ_defvec=bfd_elf32_shl_vec - targ_selvecs="bfd_elf32_sh_vec shlcoff_vec shcoff_vec shlcoff_small_vec shcoff_small_vec bfd_elf32_sh64_vec bfd_elf32_sh64l_vec bfd_elf64_sh64_vec bfd_elf64_sh64l_vec" - targ_underscore=yes - want64=true - ;; -#endif - - sh-*-rtemscoff*) - targ_defvec=shcoff_vec - targ_selvecs="shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec" - targ_underscore=yes - ;; - -#ifdef BFD64 - sh-*-elf* | sh[1234]*-elf* | sh-*-rtems* | sh-*-kaos*) - targ_defvec=bfd_elf32_sh_vec - targ_selvecs="bfd_elf32_shl_vec shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec bfd_elf32_sh64_vec bfd_elf32_sh64l_vec bfd_elf64_sh64_vec bfd_elf64_sh64l_vec" - targ_underscore=yes - want64=true - ;; -#endif - - sh-*-nto*) - targ_defvec=bfd_elf32_sh_vec - targ_selvecs="bfd_elf32_shl_vec shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec" - targ_underscore=yes - ;; - sh*-*-openbsd*) - targ_defvec=bfd_elf32_shlnbsd_vec - targ_selvecs="bfd_elf32_shnbsd_vec shcoff_vec shlcoff_vec" - ;; - sh-*-pe) - targ_defvec=shlpe_vec - targ_selvecs="shlpe_vec shlpei_vec" - targ_underscore=yes - ;; - sh-*-vxworks) - targ_defvec=bfd_elf32_shvxworks_vec - targ_selvecs="bfd_elf32_shlvxworks_vec" - # FIXME None of the following are actually used on this target, but - # they're necessary for coff-sh.c (which is unconditionally used) to be - # compiled correctly. - targ_selvecs="$targ_selvecs shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec" - targ_underscore=yes - ;; - sh-*-*) - targ_defvec=shcoff_vec - targ_selvecs="shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec" - targ_underscore=yes - ;; - - sparclet-*-aout*) - targ_defvec=sunos_big_vec - targ_selvecs=sparcle_aout_vec - targ_underscore=yes - ;; - sparc86x-*-aout*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - sparclite-*-elf* | sparc86x-*-elf*) - targ_defvec=bfd_elf32_sparc_vec - ;; - sparc*-*-chorus*) - targ_defvec=bfd_elf32_sparc_vec - ;; - sparc-*-linux*aout*) - targ_defvec=sparclinux_vec - targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec" - targ_underscore=yes - ;; - sparc-*-linux-* | sparcv*-*-linux-*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs="sparclinux_vec bfd_elf64_sparc_vec sunos_big_vec" - ;; - sparc-*-netbsdelf*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs=sparcnetbsd_vec - ;; - sparc-*-netbsdaout* | sparc-*-netbsd*) - targ_defvec=sparcnetbsd_vec - targ_selvecs=bfd_elf32_sparc_vec - targ_underscore=yes - ;; - sparc-*-openbsd[0-2].* | sparc-*-openbsd3.[0-1]) - targ_defvec=sparcnetbsd_vec - targ_underscore=yes - ;; - sparc-*-openbsd*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs=sparcnetbsd_vec - ;; - sparc-*-elf*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs=sunos_big_vec - ;; - sparc-*-solaris2.[0-6] | sparc-*-solaris2.[0-6].*) - targ_defvec=bfd_elf32_sparc_sol2_vec - targ_selvecs=sunos_big_vec - ;; -#ifdef BFD64 - sparc-*-solaris2* | sparcv9-*-solaris2* | sparc64-*-solaris2*) - targ_defvec=bfd_elf32_sparc_sol2_vec - targ_selvecs="bfd_elf64_sparc_sol2_vec sunos_big_vec" - want64=true - ;; -#endif - sparc-*-sysv4*) - targ_defvec=bfd_elf32_sparc_vec - ;; - sparc-*-vxworks*) - targ_defvec=bfd_elf32_sparc_vxworks_vec - targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec" - ;; - sparc-*-netware*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs="nlm32_sparc_vec sunos_big_vec" - ;; -#ifdef BFD64 - sparc64-*-aout*) - targ_defvec=sunos_big_vec - targ_underscore=yes - want64=true - ;; - sparc64*-*-linux-*) - targ_defvec=bfd_elf64_sparc_vec - targ_selvecs="bfd_elf32_sparc_vec sparclinux_vec sunos_big_vec" - want64=true - ;; - sparc64-*-elf* | sparc64-*-rtems* ) - targ_defvec=bfd_elf64_sparc_vec - targ_selvecs=bfd_elf32_sparc_vec - want64=true - ;; -#endif /* BFD64 */ - sparc*-*-coff*) - targ_defvec=sparccoff_vec - ;; - sparc-*-rtems*) - targ_defvec=bfd_elf32_sparc_vec - targ_selvecs="sunos_big_vec sparccoff_vec" - ;; - sparc*-*-*) - targ_defvec=sunos_big_vec - targ_underscore=yes - ;; - - spu-*-elf) - targ_defvec=bfd_elf32_spu_vec - want64=true - ;; - -#if HAVE_host_aout_vec - tahoe-*-*) - targ_defvec=host_aout_vec - targ_underscore=yes - ;; -#endif - - tic6x-*-elf) - targ_defvec=bfd_elf32_tic6x_elf_le_vec - targ_selvecs="bfd_elf32_tic6x_elf_be_vec bfd_elf32_tic6x_le_vec bfd_elf32_tic6x_be_vec" - ;; - - tic6x-*-uclinux) - targ_defvec=bfd_elf32_tic6x_linux_le_vec - targ_selvecs="bfd_elf32_tic6x_linux_be_vec bfd_elf32_tic6x_le_vec bfd_elf32_tic6x_be_vec" - ;; - - tic80*-*-*) - targ_defvec=tic80coff_vec - targ_underscore=yes - ;; - -#ifdef BFD64 - tilegx-*-*) - targ_defvec=bfd_elf64_tilegx_vec - targ_selvecs=bfd_elf32_tilegx_vec - ;; -#endif - - tilepro-*-*) - targ_defvec=bfd_elf32_tilepro_vec - ;; - - v850*-*-*) - targ_defvec=bfd_elf32_v850_vec - ;; - - vax-*-netbsdelf*) - targ_defvec=bfd_elf32_vax_vec - targ_selvecs="vaxnetbsd_vec vax1knetbsd_vec" - ;; - - vax-*-netbsdaout* | vax-*-netbsd*) - targ_defvec=vaxnetbsd_vec - targ_selvecs="bfd_elf32_vax_vec vax1knetbsd_vec" - targ_underscore=yes - ;; - - vax-*-bsd* | vax-*-ultrix*) - targ_defvec=vaxbsd_vec - targ_underscore=yes - ;; - - vax-*-openbsd*) - targ_defvec=vaxnetbsd_vec - targ_underscore=yes - ;; - - vax-*-linux-*) - targ_defvec=bfd_elf32_vax_vec - ;; - - we32k-*-*) - targ_defvec=we32kcoff_vec - ;; - - w65-*-*) - targ_defvec=w65_vec - ;; - - xstormy16-*-elf) - targ_defvec=bfd_elf32_xstormy16_vec - ;; - - xtensa*-*-*) - targ_defvec=bfd_elf32_xtensa_le_vec - targ_selvecs=bfd_elf32_xtensa_be_vec - ;; - xc16x-*-elf) - targ_defvec=bfd_elf32_xc16x_vec - ;; - - z80-*-*) - targ_defvec=z80coff_vec - targ_underscore=no - ;; - - z8k*-*-*) - targ_defvec=z8kcoff_vec - targ_underscore=yes - ;; - - *-*-ieee*) - targ_defvec=ieee_vec - ;; - - *-adobe-*) - targ_defvec=a_out_adobe_vec - targ_underscore=yes - ;; - - *-sony-*) - targ_defvec=newsos3_vec - targ_underscore=yes - ;; - - *-tandem-*) - targ_defvec=m68kcoff_vec - targ_selvecs=ieee_vec - ;; -# END OF targmatch.h - *) - echo 1>&2 "*** BFD does not support target ${targ}." - echo 1>&2 "*** Look in bfd/config.bfd for supported targets." - exit 1 - ;; -esac - -case "${host64}${want64}" in - *true*) - targ_selvecs="${targ_selvecs} ${targ64_selvecs}" - ;; -esac - -# If we support any ELF target, then automatically add support for the -# generic ELF targets. This permits an objdump with some ELF support -# to be used on an arbitrary ELF file for anything other than -# relocation information. -case "${targ_defvec} ${targ_selvecs}" in - *bfd_elf64* | *bfd_elf32_n*mips*) - targ_selvecs="${targ_selvecs} bfd_elf64_little_generic_vec bfd_elf64_big_generic_vec bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec" - ;; - *bfd_elf32*) - targ_selvecs="${targ_selvecs} bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec" - ;; -esac - -# If we support Intel L1OM target, then add support for bfd_l1om_arch. -case "${targ_defvec} ${targ_selvecs}" in - *bfd_elf64_l1om_vec*) - targ_archs="$targ_archs bfd_l1om_arch" - ;; -esac - -# If we support Intel K1OM target, then add support for bfd_k1om_arch. -case "${targ_defvec} ${targ_selvecs}" in - *bfd_elf64_k1om_vec*) - targ_archs="$targ_archs bfd_k1om_arch" - ;; -esac diff --git a/contrib/binutils-2.22/bfd/corefile.c b/contrib/binutils-2.22/bfd/corefile.c deleted file mode 100644 index bba0d1ca4f..0000000000 --- a/contrib/binutils-2.22/bfd/corefile.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Core file generic interface routines for BFD. - Copyright 1990, 1991, 1992, 1993, 1994, 2000, 2001, 2002, 2003, 2005, - 2007 Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - Core files - -SUBSECTION - Core file functions - -DESCRIPTION - These are functions pertaining to core files. -*/ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -/* -FUNCTION - bfd_core_file_failing_command - -SYNOPSIS - const char *bfd_core_file_failing_command (bfd *abfd); - -DESCRIPTION - Return a read-only string explaining which program was running - when it failed and produced the core file @var{abfd}. - -*/ - -const char * -bfd_core_file_failing_command (bfd *abfd) -{ - if (abfd->format != bfd_core) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - return BFD_SEND (abfd, _core_file_failing_command, (abfd)); -} - -/* -FUNCTION - bfd_core_file_failing_signal - -SYNOPSIS - int bfd_core_file_failing_signal (bfd *abfd); - -DESCRIPTION - Returns the signal number which caused the core dump which - generated the file the BFD @var{abfd} is attached to. -*/ - -int -bfd_core_file_failing_signal (bfd *abfd) -{ - if (abfd->format != bfd_core) - { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - return BFD_SEND (abfd, _core_file_failing_signal, (abfd)); -} - -/* -FUNCTION - bfd_core_file_pid - -SYNOPSIS - int bfd_core_file_pid (bfd *abfd); - -DESCRIPTION - - Returns the PID of the process the core dump the BFD - @var{abfd} is attached to was generated from. -*/ - -int -bfd_core_file_pid (bfd *abfd) -{ - if (abfd->format != bfd_core) - { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - return BFD_SEND (abfd, _core_file_pid, (abfd)); -} - - -/* -FUNCTION - core_file_matches_executable_p - -SYNOPSIS - bfd_boolean core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -DESCRIPTION - Return <> if the core file attached to @var{core_bfd} - was generated by a run of the executable file attached to - @var{exec_bfd}, <> otherwise. -*/ - -bfd_boolean -core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd) -{ - if (core_bfd->format != bfd_core || exec_bfd->format != bfd_object) - { - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - return BFD_SEND (core_bfd, _core_file_matches_executable_p, - (core_bfd, exec_bfd)); -} - -/* -FUNCTION - generic_core_file_matches_executable_p - -SYNOPSIS - bfd_boolean generic_core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -DESCRIPTION - Return TRUE if the core file attached to @var{core_bfd} - was generated by a run of the executable file attached - to @var{exec_bfd}. The match is based on executable - basenames only. - - Note: When not able to determine the core file failing - command or the executable name, we still return TRUE even - though we're not sure that core file and executable match. - This is to avoid generating a false warning in situations - where we really don't know whether they match or not. -*/ - -bfd_boolean -generic_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd) -{ - char *exec; - char *core; - char *last_slash; - - if (exec_bfd == NULL || core_bfd == NULL) - return TRUE; - - /* The cast below is to avoid a compiler warning due to the assignment - of the const char * returned by bfd_core_file_failing_command to a - non-const char *. In this case, the assignement does not lead to - breaking the const, as we're only reading the string. */ - - core = (char *) bfd_core_file_failing_command (core_bfd); - if (core == NULL) - return TRUE; - - exec = bfd_get_filename (exec_bfd); - if (exec == NULL) - return TRUE; - - last_slash = strrchr (core, '/'); - if (last_slash != NULL) - core = last_slash + 1; - - last_slash = strrchr (exec, '/'); - if (last_slash != NULL) - exec = last_slash + 1; - - return filename_cmp (exec, core) == 0; -} - diff --git a/contrib/binutils-2.22/bfd/cpu-i386.c b/contrib/binutils-2.22/bfd/cpu-i386.c deleted file mode 100644 index f98c0e5052..0000000000 --- a/contrib/binutils-2.22/bfd/cpu-i386.c +++ /dev/null @@ -1,151 +0,0 @@ -/* BFD support for the Intel 386 architecture. - Copyright 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2004, 2005, - 2007, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -static const bfd_arch_info_type * -bfd_i386_compatible (const bfd_arch_info_type *a, - const bfd_arch_info_type *b) -{ - const bfd_arch_info_type *compat = bfd_default_compatible (a, b); - - /* Don't allow mixing x64_32 with x86_64. */ - if (compat - && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32)) - compat = NULL; - - return compat; -} - -static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_x64_32_intel_syntax, - "i386:intel", - "i386:x64-32:intel", - 3, - FALSE, - bfd_i386_compatible, - bfd_default_scan, - 0 -}; - -static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_x86_64_intel_syntax, - "i386:intel", - "i386:x86-64:intel", - 3, - FALSE, - bfd_i386_compatible, - bfd_default_scan, - &bfd_x64_32_arch_intel_syntax, -}; - -static const bfd_arch_info_type bfd_i386_arch_intel_syntax = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_i386_i386_intel_syntax, - "i386:intel", - "i386:intel", - 3, - TRUE, - bfd_i386_compatible, - bfd_default_scan, - &bfd_x86_64_arch_intel_syntax -}; - -static const bfd_arch_info_type i8086_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address (well, not really) */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_i386_i8086, - "i8086", - "i8086", - 3, - FALSE, - bfd_i386_compatible, - bfd_default_scan, - &bfd_i386_arch_intel_syntax -}; - -static const bfd_arch_info_type bfd_x64_32_arch = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_x64_32, - "i386", - "i386:x64-32", - 3, - FALSE, - bfd_i386_compatible, - bfd_default_scan, - &i8086_arch -}; - -static const bfd_arch_info_type bfd_x86_64_arch = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_x86_64, - "i386", - "i386:x86-64", - 3, - FALSE, - bfd_i386_compatible, - bfd_default_scan, - &bfd_x64_32_arch -}; - -const bfd_arch_info_type bfd_i386_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - bfd_mach_i386_i386, - "i386", - "i386", - 3, - TRUE, - bfd_i386_compatible, - bfd_default_scan, - &bfd_x86_64_arch -}; diff --git a/contrib/binutils-2.22/bfd/cpu-l1om.c b/contrib/binutils-2.22/bfd/cpu-l1om.c deleted file mode 100644 index c1057c4e9b..0000000000 --- a/contrib/binutils-2.22/bfd/cpu-l1om.c +++ /dev/null @@ -1,56 +0,0 @@ -/* BFD support for the Intel L1OM architecture. - Copyright 2009 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -static const bfd_arch_info_type bfd_l1om_arch_intel_syntax = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_l1om, - bfd_mach_l1om_intel_syntax, - "l1om:intel", - "l1om:intel", - 3, - TRUE, - bfd_default_compatible, - bfd_default_scan, - 0 -}; - -const bfd_arch_info_type bfd_l1om_arch = -{ - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_l1om, - bfd_mach_l1om, - "l1om", - "l1om", - 3, - TRUE, - bfd_default_compatible, - bfd_default_scan, - &bfd_l1om_arch_intel_syntax -}; diff --git a/contrib/binutils-2.22/bfd/doc/bfdsumm.texi b/contrib/binutils-2.22/bfd/doc/bfdsumm.texi deleted file mode 100644 index 77a5f09e51..0000000000 --- a/contrib/binutils-2.22/bfd/doc/bfdsumm.texi +++ /dev/null @@ -1,148 +0,0 @@ -@c This summary of BFD is shared by the BFD and LD docs. -When an object file is opened, BFD subroutines automatically determine -the format of the input object file. They then build a descriptor in -memory with pointers to routines that will be used to access elements of -the object file's data structures. - -As different information from the object files is required, -BFD reads from different sections of the file and processes them. -For example, a very common operation for the linker is processing symbol -tables. Each BFD back end provides a routine for converting -between the object file's representation of symbols and an internal -canonical format. When the linker asks for the symbol table of an object -file, it calls through a memory pointer to the routine from the -relevant BFD back end which reads and converts the table into a canonical -form. The linker then operates upon the canonical form. When the link is -finished and the linker writes the output file's symbol table, -another BFD back end routine is called to take the newly -created symbol table and convert it into the chosen output format. - -@menu -* BFD information loss:: Information Loss -* Canonical format:: The BFD canonical object-file format -@end menu - -@node BFD information loss -@subsection Information Loss - -@emph{Information can be lost during output.} The output formats -supported by BFD do not provide identical facilities, and -information which can be described in one form has nowhere to go in -another format. One example of this is alignment information in -@code{b.out}. There is nowhere in an @code{a.out} format file to store -alignment information on the contained data, so when a file is linked -from @code{b.out} and an @code{a.out} image is produced, alignment -information will not propagate to the output file. (The linker will -still use the alignment information internally, so the link is performed -correctly). - -Another example is COFF section names. COFF files may contain an -unlimited number of sections, each one with a textual section name. If -the target of the link is a format which does not have many sections (e.g., -@code{a.out}) or has sections without names (e.g., the Oasys format), the -link cannot be done simply. You can circumvent this problem by -describing the desired input-to-output section mapping with the linker command -language. - -@emph{Information can be lost during canonicalization.} The BFD -internal canonical form of the external formats is not exhaustive; there -are structures in input formats for which there is no direct -representation internally. This means that the BFD back ends -cannot maintain all possible data richness through the transformation -between external to internal and back to external formats. - -This limitation is only a problem when an application reads one -format and writes another. Each BFD back end is responsible for -maintaining as much data as possible, and the internal BFD -canonical form has structures which are opaque to the BFD core, -and exported only to the back ends. When a file is read in one format, -the canonical form is generated for BFD and the application. At the -same time, the back end saves away any information which may otherwise -be lost. If the data is then written back in the same format, the back -end routine will be able to use the canonical form provided by the -BFD core as well as the information it prepared earlier. Since -there is a great deal of commonality between back ends, -there is no information lost when -linking or copying big endian COFF to little endian COFF, or @code{a.out} to -@code{b.out}. When a mixture of formats is linked, the information is -only lost from the files whose format differs from the destination. - -@node Canonical format -@subsection The BFD canonical object-file format - -The greatest potential for loss of information occurs when there is the least -overlap between the information provided by the source format, that -stored by the canonical format, and that needed by the -destination format. A brief description of the canonical form may help -you understand which kinds of data you can count on preserving across -conversions. -@cindex BFD canonical format -@cindex internal object-file format - -@table @emph -@item files -Information stored on a per-file basis includes target machine -architecture, particular implementation format type, a demand pageable -bit, and a write protected bit. Information like Unix magic numbers is -not stored here---only the magic numbers' meaning, so a @code{ZMAGIC} -file would have both the demand pageable bit and the write protected -text bit set. The byte order of the target is stored on a per-file -basis, so that big- and little-endian object files may be used with one -another. - -@item sections -Each section in the input file contains the name of the section, the -section's original address in the object file, size and alignment -information, various flags, and pointers into other BFD data -structures. - -@item symbols -Each symbol contains a pointer to the information for the object file -which originally defined it, its name, its value, and various flag -bits. When a BFD back end reads in a symbol table, it relocates all -symbols to make them relative to the base of the section where they were -defined. Doing this ensures that each symbol points to its containing -section. Each symbol also has a varying amount of hidden private data -for the BFD back end. Since the symbol points to the original file, the -private data format for that symbol is accessible. @code{ld} can -operate on a collection of symbols of wildly different formats without -problems. - -Normal global and simple local symbols are maintained on output, so an -output file (no matter its format) will retain symbols pointing to -functions and to global, static, and common variables. Some symbol -information is not worth retaining; in @code{a.out}, type information is -stored in the symbol table as long symbol names. This information would -be useless to most COFF debuggers; the linker has command line switches -to allow users to throw it away. - -There is one word of type information within the symbol, so if the -format supports symbol type information within symbols (for example, COFF, -IEEE, Oasys) and the type is simple enough to fit within one word -(nearly everything but aggregates), the information will be preserved. - -@item relocation level -Each canonical BFD relocation record contains a pointer to the symbol to -relocate to, the offset of the data to relocate, the section the data -is in, and a pointer to a relocation type descriptor. Relocation is -performed by passing messages through the relocation type -descriptor and the symbol pointer. Therefore, relocations can be performed -on output data using a relocation method that is only available in one of the -input formats. For instance, Oasys provides a byte relocation format. -A relocation record requesting this relocation type would point -indirectly to a routine to perform this, so the relocation may be -performed on a byte being written to a 68k COFF file, even though 68k COFF -has no such relocation type. - -@item line numbers -Object formats can contain, for debugging purposes, some form of mapping -between symbols, source line numbers, and addresses in the output file. -These addresses have to be relocated along with the symbol information. -Each symbol with an associated list of line number records points to the -first record of the list. The head of a line number list consists of a -pointer to the symbol, which allows finding out the address of the -function whose line number is being described. The rest of the list is -made up of pairs: offsets into the section and line numbers. Any format -which can simply derive this information can pass it successfully -between formats (COFF, IEEE and Oasys). -@end table diff --git a/contrib/binutils-2.22/bfd/doc/bfdver.texi b/contrib/binutils-2.22/bfd/doc/bfdver.texi deleted file mode 100644 index 0529522473..0000000000 --- a/contrib/binutils-2.22/bfd/doc/bfdver.texi +++ /dev/null @@ -1,4 +0,0 @@ -@set VERSION 2.22 -@set VERSION_PACKAGE (GNU Binutils) -@set UPDATED November 2011 -@set BUGURL @uref{http://www.sourceware.org/bugzilla/} diff --git a/contrib/binutils-2.22/bfd/dwarf1.c b/contrib/binutils-2.22/bfd/dwarf1.c deleted file mode 100644 index 375f4cf166..0000000000 --- a/contrib/binutils-2.22/bfd/dwarf1.c +++ /dev/null @@ -1,564 +0,0 @@ -/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line). - Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com). - - This file is part of BFD. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/dwarf.h" - -/* dwarf1_debug is the starting point for all dwarf1 info. */ - -struct dwarf1_debug -{ - /* The bfd we are working with. */ - bfd* abfd; - - /* Pointer to the symbol table. */ - asymbol** syms; - - /* List of already parsed compilation units. */ - struct dwarf1_unit* lastUnit; - - /* The buffer for the .debug section. - Zero indicates that the .debug section failed to load. */ - bfd_byte *debug_section; - - /* Pointer to the end of the .debug_info section memory buffer. */ - bfd_byte *debug_section_end; - - /* The buffer for the .line section. */ - bfd_byte *line_section; - - /* End of that buffer. */ - bfd_byte *line_section_end; - - /* The current or next unread die within the .debug section. */ - bfd_byte *currentDie; -}; - -/* One dwarf1_unit for each parsed compilation unit die. */ - -struct dwarf1_unit -{ - /* Linked starting from stash->lastUnit. */ - struct dwarf1_unit* prev; - - /* Name of the compilation unit. */ - char *name; - - /* The highest and lowest address used in the compilation unit. */ - unsigned long low_pc; - unsigned long high_pc; - - /* Does this unit have a statement list? */ - int has_stmt_list; - - /* If any, the offset of the line number table in the .line section. */ - unsigned long stmt_list_offset; - - /* If non-zero, a pointer to the first child of this unit. */ - bfd_byte *first_child; - - /* How many line entries? */ - unsigned long line_count; - - /* The decoded line number table (line_count entries). */ - struct linenumber* linenumber_table; - - /* The list of functions in this unit. */ - struct dwarf1_func* func_list; -}; - -/* One dwarf1_func for each parsed function die. */ - -struct dwarf1_func -{ - /* Linked starting from aUnit->func_list. */ - struct dwarf1_func* prev; - - /* Name of function. */ - char* name; - - /* The highest and lowest address used in the compilation unit. */ - unsigned long low_pc; - unsigned long high_pc; -}; - -/* Used to return info about a parsed die. */ -struct die_info -{ - unsigned long length; - unsigned long sibling; - unsigned long low_pc; - unsigned long high_pc; - unsigned long stmt_list_offset; - - char* name; - - int has_stmt_list; - - unsigned short tag; -}; - -/* Parsed line number information. */ -struct linenumber -{ - /* First address in the line. */ - unsigned long addr; - - /* The line number. */ - unsigned long linenumber; -}; - -/* Find the form of an attr, from the attr field. */ -#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified. */ - -/* Return a newly allocated dwarf1_unit. It should be cleared and - then attached into the 'stash' at 'stash->lastUnit'. */ - -static struct dwarf1_unit* -alloc_dwarf1_unit (struct dwarf1_debug* stash) -{ - bfd_size_type amt = sizeof (struct dwarf1_unit); - - struct dwarf1_unit* x = (struct dwarf1_unit *) bfd_zalloc (stash->abfd, amt); - if (x) - { - x->prev = stash->lastUnit; - stash->lastUnit = x; - } - - return x; -} - -/* Return a newly allocated dwarf1_func. It must be cleared and - attached into 'aUnit' at 'aUnit->func_list'. */ - -static struct dwarf1_func * -alloc_dwarf1_func (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit) -{ - bfd_size_type amt = sizeof (struct dwarf1_func); - - struct dwarf1_func* x = (struct dwarf1_func *) bfd_zalloc (stash->abfd, amt); - if (x) - { - x->prev = aUnit->func_list; - aUnit->func_list = x; - } - - return x; -} - -/* parse_die - parse a Dwarf1 die. - Parse the die starting at 'aDiePtr' into 'aDieInfo'. - 'abfd' must be the bfd from which the section that 'aDiePtr' - points to was pulled from. - - Return FALSE if the die is invalidly formatted; TRUE otherwise. */ - -static bfd_boolean -parse_die (bfd * abfd, - struct die_info * aDieInfo, - bfd_byte * aDiePtr, - bfd_byte * aDiePtrEnd) -{ - bfd_byte *this_die = aDiePtr; - bfd_byte *xptr = this_die; - - memset (aDieInfo, 0, sizeof (* aDieInfo)); - - /* First comes the length. */ - aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr); - xptr += 4; - if (aDieInfo->length == 0 - || (this_die + aDieInfo->length) >= aDiePtrEnd) - return FALSE; - if (aDieInfo->length < 6) - { - /* Just padding bytes. */ - aDieInfo->tag = TAG_padding; - return TRUE; - } - - /* Then the tag. */ - aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr); - xptr += 2; - - /* Then the attributes. */ - while (xptr < (this_die + aDieInfo->length)) - { - unsigned short attr; - - /* Parse the attribute based on its form. This section - must handle all dwarf1 forms, but need only handle the - actual attributes that we care about. */ - attr = bfd_get_16 (abfd, (bfd_byte *) xptr); - xptr += 2; - - switch (FORM_FROM_ATTR (attr)) - { - case FORM_DATA2: - xptr += 2; - break; - case FORM_DATA4: - case FORM_REF: - if (attr == AT_sibling) - aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr); - else if (attr == AT_stmt_list) - { - aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr); - aDieInfo->has_stmt_list = 1; - } - xptr += 4; - break; - case FORM_DATA8: - xptr += 8; - break; - case FORM_ADDR: - if (attr == AT_low_pc) - aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr); - else if (attr == AT_high_pc) - aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr); - xptr += 4; - break; - case FORM_BLOCK2: - xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr); - break; - case FORM_BLOCK4: - xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr); - break; - case FORM_STRING: - if (attr == AT_name) - aDieInfo->name = (char *) xptr; - xptr += strlen ((char *) xptr) + 1; - break; - } - } - - return TRUE; -} - -/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset' - into 'aUnit->linenumber_table'. Return FALSE if an error - occurs; TRUE otherwise. */ - -static bfd_boolean -parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit) -{ - bfd_byte *xptr; - - /* Load the ".line" section from the bfd if we haven't already. */ - if (stash->line_section == 0) - { - asection *msec; - bfd_size_type size; - - msec = bfd_get_section_by_name (stash->abfd, ".line"); - if (! msec) - return FALSE; - - size = msec->rawsize ? msec->rawsize : msec->size; - stash->line_section - = bfd_simple_get_relocated_section_contents - (stash->abfd, msec, NULL, stash->syms); - - if (! stash->line_section) - return FALSE; - - stash->line_section_end = stash->line_section + size; - } - - xptr = stash->line_section + aUnit->stmt_list_offset; - if (xptr < stash->line_section_end) - { - unsigned long eachLine; - bfd_byte *tblend; - unsigned long base; - bfd_size_type amt; - - /* First comes the length. */ - tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr; - xptr += 4; - - /* Then the base address for each address in the table. */ - base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); - xptr += 4; - - /* How many line entrys? - 10 = 4 (line number) + 2 (pos in line) + 4 (address in line). */ - aUnit->line_count = (tblend - xptr) / 10; - - /* Allocate an array for the entries. */ - amt = sizeof (struct linenumber) * aUnit->line_count; - aUnit->linenumber_table = (struct linenumber *) bfd_alloc (stash->abfd, - amt); - if (!aUnit->linenumber_table) - return FALSE; - - for (eachLine = 0; eachLine < aUnit->line_count; eachLine++) - { - /* A line number. */ - aUnit->linenumber_table[eachLine].linenumber - = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); - xptr += 4; - - /* Skip the position within the line. */ - xptr += 2; - - /* And finally the address. */ - aUnit->linenumber_table[eachLine].addr - = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr); - xptr += 4; - } - } - - return TRUE; -} - -/* Parse each function die in a compilation unit 'aUnit'. - The first child die of 'aUnit' should be in 'aUnit->first_child', - the result is placed in 'aUnit->func_list'. - Return FALSE if error; TRUE otherwise. */ - -static bfd_boolean -parse_functions_in_unit (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit) -{ - bfd_byte *eachDie; - - if (aUnit->first_child) - for (eachDie = aUnit->first_child; - eachDie < stash->debug_section_end; - ) - { - struct die_info eachDieInfo; - - if (! parse_die (stash->abfd, &eachDieInfo, eachDie, - stash->debug_section_end)) - return FALSE; - - if (eachDieInfo.tag == TAG_global_subroutine - || eachDieInfo.tag == TAG_subroutine - || eachDieInfo.tag == TAG_inlined_subroutine - || eachDieInfo.tag == TAG_entry_point) - { - struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit); - if (!aFunc) - return FALSE; - - aFunc->name = eachDieInfo.name; - aFunc->low_pc = eachDieInfo.low_pc; - aFunc->high_pc = eachDieInfo.high_pc; - } - - /* Move to next sibling, if none, end loop */ - if (eachDieInfo.sibling) - eachDie = stash->debug_section + eachDieInfo.sibling; - else - break; - } - - return TRUE; -} - -/* Find the nearest line to 'addr' in 'aUnit'. - Return whether we found the line (or a function) without error. */ - -static bfd_boolean -dwarf1_unit_find_nearest_line (struct dwarf1_debug* stash, - struct dwarf1_unit* aUnit, - unsigned long addr, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr) -{ - int line_p = FALSE; - int func_p = FALSE; - - if (aUnit->low_pc <= addr && addr < aUnit->high_pc) - { - if (aUnit->has_stmt_list) - { - unsigned long i; - struct dwarf1_func* eachFunc; - - if (! aUnit->linenumber_table) - { - if (! parse_line_table (stash, aUnit)) - return FALSE; - } - - if (! aUnit->func_list) - { - if (! parse_functions_in_unit (stash, aUnit)) - return FALSE; - } - - for (i = 0; i < aUnit->line_count; i++) - { - if (aUnit->linenumber_table[i].addr <= addr - && addr < aUnit->linenumber_table[i+1].addr) - { - *filename_ptr = aUnit->name; - *linenumber_ptr = aUnit->linenumber_table[i].linenumber; - line_p = TRUE; - break; - } - } - - for (eachFunc = aUnit->func_list; - eachFunc; - eachFunc = eachFunc->prev) - { - if (eachFunc->low_pc <= addr - && addr < eachFunc->high_pc) - { - *functionname_ptr = eachFunc->name; - func_p = TRUE; - break; - } - } - } - } - - return line_p || func_p; -} - -/* The DWARF 1 version of find_nearest line. - Return TRUE if the line is found without error. */ - -bfd_boolean -_bfd_dwarf1_find_nearest_line (bfd *abfd, - asection *section, - asymbol **symbols, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr) -{ - struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info; - - struct dwarf1_unit* eachUnit; - - /* What address are we looking for? */ - unsigned long addr = (unsigned long)(offset + section->vma); - - *filename_ptr = NULL; - *functionname_ptr = NULL; - *linenumber_ptr = 0; - - if (! stash) - { - asection *msec; - bfd_size_type size = sizeof (struct dwarf1_debug); - - stash = elf_tdata (abfd)->dwarf1_find_line_info - = (struct dwarf1_debug *) bfd_zalloc (abfd, size); - - if (! stash) - return FALSE; - - msec = bfd_get_section_by_name (abfd, ".debug"); - if (! msec) - /* No dwarf1 info. Note that at this point the stash - has been allocated, but contains zeros, this lets - future calls to this function fail quicker. */ - return FALSE; - - size = msec->rawsize ? msec->rawsize : msec->size; - stash->debug_section - = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, - symbols); - - if (! stash->debug_section) - return FALSE; - - stash->debug_section_end = stash->debug_section + size; - stash->currentDie = stash->debug_section; - stash->abfd = abfd; - stash->syms = symbols; - } - - /* A null debug_section indicates that there was no dwarf1 info - or that an error occured while setting up the stash. */ - - if (! stash->debug_section) - return FALSE; - - /* Look at the previously parsed units to see if any contain - the addr. */ - for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev) - if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc) - return dwarf1_unit_find_nearest_line (stash, eachUnit, addr, - filename_ptr, - functionname_ptr, - linenumber_ptr); - - while (stash->currentDie < stash->debug_section_end) - { - struct die_info aDieInfo; - - if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie, - stash->debug_section_end)) - return FALSE; - - if (aDieInfo.tag == TAG_compile_unit) - { - struct dwarf1_unit* aUnit - = alloc_dwarf1_unit (stash); - if (!aUnit) - return FALSE; - - aUnit->name = aDieInfo.name; - aUnit->low_pc = aDieInfo.low_pc; - aUnit->high_pc = aDieInfo.high_pc; - aUnit->has_stmt_list = aDieInfo.has_stmt_list; - aUnit->stmt_list_offset = aDieInfo.stmt_list_offset; - - /* A die has a child if it's followed by a die that is - not it's sibling. */ - if (aDieInfo.sibling - && stash->currentDie + aDieInfo.length - < stash->debug_section_end - && stash->currentDie + aDieInfo.length - != stash->debug_section + aDieInfo.sibling) - aUnit->first_child = stash->currentDie + aDieInfo.length; - else - aUnit->first_child = 0; - - if (aUnit->low_pc <= addr && addr < aUnit->high_pc) - return dwarf1_unit_find_nearest_line (stash, aUnit, addr, - filename_ptr, - functionname_ptr, - linenumber_ptr); - } - - if (aDieInfo.sibling != 0) - stash->currentDie = stash->debug_section + aDieInfo.sibling; - else - stash->currentDie += aDieInfo.length; - } - - return FALSE; -} diff --git a/contrib/binutils-2.22/bfd/dwarf2.c b/contrib/binutils-2.22/bfd/dwarf2.c deleted file mode 100644 index 3cd2f7d7d4..0000000000 --- a/contrib/binutils-2.22/bfd/dwarf2.c +++ /dev/null @@ -1,3583 +0,0 @@ -/* DWARF 2 support. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - - Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions - (gavin@cygnus.com). - - From the dwarf2read.c header: - Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, - Inc. with support from Florida State University (under contract - with the Ada Joint Program Office), and Silicon Graphics, Inc. - Initial contribution by Brent Benson, Harris Computer Systems, Inc., - based on Fred Fish's (Cygnus Support) implementation of DWARF 1 - support in dwarfread.c - - This file is part of BFD. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "dwarf2.h" - -/* The data in the .debug_line statement prologue looks like this. */ - -struct line_head -{ - bfd_vma total_length; - unsigned short version; - bfd_vma prologue_length; - unsigned char minimum_instruction_length; - unsigned char maximum_ops_per_insn; - unsigned char default_is_stmt; - int line_base; - unsigned char line_range; - unsigned char opcode_base; - unsigned char *standard_opcode_lengths; -}; - -/* Attributes have a name and a value. */ - -struct attribute -{ - enum dwarf_attribute name; - enum dwarf_form form; - union - { - char *str; - struct dwarf_block *blk; - bfd_uint64_t val; - bfd_int64_t sval; - } - u; -}; - -/* Blocks are a bunch of untyped bytes. */ -struct dwarf_block -{ - unsigned int size; - bfd_byte *data; -}; - -struct adjusted_section -{ - asection *section; - bfd_vma adj_vma; -}; - -struct dwarf2_debug -{ - /* A list of all previously read comp_units. */ - struct comp_unit *all_comp_units; - - /* Last comp unit in list above. */ - struct comp_unit *last_comp_unit; - - /* The next unread compilation unit within the .debug_info section. - Zero indicates that the .debug_info section has not been loaded - into a buffer yet. */ - bfd_byte *info_ptr; - - /* Pointer to the end of the .debug_info section memory buffer. */ - bfd_byte *info_ptr_end; - - /* Pointer to the bfd, section and address of the beginning of the - section. The bfd might be different than expected because of - gnu_debuglink sections. */ - bfd *bfd_ptr; - asection *sec; - bfd_byte *sec_info_ptr; - - /* A pointer to the memory block allocated for info_ptr. Neither - info_ptr nor sec_info_ptr are guaranteed to stay pointing to the - beginning of the malloc block. This is used only to free the - memory later. */ - bfd_byte *info_ptr_memory; - - /* Pointer to the symbol table. */ - asymbol **syms; - - /* Pointer to the .debug_abbrev section loaded into memory. */ - bfd_byte *dwarf_abbrev_buffer; - - /* Length of the loaded .debug_abbrev section. */ - bfd_size_type dwarf_abbrev_size; - - /* Buffer for decode_line_info. */ - bfd_byte *dwarf_line_buffer; - - /* Length of the loaded .debug_line section. */ - bfd_size_type dwarf_line_size; - - /* Pointer to the .debug_str section loaded into memory. */ - bfd_byte *dwarf_str_buffer; - - /* Length of the loaded .debug_str section. */ - bfd_size_type dwarf_str_size; - - /* Pointer to the .debug_ranges section loaded into memory. */ - bfd_byte *dwarf_ranges_buffer; - - /* Length of the loaded .debug_ranges section. */ - bfd_size_type dwarf_ranges_size; - - /* If the most recent call to bfd_find_nearest_line was given an - address in an inlined function, preserve a pointer into the - calling chain for subsequent calls to bfd_find_inliner_info to - use. */ - struct funcinfo *inliner_chain; - - /* Number of sections whose VMA we must adjust. */ - unsigned int adjusted_section_count; - - /* Array of sections with adjusted VMA. */ - struct adjusted_section *adjusted_sections; - - /* Number of times find_line is called. This is used in - the heuristic for enabling the info hash tables. */ - int info_hash_count; - -#define STASH_INFO_HASH_TRIGGER 100 - - /* Hash table mapping symbol names to function infos. */ - struct info_hash_table *funcinfo_hash_table; - - /* Hash table mapping symbol names to variable infos. */ - struct info_hash_table *varinfo_hash_table; - - /* Head of comp_unit list in the last hash table update. */ - struct comp_unit *hash_units_head; - - /* Status of info hash. */ - int info_hash_status; -#define STASH_INFO_HASH_OFF 0 -#define STASH_INFO_HASH_ON 1 -#define STASH_INFO_HASH_DISABLED 2 -}; - -struct arange -{ - struct arange *next; - bfd_vma low; - bfd_vma high; -}; - -/* A minimal decoding of DWARF2 compilation units. We only decode - what's needed to get to the line number information. */ - -struct comp_unit -{ - /* Chain the previously read compilation units. */ - struct comp_unit *next_unit; - - /* Likewise, chain the compilation unit read after this one. - The comp units are stored in reversed reading order. */ - struct comp_unit *prev_unit; - - /* Keep the bfd convenient (for memory allocation). */ - bfd *abfd; - - /* The lowest and highest addresses contained in this compilation - unit as specified in the compilation unit header. */ - struct arange arange; - - /* The DW_AT_name attribute (for error messages). */ - char *name; - - /* The abbrev hash table. */ - struct abbrev_info **abbrevs; - - /* Note that an error was found by comp_unit_find_nearest_line. */ - int error; - - /* The DW_AT_comp_dir attribute. */ - char *comp_dir; - - /* TRUE if there is a line number table associated with this comp. unit. */ - int stmtlist; - - /* Pointer to the current comp_unit so that we can find a given entry - by its reference. */ - bfd_byte *info_ptr_unit; - - /* Pointer to the start of the debug section, for DW_FORM_ref_addr. */ - bfd_byte *sec_info_ptr; - - /* The offset into .debug_line of the line number table. */ - unsigned long line_offset; - - /* Pointer to the first child die for the comp unit. */ - bfd_byte *first_child_die_ptr; - - /* The end of the comp unit. */ - bfd_byte *end_ptr; - - /* The decoded line number, NULL if not yet decoded. */ - struct line_info_table *line_table; - - /* A list of the functions found in this comp. unit. */ - struct funcinfo *function_table; - - /* A list of the variables found in this comp. unit. */ - struct varinfo *variable_table; - - /* Pointer to dwarf2_debug structure. */ - struct dwarf2_debug *stash; - - /* DWARF format version for this unit - from unit header. */ - int version; - - /* Address size for this unit - from unit header. */ - unsigned char addr_size; - - /* Offset size for this unit - from unit header. */ - unsigned char offset_size; - - /* Base address for this unit - from DW_AT_low_pc attribute of - DW_TAG_compile_unit DIE */ - bfd_vma base_address; - - /* TRUE if symbols are cached in hash table for faster lookup by name. */ - bfd_boolean cached; -}; - -/* This data structure holds the information of an abbrev. */ -struct abbrev_info -{ - unsigned int number; /* Number identifying abbrev. */ - enum dwarf_tag tag; /* DWARF tag. */ - int has_children; /* Boolean. */ - unsigned int num_attrs; /* Number of attributes. */ - struct attr_abbrev *attrs; /* An array of attribute descriptions. */ - struct abbrev_info *next; /* Next in chain. */ -}; - -struct attr_abbrev -{ - enum dwarf_attribute name; - enum dwarf_form form; -}; - -/* Map of uncompressed DWARF debug section name to compressed one. It - is terminated by NULL uncompressed_name. */ - -const struct dwarf_debug_section dwarf_debug_sections[] = -{ - { ".debug_abbrev", ".zdebug_abbrev" }, - { ".debug_aranges", ".zdebug_aranges" }, - { ".debug_frame", ".zdebug_frame" }, - { ".debug_info", ".zdebug_info" }, - { ".debug_line", ".zdebug_line" }, - { ".debug_loc", ".zdebug_loc" }, - { ".debug_macinfo", ".zdebug_macinfo" }, - { ".debug_macro", ".zdebug_macro" }, - { ".debug_pubnames", ".zdebug_pubnames" }, - { ".debug_pubtypes", ".zdebug_pubtypes" }, - { ".debug_ranges", ".zdebug_ranges" }, - { ".debug_static_func", ".zdebug_static_func" }, - { ".debug_static_vars", ".zdebug_static_vars" }, - { ".debug_str", ".zdebug_str", }, - { ".debug_types", ".zdebug_types" }, - /* GNU DWARF 1 extensions */ - { ".debug_sfnames", ".zdebug_sfnames" }, - { ".debug_srcinfo", ".zebug_srcinfo" }, - /* SGI/MIPS DWARF 2 extensions */ - { ".debug_funcnames", ".zdebug_funcnames" }, - { ".debug_typenames", ".zdebug_typenames" }, - { ".debug_varnames", ".zdebug_varnames" }, - { ".debug_weaknames", ".zdebug_weaknames" }, - { NULL, NULL }, -}; - -enum dwarf_debug_section_enum -{ - debug_abbrev = 0, - debug_aranges, - debug_frame, - debug_info, - debug_line, - debug_loc, - debug_macinfo, - debug_macro, - debug_pubnames, - debug_pubtypes, - debug_ranges, - debug_static_func, - debug_static_vars, - debug_str, - debug_types, - debug_sfnames, - debug_srcinfo, - debug_funcnames, - debug_typenames, - debug_varnames, - debug_weaknames -}; - -#ifndef ABBREV_HASH_SIZE -#define ABBREV_HASH_SIZE 121 -#endif -#ifndef ATTR_ALLOC_CHUNK -#define ATTR_ALLOC_CHUNK 4 -#endif - -/* Variable and function hash tables. This is used to speed up look-up - in lookup_symbol_in_var_table() and lookup_symbol_in_function_table(). - In order to share code between variable and function infos, we use - a list of untyped pointer for all variable/function info associated with - a symbol. We waste a bit of memory for list with one node but that - simplifies the code. */ - -struct info_list_node -{ - struct info_list_node *next; - void *info; -}; - -/* Info hash entry. */ -struct info_hash_entry -{ - struct bfd_hash_entry root; - struct info_list_node *head; -}; - -struct info_hash_table -{ - struct bfd_hash_table base; -}; - -/* Function to create a new entry in info hash table. */ - -static struct bfd_hash_entry * -info_hash_table_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - struct info_hash_entry *ret = (struct info_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - derived class. */ - if (ret == NULL) - { - ret = (struct info_hash_entry *) bfd_hash_allocate (table, - sizeof (* ret)); - if (ret == NULL) - return NULL; - } - - /* Call the allocation method of the base class. */ - ret = ((struct info_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - /* Initialize the local fields here. */ - if (ret) - ret->head = NULL; - - return (struct bfd_hash_entry *) ret; -} - -/* Function to create a new info hash table. It returns a pointer to the - newly created table or NULL if there is any error. We need abfd - solely for memory allocation. */ - -static struct info_hash_table * -create_info_hash_table (bfd *abfd) -{ - struct info_hash_table *hash_table; - - hash_table = (struct info_hash_table *) - bfd_alloc (abfd, sizeof (struct info_hash_table)); - if (!hash_table) - return hash_table; - - if (!bfd_hash_table_init (&hash_table->base, info_hash_table_newfunc, - sizeof (struct info_hash_entry))) - { - bfd_release (abfd, hash_table); - return NULL; - } - - return hash_table; -} - -/* Insert an info entry into an info hash table. We do not check of - duplicate entries. Also, the caller need to guarantee that the - right type of info in inserted as info is passed as a void* pointer. - This function returns true if there is no error. */ - -static bfd_boolean -insert_info_hash_table (struct info_hash_table *hash_table, - const char *key, - void *info, - bfd_boolean copy_p) -{ - struct info_hash_entry *entry; - struct info_list_node *node; - - entry = (struct info_hash_entry*) bfd_hash_lookup (&hash_table->base, - key, TRUE, copy_p); - if (!entry) - return FALSE; - - node = (struct info_list_node *) bfd_hash_allocate (&hash_table->base, - sizeof (*node)); - if (!node) - return FALSE; - - node->info = info; - node->next = entry->head; - entry->head = node; - - return TRUE; -} - -/* Look up an info entry list from an info hash table. Return NULL - if there is none. */ - -static struct info_list_node * -lookup_info_hash_table (struct info_hash_table *hash_table, const char *key) -{ - struct info_hash_entry *entry; - - entry = (struct info_hash_entry*) bfd_hash_lookup (&hash_table->base, key, - FALSE, FALSE); - return entry ? entry->head : NULL; -} - -/* Read a section into its appropriate place in the dwarf2_debug - struct (indicated by SECTION_BUFFER and SECTION_SIZE). If SYMS is - not NULL, use bfd_simple_get_relocated_section_contents to read the - section contents, otherwise use bfd_get_section_contents. Fail if - the located section does not contain at least OFFSET bytes. */ - -static bfd_boolean -read_section (bfd * abfd, - enum dwarf_debug_section_enum sec, - asymbol ** syms, - bfd_uint64_t offset, - bfd_byte ** section_buffer, - bfd_size_type * section_size) -{ - asection *msec; - const char *section_name = dwarf_debug_sections[sec].uncompressed_name; - - /* read_section is a noop if the section has already been read. */ - if (!*section_buffer) - { - msec = bfd_get_section_by_name (abfd, section_name); - if (! msec) - { - section_name = dwarf_debug_sections[sec].compressed_name; - msec = bfd_get_section_by_name (abfd, section_name); - } - if (! msec) - { - (*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."), section_name); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - *section_size = msec->rawsize ? msec->rawsize : msec->size; - if (syms) - { - *section_buffer - = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms); - if (! *section_buffer) - return FALSE; - } - else - { - *section_buffer = (bfd_byte *) bfd_malloc (*section_size); - if (! *section_buffer) - return FALSE; - if (! bfd_get_section_contents (abfd, msec, *section_buffer, - 0, *section_size)) - return FALSE; - } - } - - /* It is possible to get a bad value for the offset into the section - that the client wants. Validate it here to avoid trouble later. */ - if (offset != 0 && offset >= *section_size) - { - (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."), - (long) offset, section_name, *section_size); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - return TRUE; -} - -/* VERBATIM - The following function up to the END VERBATIM mark are - copied directly from dwarf2read.c. */ - -/* Read dwarf information from a buffer. */ - -static unsigned int -read_1_byte (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *buf) -{ - return bfd_get_8 (abfd, buf); -} - -static int -read_1_signed_byte (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *buf) -{ - return bfd_get_signed_8 (abfd, buf); -} - -static unsigned int -read_2_bytes (bfd *abfd, bfd_byte *buf) -{ - return bfd_get_16 (abfd, buf); -} - -static unsigned int -read_4_bytes (bfd *abfd, bfd_byte *buf) -{ - return bfd_get_32 (abfd, buf); -} - -static bfd_uint64_t -read_8_bytes (bfd *abfd, bfd_byte *buf) -{ - return bfd_get_64 (abfd, buf); -} - -static bfd_byte * -read_n_bytes (bfd *abfd ATTRIBUTE_UNUSED, - bfd_byte *buf, - unsigned int size ATTRIBUTE_UNUSED) -{ - return buf; -} - -static char * -read_string (bfd *abfd ATTRIBUTE_UNUSED, - bfd_byte *buf, - unsigned int *bytes_read_ptr) -{ - /* Return a pointer to the embedded string. */ - char *str = (char *) buf; - - if (*str == '\0') - { - *bytes_read_ptr = 1; - return NULL; - } - - *bytes_read_ptr = strlen (str) + 1; - return str; -} - -/* END VERBATIM */ - -static char * -read_indirect_string (struct comp_unit * unit, - bfd_byte * buf, - unsigned int * bytes_read_ptr) -{ - bfd_uint64_t offset; - struct dwarf2_debug *stash = unit->stash; - char *str; - - if (unit->offset_size == 4) - offset = read_4_bytes (unit->abfd, buf); - else - offset = read_8_bytes (unit->abfd, buf); - - *bytes_read_ptr = unit->offset_size; - - if (! read_section (unit->abfd, debug_str, stash->syms, offset, - &stash->dwarf_str_buffer, &stash->dwarf_str_size)) - return NULL; - - str = (char *) stash->dwarf_str_buffer + offset; - if (*str == '\0') - return NULL; - return str; -} - -static bfd_uint64_t -read_address (struct comp_unit *unit, bfd_byte *buf) -{ - int signed_vma = get_elf_backend_data (unit->abfd)->sign_extend_vma; - - if (signed_vma) - { - switch (unit->addr_size) - { - case 8: - return bfd_get_signed_64 (unit->abfd, buf); - case 4: - return bfd_get_signed_32 (unit->abfd, buf); - case 2: - return bfd_get_signed_16 (unit->abfd, buf); - default: - abort (); - } - } - else - { - switch (unit->addr_size) - { - case 8: - return bfd_get_64 (unit->abfd, buf); - case 4: - return bfd_get_32 (unit->abfd, buf); - case 2: - return bfd_get_16 (unit->abfd, buf); - default: - abort (); - } - } -} - -/* Lookup an abbrev_info structure in the abbrev hash table. */ - -static struct abbrev_info * -lookup_abbrev (unsigned int number, struct abbrev_info **abbrevs) -{ - unsigned int hash_number; - struct abbrev_info *abbrev; - - hash_number = number % ABBREV_HASH_SIZE; - abbrev = abbrevs[hash_number]; - - while (abbrev) - { - if (abbrev->number == number) - return abbrev; - else - abbrev = abbrev->next; - } - - return NULL; -} - -/* In DWARF version 2, the description of the debugging information is - stored in a separate .debug_abbrev section. Before we read any - dies from a section we read in all abbreviations and install them - in a hash table. */ - -static struct abbrev_info** -read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash) -{ - struct abbrev_info **abbrevs; - bfd_byte *abbrev_ptr; - struct abbrev_info *cur_abbrev; - unsigned int abbrev_number, bytes_read, abbrev_name; - unsigned int abbrev_form, hash_number; - bfd_size_type amt; - - if (! read_section (abfd, debug_abbrev, stash->syms, offset, - &stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size)) - return NULL; - - amt = sizeof (struct abbrev_info*) * ABBREV_HASH_SIZE; - abbrevs = (struct abbrev_info **) bfd_zalloc (abfd, amt); - if (abbrevs == NULL) - return NULL; - - abbrev_ptr = stash->dwarf_abbrev_buffer + offset; - abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - - /* Loop until we reach an abbrev number of 0. */ - while (abbrev_number) - { - amt = sizeof (struct abbrev_info); - cur_abbrev = (struct abbrev_info *) bfd_zalloc (abfd, amt); - if (cur_abbrev == NULL) - return NULL; - - /* Read in abbrev header. */ - cur_abbrev->number = abbrev_number; - cur_abbrev->tag = (enum dwarf_tag) - read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr); - abbrev_ptr += 1; - - /* Now read in declarations. */ - abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - - while (abbrev_name) - { - if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0) - { - struct attr_abbrev *tmp; - - amt = cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK; - amt *= sizeof (struct attr_abbrev); - tmp = (struct attr_abbrev *) bfd_realloc (cur_abbrev->attrs, amt); - if (tmp == NULL) - { - size_t i; - - for (i = 0; i < ABBREV_HASH_SIZE; i++) - { - struct abbrev_info *abbrev = abbrevs[i]; - - while (abbrev) - { - free (abbrev->attrs); - abbrev = abbrev->next; - } - } - return NULL; - } - cur_abbrev->attrs = tmp; - } - - cur_abbrev->attrs[cur_abbrev->num_attrs].name - = (enum dwarf_attribute) abbrev_name; - cur_abbrev->attrs[cur_abbrev->num_attrs++].form - = (enum dwarf_form) abbrev_form; - abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - } - - hash_number = abbrev_number % ABBREV_HASH_SIZE; - cur_abbrev->next = abbrevs[hash_number]; - abbrevs[hash_number] = cur_abbrev; - - /* Get next abbreviation. - Under Irix6 the abbreviations for a compilation unit are not - always properly terminated with an abbrev number of 0. - Exit loop if we encounter an abbreviation which we have - already read (which means we are about to read the abbreviations - for the next compile unit) or if the end of the abbreviation - table is reached. */ - if ((unsigned int) (abbrev_ptr - stash->dwarf_abbrev_buffer) - >= stash->dwarf_abbrev_size) - break; - abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); - abbrev_ptr += bytes_read; - if (lookup_abbrev (abbrev_number,abbrevs) != NULL) - break; - } - - return abbrevs; -} - -/* Read an attribute value described by an attribute form. */ - -static bfd_byte * -read_attribute_value (struct attribute *attr, - unsigned form, - struct comp_unit *unit, - bfd_byte *info_ptr) -{ - bfd *abfd = unit->abfd; - unsigned int bytes_read; - struct dwarf_block *blk; - bfd_size_type amt; - - attr->form = (enum dwarf_form) form; - - switch (form) - { - case DW_FORM_ref_addr: - /* DW_FORM_ref_addr is an address in DWARF2, and an offset in - DWARF3. */ - if (unit->version == 3 || unit->version == 4) - { - if (unit->offset_size == 4) - attr->u.val = read_4_bytes (unit->abfd, info_ptr); - else - attr->u.val = read_8_bytes (unit->abfd, info_ptr); - info_ptr += unit->offset_size; - break; - } - /* FALLTHROUGH */ - case DW_FORM_addr: - attr->u.val = read_address (unit, info_ptr); - info_ptr += unit->addr_size; - break; - case DW_FORM_sec_offset: - if (unit->offset_size == 4) - attr->u.val = read_4_bytes (unit->abfd, info_ptr); - else - attr->u.val = read_8_bytes (unit->abfd, info_ptr); - info_ptr += unit->offset_size; - break; - case DW_FORM_block2: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); - if (blk == NULL) - return NULL; - blk->size = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - blk->data = read_n_bytes (abfd, info_ptr, blk->size); - info_ptr += blk->size; - attr->u.blk = blk; - break; - case DW_FORM_block4: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); - if (blk == NULL) - return NULL; - blk->size = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - blk->data = read_n_bytes (abfd, info_ptr, blk->size); - info_ptr += blk->size; - attr->u.blk = blk; - break; - case DW_FORM_data2: - attr->u.val = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - break; - case DW_FORM_data4: - attr->u.val = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - break; - case DW_FORM_data8: - attr->u.val = read_8_bytes (abfd, info_ptr); - info_ptr += 8; - break; - case DW_FORM_string: - attr->u.str = read_string (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_strp: - attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_exprloc: - case DW_FORM_block: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); - if (blk == NULL) - return NULL; - blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - blk->data = read_n_bytes (abfd, info_ptr, blk->size); - info_ptr += blk->size; - attr->u.blk = blk; - break; - case DW_FORM_block1: - amt = sizeof (struct dwarf_block); - blk = (struct dwarf_block *) bfd_alloc (abfd, amt); - if (blk == NULL) - return NULL; - blk->size = read_1_byte (abfd, info_ptr); - info_ptr += 1; - blk->data = read_n_bytes (abfd, info_ptr, blk->size); - info_ptr += blk->size; - attr->u.blk = blk; - break; - case DW_FORM_data1: - attr->u.val = read_1_byte (abfd, info_ptr); - info_ptr += 1; - break; - case DW_FORM_flag: - attr->u.val = read_1_byte (abfd, info_ptr); - info_ptr += 1; - break; - case DW_FORM_flag_present: - attr->u.val = 1; - break; - case DW_FORM_sdata: - attr->u.sval = read_signed_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_udata: - attr->u.val = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_ref1: - attr->u.val = read_1_byte (abfd, info_ptr); - info_ptr += 1; - break; - case DW_FORM_ref2: - attr->u.val = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - break; - case DW_FORM_ref4: - attr->u.val = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - break; - case DW_FORM_ref8: - attr->u.val = read_8_bytes (abfd, info_ptr); - info_ptr += 8; - break; - case DW_FORM_ref_sig8: - attr->u.val = read_8_bytes (abfd, info_ptr); - info_ptr += 8; - break; - case DW_FORM_ref_udata: - attr->u.val = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_indirect: - form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - info_ptr = read_attribute_value (attr, form, unit, info_ptr); - break; - default: - (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."), - form); - bfd_set_error (bfd_error_bad_value); - return NULL; - } - return info_ptr; -} - -/* Read an attribute described by an abbreviated attribute. */ - -static bfd_byte * -read_attribute (struct attribute *attr, - struct attr_abbrev *abbrev, - struct comp_unit *unit, - bfd_byte *info_ptr) -{ - attr->name = abbrev->name; - info_ptr = read_attribute_value (attr, abbrev->form, unit, info_ptr); - return info_ptr; -} - -/* Source line information table routines. */ - -#define FILE_ALLOC_CHUNK 5 -#define DIR_ALLOC_CHUNK 5 - -struct line_info -{ - struct line_info* prev_line; - bfd_vma address; - char *filename; - unsigned int line; - unsigned int column; - unsigned char op_index; - unsigned char end_sequence; /* End of (sequential) code sequence. */ -}; - -struct fileinfo -{ - char *name; - unsigned int dir; - unsigned int time; - unsigned int size; -}; - -struct line_sequence -{ - bfd_vma low_pc; - struct line_sequence* prev_sequence; - struct line_info* last_line; /* Largest VMA. */ -}; - -struct line_info_table -{ - bfd* abfd; - unsigned int num_files; - unsigned int num_dirs; - unsigned int num_sequences; - char * comp_dir; - char ** dirs; - struct fileinfo* files; - struct line_sequence* sequences; - struct line_info* lcl_head; /* Local head; used in 'add_line_info'. */ -}; - -/* Remember some information about each function. If the function is - inlined (DW_TAG_inlined_subroutine) it may have two additional - attributes, DW_AT_call_file and DW_AT_call_line, which specify the - source code location where this function was inlined. */ - -struct funcinfo -{ - struct funcinfo *prev_func; /* Pointer to previous function in list of all functions */ - struct funcinfo *caller_func; /* Pointer to function one scope higher */ - char *caller_file; /* Source location file name where caller_func inlines this func */ - int caller_line; /* Source location line number where caller_func inlines this func */ - char *file; /* Source location file name */ - int line; /* Source location line number */ - int tag; - char *name; - struct arange arange; - asection *sec; /* Where the symbol is defined */ -}; - -struct varinfo -{ - /* Pointer to previous variable in list of all variables */ - struct varinfo *prev_var; - /* Source location file name */ - char *file; - /* Source location line number */ - int line; - int tag; - char *name; - bfd_vma addr; - /* Where the symbol is defined */ - asection *sec; - /* Is this a stack variable? */ - unsigned int stack: 1; -}; - -/* Return TRUE if NEW_LINE should sort after LINE. */ - -static inline bfd_boolean -new_line_sorts_after (struct line_info *new_line, struct line_info *line) -{ - return (new_line->address > line->address - || (new_line->address == line->address - && (new_line->op_index > line->op_index - || (new_line->op_index == line->op_index - && new_line->end_sequence < line->end_sequence)))); -} - - -/* Adds a new entry to the line_info list in the line_info_table, ensuring - that the list is sorted. Note that the line_info list is sorted from - highest to lowest VMA (with possible duplicates); that is, - line_info->prev_line always accesses an equal or smaller VMA. */ - -static bfd_boolean -add_line_info (struct line_info_table *table, - bfd_vma address, - unsigned char op_index, - char *filename, - unsigned int line, - unsigned int column, - int end_sequence) -{ - bfd_size_type amt = sizeof (struct line_info); - struct line_sequence* seq = table->sequences; - struct line_info* info = (struct line_info *) bfd_alloc (table->abfd, amt); - - if (info == NULL) - return FALSE; - - /* Set member data of 'info'. */ - info->prev_line = NULL; - info->address = address; - info->op_index = op_index; - info->line = line; - info->column = column; - info->end_sequence = end_sequence; - - if (filename && filename[0]) - { - info->filename = (char *) bfd_alloc (table->abfd, strlen (filename) + 1); - if (info->filename == NULL) - return FALSE; - strcpy (info->filename, filename); - } - else - info->filename = NULL; - - /* Find the correct location for 'info'. Normally we will receive - new line_info data 1) in order and 2) with increasing VMAs. - However some compilers break the rules (cf. decode_line_info) and - so we include some heuristics for quickly finding the correct - location for 'info'. In particular, these heuristics optimize for - the common case in which the VMA sequence that we receive is a - list of locally sorted VMAs such as - p...z a...j (where a < j < p < z) - - Note: table->lcl_head is used to head an *actual* or *possible* - sub-sequence within the list (such as a...j) that is not directly - headed by table->last_line - - Note: we may receive duplicate entries from 'decode_line_info'. */ - - if (seq - && seq->last_line->address == address - && seq->last_line->op_index == op_index - && seq->last_line->end_sequence == end_sequence) - { - /* We only keep the last entry with the same address and end - sequence. See PR ld/4986. */ - if (table->lcl_head == seq->last_line) - table->lcl_head = info; - info->prev_line = seq->last_line->prev_line; - seq->last_line = info; - } - else if (!seq || seq->last_line->end_sequence) - { - /* Start a new line sequence. */ - amt = sizeof (struct line_sequence); - seq = (struct line_sequence *) bfd_malloc (amt); - if (seq == NULL) - return FALSE; - seq->low_pc = address; - seq->prev_sequence = table->sequences; - seq->last_line = info; - table->lcl_head = info; - table->sequences = seq; - table->num_sequences++; - } - else if (new_line_sorts_after (info, seq->last_line)) - { - /* Normal case: add 'info' to the beginning of the current sequence. */ - info->prev_line = seq->last_line; - seq->last_line = info; - - /* lcl_head: initialize to head a *possible* sequence at the end. */ - if (!table->lcl_head) - table->lcl_head = info; - } - else if (!new_line_sorts_after (info, table->lcl_head) - && (!table->lcl_head->prev_line - || new_line_sorts_after (info, table->lcl_head->prev_line))) - { - /* Abnormal but easy: lcl_head is the head of 'info'. */ - info->prev_line = table->lcl_head->prev_line; - table->lcl_head->prev_line = info; - } - else - { - /* Abnormal and hard: Neither 'last_line' nor 'lcl_head' - are valid heads for 'info'. Reset 'lcl_head'. */ - struct line_info* li2 = seq->last_line; /* Always non-NULL. */ - struct line_info* li1 = li2->prev_line; - - while (li1) - { - if (!new_line_sorts_after (info, li2) - && new_line_sorts_after (info, li1)) - break; - - li2 = li1; /* always non-NULL */ - li1 = li1->prev_line; - } - table->lcl_head = li2; - info->prev_line = table->lcl_head->prev_line; - table->lcl_head->prev_line = info; - if (address < seq->low_pc) - seq->low_pc = address; - } - return TRUE; -} - -/* Extract a fully qualified filename from a line info table. - The returned string has been malloc'ed and it is the caller's - responsibility to free it. */ - -static char * -concat_filename (struct line_info_table *table, unsigned int file) -{ - char *filename; - - if (file - 1 >= table->num_files) - { - /* FILE == 0 means unknown. */ - if (file) - (*_bfd_error_handler) - (_("Dwarf Error: mangled line number section (bad file number).")); - return strdup (""); - } - - filename = table->files[file - 1].name; - - if (!IS_ABSOLUTE_PATH (filename)) - { - char *dir_name = NULL; - char *subdir_name = NULL; - char *name; - size_t len; - - if (table->files[file - 1].dir) - subdir_name = table->dirs[table->files[file - 1].dir - 1]; - - if (!subdir_name || !IS_ABSOLUTE_PATH (subdir_name)) - dir_name = table->comp_dir; - - if (!dir_name) - { - dir_name = subdir_name; - subdir_name = NULL; - } - - if (!dir_name) - return strdup (filename); - - len = strlen (dir_name) + strlen (filename) + 2; - - if (subdir_name) - { - len += strlen (subdir_name) + 1; - name = (char *) bfd_malloc (len); - if (name) - sprintf (name, "%s/%s/%s", dir_name, subdir_name, filename); - } - else - { - name = (char *) bfd_malloc (len); - if (name) - sprintf (name, "%s/%s", dir_name, filename); - } - - return name; - } - - return strdup (filename); -} - -static bfd_boolean -arange_add (bfd *abfd, struct arange *first_arange, - bfd_vma low_pc, bfd_vma high_pc) -{ - struct arange *arange; - - /* If the first arange is empty, use it. */ - if (first_arange->high == 0) - { - first_arange->low = low_pc; - first_arange->high = high_pc; - return TRUE; - } - - /* Next see if we can cheaply extend an existing range. */ - arange = first_arange; - do - { - if (low_pc == arange->high) - { - arange->high = high_pc; - return TRUE; - } - if (high_pc == arange->low) - { - arange->low = low_pc; - return TRUE; - } - arange = arange->next; - } - while (arange); - - /* Need to allocate a new arange and insert it into the arange list. - Order isn't significant, so just insert after the first arange. */ - arange = (struct arange *) bfd_zalloc (abfd, sizeof (*arange)); - if (arange == NULL) - return FALSE; - arange->low = low_pc; - arange->high = high_pc; - arange->next = first_arange->next; - first_arange->next = arange; - return TRUE; -} - -/* Compare function for line sequences. */ - -static int -compare_sequences (const void* a, const void* b) -{ - const struct line_sequence* seq1 = a; - const struct line_sequence* seq2 = b; - - /* Sort by low_pc as the primary key. */ - if (seq1->low_pc < seq2->low_pc) - return -1; - if (seq1->low_pc > seq2->low_pc) - return 1; - - /* If low_pc values are equal, sort in reverse order of - high_pc, so that the largest region comes first. */ - if (seq1->last_line->address < seq2->last_line->address) - return 1; - if (seq1->last_line->address > seq2->last_line->address) - return -1; - - if (seq1->last_line->op_index < seq2->last_line->op_index) - return 1; - if (seq1->last_line->op_index > seq2->last_line->op_index) - return -1; - - return 0; -} - -/* Sort the line sequences for quick lookup. */ - -static bfd_boolean -sort_line_sequences (struct line_info_table* table) -{ - bfd_size_type amt; - struct line_sequence* sequences; - struct line_sequence* seq; - unsigned int n = 0; - unsigned int num_sequences = table->num_sequences; - bfd_vma last_high_pc; - - if (num_sequences == 0) - return TRUE; - - /* Allocate space for an array of sequences. */ - amt = sizeof (struct line_sequence) * num_sequences; - sequences = (struct line_sequence *) bfd_alloc (table->abfd, amt); - if (sequences == NULL) - return FALSE; - - /* Copy the linked list into the array, freeing the original nodes. */ - seq = table->sequences; - for (n = 0; n < num_sequences; n++) - { - struct line_sequence* last_seq = seq; - - BFD_ASSERT (seq); - sequences[n].low_pc = seq->low_pc; - sequences[n].prev_sequence = NULL; - sequences[n].last_line = seq->last_line; - seq = seq->prev_sequence; - free (last_seq); - } - BFD_ASSERT (seq == NULL); - - qsort (sequences, n, sizeof (struct line_sequence), compare_sequences); - - /* Make the list binary-searchable by trimming overlapping entries - and removing nested entries. */ - num_sequences = 1; - last_high_pc = sequences[0].last_line->address; - for (n = 1; n < table->num_sequences; n++) - { - if (sequences[n].low_pc < last_high_pc) - { - if (sequences[n].last_line->address <= last_high_pc) - /* Skip nested entries. */ - continue; - - /* Trim overlapping entries. */ - sequences[n].low_pc = last_high_pc; - } - last_high_pc = sequences[n].last_line->address; - if (n > num_sequences) - { - /* Close up the gap. */ - sequences[num_sequences].low_pc = sequences[n].low_pc; - sequences[num_sequences].last_line = sequences[n].last_line; - } - num_sequences++; - } - - table->sequences = sequences; - table->num_sequences = num_sequences; - return TRUE; -} - -/* Decode the line number information for UNIT. */ - -static struct line_info_table* -decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) -{ - bfd *abfd = unit->abfd; - struct line_info_table* table; - bfd_byte *line_ptr; - bfd_byte *line_end; - struct line_head lh; - unsigned int i, bytes_read, offset_size; - char *cur_file, *cur_dir; - unsigned char op_code, extended_op, adj_opcode; - bfd_size_type amt; - - if (! read_section (abfd, debug_line, stash->syms, unit->line_offset, - &stash->dwarf_line_buffer, &stash->dwarf_line_size)) - return NULL; - - amt = sizeof (struct line_info_table); - table = (struct line_info_table *) bfd_alloc (abfd, amt); - if (table == NULL) - return NULL; - table->abfd = abfd; - table->comp_dir = unit->comp_dir; - - table->num_files = 0; - table->files = NULL; - - table->num_dirs = 0; - table->dirs = NULL; - - table->num_sequences = 0; - table->sequences = NULL; - - table->lcl_head = NULL; - - line_ptr = stash->dwarf_line_buffer + unit->line_offset; - - /* Read in the prologue. */ - lh.total_length = read_4_bytes (abfd, line_ptr); - line_ptr += 4; - offset_size = 4; - if (lh.total_length == 0xffffffff) - { - lh.total_length = read_8_bytes (abfd, line_ptr); - line_ptr += 8; - offset_size = 8; - } - else if (lh.total_length == 0 && unit->addr_size == 8) - { - /* Handle (non-standard) 64-bit DWARF2 formats. */ - lh.total_length = read_4_bytes (abfd, line_ptr); - line_ptr += 4; - offset_size = 8; - } - line_end = line_ptr + lh.total_length; - lh.version = read_2_bytes (abfd, line_ptr); - if (lh.version < 2 || lh.version > 4) - { - (*_bfd_error_handler) - (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version); - bfd_set_error (bfd_error_bad_value); - return NULL; - } - line_ptr += 2; - if (offset_size == 4) - lh.prologue_length = read_4_bytes (abfd, line_ptr); - else - lh.prologue_length = read_8_bytes (abfd, line_ptr); - line_ptr += offset_size; - lh.minimum_instruction_length = read_1_byte (abfd, line_ptr); - line_ptr += 1; - if (lh.version >= 4) - { - lh.maximum_ops_per_insn = read_1_byte (abfd, line_ptr); - line_ptr += 1; - } - else - lh.maximum_ops_per_insn = 1; - if (lh.maximum_ops_per_insn == 0) - { - (*_bfd_error_handler) - (_("Dwarf Error: Invalid maximum operations per instruction.")); - bfd_set_error (bfd_error_bad_value); - return NULL; - } - lh.default_is_stmt = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.line_base = read_1_signed_byte (abfd, line_ptr); - line_ptr += 1; - lh.line_range = read_1_byte (abfd, line_ptr); - line_ptr += 1; - lh.opcode_base = read_1_byte (abfd, line_ptr); - line_ptr += 1; - amt = lh.opcode_base * sizeof (unsigned char); - lh.standard_opcode_lengths = (unsigned char *) bfd_alloc (abfd, amt); - - lh.standard_opcode_lengths[0] = 1; - - for (i = 1; i < lh.opcode_base; ++i) - { - lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr); - line_ptr += 1; - } - - /* Read directory table. */ - while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL) - { - line_ptr += bytes_read; - - if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0) - { - char **tmp; - - amt = table->num_dirs + DIR_ALLOC_CHUNK; - amt *= sizeof (char *); - - tmp = (char **) bfd_realloc (table->dirs, amt); - if (tmp == NULL) - goto fail; - table->dirs = tmp; - } - - table->dirs[table->num_dirs++] = cur_dir; - } - - line_ptr += bytes_read; - - /* Read file name table. */ - while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL) - { - line_ptr += bytes_read; - - if ((table->num_files % FILE_ALLOC_CHUNK) == 0) - { - struct fileinfo *tmp; - - amt = table->num_files + FILE_ALLOC_CHUNK; - amt *= sizeof (struct fileinfo); - - tmp = (struct fileinfo *) bfd_realloc (table->files, amt); - if (tmp == NULL) - goto fail; - table->files = tmp; - } - - table->files[table->num_files].name = cur_file; - table->files[table->num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->files[table->num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->files[table->num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->num_files++; - } - - line_ptr += bytes_read; - - /* Read the statement sequences until there's nothing left. */ - while (line_ptr < line_end) - { - /* State machine registers. */ - bfd_vma address = 0; - unsigned char op_index = 0; - char * filename = table->num_files ? concat_filename (table, 1) : NULL; - unsigned int line = 1; - unsigned int column = 0; - int is_stmt = lh.default_is_stmt; - int end_sequence = 0; - /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some - compilers generate address sequences that are wildly out of - order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler - for ia64-Linux). Thus, to determine the low and high - address, we must compare on every DW_LNS_copy, etc. */ - bfd_vma low_pc = (bfd_vma) -1; - bfd_vma high_pc = 0; - - /* Decode the table. */ - while (! end_sequence) - { - op_code = read_1_byte (abfd, line_ptr); - line_ptr += 1; - - if (op_code >= lh.opcode_base) - { - /* Special operand. */ - adj_opcode = op_code - lh.opcode_base; - if (lh.maximum_ops_per_insn == 1) - address += (adj_opcode / lh.line_range) - * lh.minimum_instruction_length; - else - { - address += ((op_index + (adj_opcode / lh.line_range)) - / lh.maximum_ops_per_insn) - * lh.minimum_instruction_length; - op_index = (op_index + (adj_opcode / lh.line_range)) - % lh.maximum_ops_per_insn; - } - line += lh.line_base + (adj_opcode % lh.line_range); - /* Append row to matrix using current values. */ - if (!add_line_info (table, address, op_index, filename, - line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; - if (address > high_pc) - high_pc = address; - } - else switch (op_code) - { - case DW_LNS_extended_op: - /* Ignore length. */ - line_ptr += 1; - extended_op = read_1_byte (abfd, line_ptr); - line_ptr += 1; - - switch (extended_op) - { - case DW_LNE_end_sequence: - end_sequence = 1; - if (!add_line_info (table, address, op_index, filename, - line, column, end_sequence)) - goto line_fail; - if (address < low_pc) - low_pc = address; - if (address > high_pc) - high_pc = address; - if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc)) - goto line_fail; - break; - case DW_LNE_set_address: - address = read_address (unit, line_ptr); - op_index = 0; - line_ptr += unit->addr_size; - break; - case DW_LNE_define_file: - cur_file = read_string (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - if ((table->num_files % FILE_ALLOC_CHUNK) == 0) - { - struct fileinfo *tmp; - - amt = table->num_files + FILE_ALLOC_CHUNK; - amt *= sizeof (struct fileinfo); - tmp = (struct fileinfo *) bfd_realloc (table->files, amt); - if (tmp == NULL) - goto line_fail; - table->files = tmp; - } - table->files[table->num_files].name = cur_file; - table->files[table->num_files].dir = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->files[table->num_files].time = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->files[table->num_files].size = - read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - table->num_files++; - break; - case DW_LNE_set_discriminator: - (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - break; - default: - (*_bfd_error_handler) (_("Dwarf Error: mangled line number section.")); - bfd_set_error (bfd_error_bad_value); - line_fail: - if (filename != NULL) - free (filename); - goto fail; - } - break; - case DW_LNS_copy: - if (!add_line_info (table, address, op_index, - filename, line, column, 0)) - goto line_fail; - if (address < low_pc) - low_pc = address; - if (address > high_pc) - high_pc = address; - break; - case DW_LNS_advance_pc: - if (lh.maximum_ops_per_insn == 1) - address += lh.minimum_instruction_length - * read_unsigned_leb128 (abfd, line_ptr, - &bytes_read); - else - { - bfd_vma adjust = read_unsigned_leb128 (abfd, line_ptr, - &bytes_read); - address = ((op_index + adjust) / lh.maximum_ops_per_insn) - * lh.minimum_instruction_length; - op_index = (op_index + adjust) % lh.maximum_ops_per_insn; - } - line_ptr += bytes_read; - break; - case DW_LNS_advance_line: - line += read_signed_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - break; - case DW_LNS_set_file: - { - unsigned int file; - - /* The file and directory tables are 0 - based, the references are 1 based. */ - file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - if (filename) - free (filename); - filename = concat_filename (table, file); - break; - } - case DW_LNS_set_column: - column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - break; - case DW_LNS_negate_stmt: - is_stmt = (!is_stmt); - break; - case DW_LNS_set_basic_block: - break; - case DW_LNS_const_add_pc: - if (lh.maximum_ops_per_insn == 1) - address += lh.minimum_instruction_length - * ((255 - lh.opcode_base) / lh.line_range); - else - { - bfd_vma adjust = ((255 - lh.opcode_base) / lh.line_range); - address += lh.minimum_instruction_length - * ((op_index + adjust) / lh.maximum_ops_per_insn); - op_index = (op_index + adjust) % lh.maximum_ops_per_insn; - } - break; - case DW_LNS_fixed_advance_pc: - address += read_2_bytes (abfd, line_ptr); - op_index = 0; - line_ptr += 2; - break; - default: - /* Unknown standard opcode, ignore it. */ - for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) - { - (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; - } - break; - } - } - - if (filename) - free (filename); - } - - if (sort_line_sequences (table)) - return table; - - fail: - if (table->sequences != NULL) - free (table->sequences); - if (table->files != NULL) - free (table->files); - if (table->dirs != NULL) - free (table->dirs); - return NULL; -} - -/* If ADDR is within TABLE set the output parameters and return TRUE, - otherwise return FALSE. The output parameters, FILENAME_PTR and - LINENUMBER_PTR, are pointers to the objects to be filled in. */ - -static bfd_boolean -lookup_address_in_line_info_table (struct line_info_table *table, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - struct line_sequence *seq = NULL; - struct line_info *each_line; - int low, high, mid; - - /* Binary search the array of sequences. */ - low = 0; - high = table->num_sequences; - while (low < high) - { - mid = (low + high) / 2; - seq = &table->sequences[mid]; - if (addr < seq->low_pc) - high = mid; - else if (addr >= seq->last_line->address) - low = mid + 1; - else - break; - } - - if (seq && addr >= seq->low_pc && addr < seq->last_line->address) - { - /* Note: seq->last_line should be a descendingly sorted list. */ - for (each_line = seq->last_line; - each_line; - each_line = each_line->prev_line) - if (addr >= each_line->address) - break; - - if (each_line - && !(each_line->end_sequence || each_line == seq->last_line)) - { - *filename_ptr = each_line->filename; - *linenumber_ptr = each_line->line; - return TRUE; - } - } - - *filename_ptr = NULL; - return FALSE; -} - -/* Read in the .debug_ranges section for future reference. */ - -static bfd_boolean -read_debug_ranges (struct comp_unit *unit) -{ - struct dwarf2_debug *stash = unit->stash; - return read_section (unit->abfd, debug_ranges, stash->syms, 0, - &stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size); -} - -/* Function table functions. */ - -/* If ADDR is within TABLE, set FUNCTIONNAME_PTR, and return TRUE. - Note that we need to find the function that has the smallest - range that contains ADDR, to handle inlined functions without - depending upon them being ordered in TABLE by increasing range. */ - -static bfd_boolean -lookup_address_in_function_table (struct comp_unit *unit, - bfd_vma addr, - struct funcinfo **function_ptr, - const char **functionname_ptr) -{ - struct funcinfo* each_func; - struct funcinfo* best_fit = NULL; - struct arange *arange; - - for (each_func = unit->function_table; - each_func; - each_func = each_func->prev_func) - { - for (arange = &each_func->arange; - arange; - arange = arange->next) - { - if (addr >= arange->low && addr < arange->high) - { - if (!best_fit || - ((arange->high - arange->low) < (best_fit->arange.high - best_fit->arange.low))) - best_fit = each_func; - } - } - } - - if (best_fit) - { - *functionname_ptr = best_fit->name; - *function_ptr = best_fit; - return TRUE; - } - else - { - return FALSE; - } -} - -/* If SYM at ADDR is within function table of UNIT, set FILENAME_PTR - and LINENUMBER_PTR, and return TRUE. */ - -static bfd_boolean -lookup_symbol_in_function_table (struct comp_unit *unit, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - struct funcinfo* each_func; - struct funcinfo* best_fit = NULL; - struct arange *arange; - const char *name = bfd_asymbol_name (sym); - asection *sec = bfd_get_section (sym); - - for (each_func = unit->function_table; - each_func; - each_func = each_func->prev_func) - { - for (arange = &each_func->arange; - arange; - arange = arange->next) - { - if ((!each_func->sec || each_func->sec == sec) - && addr >= arange->low - && addr < arange->high - && each_func->name - && strcmp (name, each_func->name) == 0 - && (!best_fit - || ((arange->high - arange->low) - < (best_fit->arange.high - best_fit->arange.low)))) - best_fit = each_func; - } - } - - if (best_fit) - { - best_fit->sec = sec; - *filename_ptr = best_fit->file; - *linenumber_ptr = best_fit->line; - return TRUE; - } - else - return FALSE; -} - -/* Variable table functions. */ - -/* If SYM is within variable table of UNIT, set FILENAME_PTR and - LINENUMBER_PTR, and return TRUE. */ - -static bfd_boolean -lookup_symbol_in_variable_table (struct comp_unit *unit, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - const char *name = bfd_asymbol_name (sym); - asection *sec = bfd_get_section (sym); - struct varinfo* each; - - for (each = unit->variable_table; each; each = each->prev_var) - if (each->stack == 0 - && each->file != NULL - && each->name != NULL - && each->addr == addr - && (!each->sec || each->sec == sec) - && strcmp (name, each->name) == 0) - break; - - if (each) - { - each->sec = sec; - *filename_ptr = each->file; - *linenumber_ptr = each->line; - return TRUE; - } - else - return FALSE; -} - -static char * -find_abstract_instance_name (struct comp_unit *unit, - struct attribute *attr_ptr) -{ - bfd *abfd = unit->abfd; - bfd_byte *info_ptr; - unsigned int abbrev_number, bytes_read, i; - struct abbrev_info *abbrev; - bfd_uint64_t die_ref = attr_ptr->u.val; - struct attribute attr; - char *name = 0; - - /* DW_FORM_ref_addr can reference an entry in a different CU. It - is an offset from the .debug_info section, not the current CU. */ - if (attr_ptr->form == DW_FORM_ref_addr) - { - /* We only support DW_FORM_ref_addr within the same file, so - any relocations should be resolved already. */ - if (!die_ref) - abort (); - - info_ptr = unit->sec_info_ptr + die_ref; - } - else - info_ptr = unit->info_ptr_unit + die_ref; - abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - - if (abbrev_number) - { - abbrev = lookup_abbrev (abbrev_number, unit->abbrevs); - if (! abbrev) - { - (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), - abbrev_number); - bfd_set_error (bfd_error_bad_value); - } - else - { - for (i = 0; i < abbrev->num_attrs; ++i) - { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, - info_ptr); - if (info_ptr == NULL) - break; - switch (attr.name) - { - case DW_AT_name: - /* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name - over DW_AT_name. */ - if (name == NULL) - name = attr.u.str; - break; - case DW_AT_specification: - name = find_abstract_instance_name (unit, &attr); - break; - case DW_AT_linkage_name: - case DW_AT_MIPS_linkage_name: - name = attr.u.str; - break; - default: - break; - } - } - } - } - return name; -} - -static bfd_boolean -read_rangelist (struct comp_unit *unit, struct arange *arange, - bfd_uint64_t offset) -{ - bfd_byte *ranges_ptr; - bfd_vma base_address = unit->base_address; - - if (! unit->stash->dwarf_ranges_buffer) - { - if (! read_debug_ranges (unit)) - return FALSE; - } - ranges_ptr = unit->stash->dwarf_ranges_buffer + offset; - - for (;;) - { - bfd_vma low_pc; - bfd_vma high_pc; - - low_pc = read_address (unit, ranges_ptr); - ranges_ptr += unit->addr_size; - high_pc = read_address (unit, ranges_ptr); - ranges_ptr += unit->addr_size; - - if (low_pc == 0 && high_pc == 0) - break; - if (low_pc == -1UL && high_pc != -1UL) - base_address = high_pc; - else - { - if (!arange_add (unit->abfd, arange, - base_address + low_pc, base_address + high_pc)) - return FALSE; - } - } - return TRUE; -} - -/* DWARF2 Compilation unit functions. */ - -/* Scan over each die in a comp. unit looking for functions to add - to the function table and variables to the variable table. */ - -static bfd_boolean -scan_unit_for_symbols (struct comp_unit *unit) -{ - bfd *abfd = unit->abfd; - bfd_byte *info_ptr = unit->first_child_die_ptr; - int nesting_level = 1; - struct funcinfo **nested_funcs; - int nested_funcs_size; - - /* Maintain a stack of in-scope functions and inlined functions, which we - can use to set the caller_func field. */ - nested_funcs_size = 32; - nested_funcs = (struct funcinfo **) - bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *)); - if (nested_funcs == NULL) - return FALSE; - nested_funcs[nesting_level] = 0; - - while (nesting_level) - { - unsigned int abbrev_number, bytes_read, i; - struct abbrev_info *abbrev; - struct attribute attr; - struct funcinfo *func; - struct varinfo *var; - bfd_vma low_pc = 0; - bfd_vma high_pc = 0; - - abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - - if (! abbrev_number) - { - nesting_level--; - continue; - } - - abbrev = lookup_abbrev (abbrev_number,unit->abbrevs); - if (! abbrev) - { - (*_bfd_error_handler) - (_("Dwarf Error: Could not find abbrev number %u."), - abbrev_number); - bfd_set_error (bfd_error_bad_value); - goto fail; - } - - var = NULL; - if (abbrev->tag == DW_TAG_subprogram - || abbrev->tag == DW_TAG_entry_point - || abbrev->tag == DW_TAG_inlined_subroutine) - { - bfd_size_type amt = sizeof (struct funcinfo); - func = (struct funcinfo *) bfd_zalloc (abfd, amt); - if (func == NULL) - goto fail; - func->tag = abbrev->tag; - func->prev_func = unit->function_table; - unit->function_table = func; - BFD_ASSERT (!unit->cached); - - if (func->tag == DW_TAG_inlined_subroutine) - for (i = nesting_level - 1; i >= 1; i--) - if (nested_funcs[i]) - { - func->caller_func = nested_funcs[i]; - break; - } - nested_funcs[nesting_level] = func; - } - else - { - func = NULL; - if (abbrev->tag == DW_TAG_variable) - { - bfd_size_type amt = sizeof (struct varinfo); - var = (struct varinfo *) bfd_zalloc (abfd, amt); - if (var == NULL) - goto fail; - var->tag = abbrev->tag; - var->stack = 1; - var->prev_var = unit->variable_table; - unit->variable_table = var; - BFD_ASSERT (!unit->cached); - } - - /* No inline function in scope at this nesting level. */ - nested_funcs[nesting_level] = 0; - } - - for (i = 0; i < abbrev->num_attrs; ++i) - { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr); - if (info_ptr == NULL) - goto fail; - - if (func) - { - switch (attr.name) - { - case DW_AT_call_file: - func->caller_file = concat_filename (unit->line_table, - attr.u.val); - break; - - case DW_AT_call_line: - func->caller_line = attr.u.val; - break; - - case DW_AT_abstract_origin: - case DW_AT_specification: - func->name = find_abstract_instance_name (unit, &attr); - break; - - case DW_AT_name: - /* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name - over DW_AT_name. */ - if (func->name == NULL) - func->name = attr.u.str; - break; - - case DW_AT_linkage_name: - case DW_AT_MIPS_linkage_name: - func->name = attr.u.str; - break; - - case DW_AT_low_pc: - low_pc = attr.u.val; - break; - - case DW_AT_high_pc: - high_pc = attr.u.val; - break; - - case DW_AT_ranges: - if (!read_rangelist (unit, &func->arange, attr.u.val)) - goto fail; - break; - - case DW_AT_decl_file: - func->file = concat_filename (unit->line_table, - attr.u.val); - break; - - case DW_AT_decl_line: - func->line = attr.u.val; - break; - - default: - break; - } - } - else if (var) - { - switch (attr.name) - { - case DW_AT_name: - var->name = attr.u.str; - break; - - case DW_AT_decl_file: - var->file = concat_filename (unit->line_table, - attr.u.val); - break; - - case DW_AT_decl_line: - var->line = attr.u.val; - break; - - case DW_AT_external: - if (attr.u.val != 0) - var->stack = 0; - break; - - case DW_AT_location: - switch (attr.form) - { - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - case DW_FORM_exprloc: - if (*attr.u.blk->data == DW_OP_addr) - { - var->stack = 0; - - /* Verify that DW_OP_addr is the only opcode in the - location, in which case the block size will be 1 - plus the address size. */ - /* ??? For TLS variables, gcc can emit - DW_OP_addr DW_OP_GNU_push_tls_address - which we don't handle here yet. */ - if (attr.u.blk->size == unit->addr_size + 1U) - var->addr = bfd_get (unit->addr_size * 8, - unit->abfd, - attr.u.blk->data + 1); - } - break; - - default: - break; - } - break; - - default: - break; - } - } - } - - if (func && high_pc != 0) - { - if (!arange_add (unit->abfd, &func->arange, low_pc, high_pc)) - goto fail; - } - - if (abbrev->has_children) - { - nesting_level++; - - if (nesting_level >= nested_funcs_size) - { - struct funcinfo **tmp; - - nested_funcs_size *= 2; - tmp = (struct funcinfo **) - bfd_realloc (nested_funcs, - (nested_funcs_size * sizeof (struct funcinfo *))); - if (tmp == NULL) - goto fail; - nested_funcs = tmp; - } - nested_funcs[nesting_level] = 0; - } - } - - free (nested_funcs); - return TRUE; - - fail: - free (nested_funcs); - return FALSE; -} - -/* Parse a DWARF2 compilation unit starting at INFO_PTR. This - includes the compilation unit header that proceeds the DIE's, but - does not include the length field that precedes each compilation - unit header. END_PTR points one past the end of this comp unit. - OFFSET_SIZE is the size of DWARF2 offsets (either 4 or 8 bytes). - - This routine does not read the whole compilation unit; only enough - to get to the line number information for the compilation unit. */ - -static struct comp_unit * -parse_comp_unit (struct dwarf2_debug *stash, - bfd_vma unit_length, - bfd_byte *info_ptr_unit, - unsigned int offset_size) -{ - struct comp_unit* unit; - unsigned int version; - bfd_uint64_t abbrev_offset = 0; - unsigned int addr_size; - struct abbrev_info** abbrevs; - unsigned int abbrev_number, bytes_read, i; - struct abbrev_info *abbrev; - struct attribute attr; - bfd_byte *info_ptr = stash->info_ptr; - bfd_byte *end_ptr = info_ptr + unit_length; - bfd_size_type amt; - bfd_vma low_pc = 0; - bfd_vma high_pc = 0; - bfd *abfd = stash->bfd_ptr; - - version = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - BFD_ASSERT (offset_size == 4 || offset_size == 8); - if (offset_size == 4) - abbrev_offset = read_4_bytes (abfd, info_ptr); - else - abbrev_offset = read_8_bytes (abfd, info_ptr); - info_ptr += offset_size; - addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; - - if (version != 2 && version != 3 && version != 4) - { - (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."), version); - bfd_set_error (bfd_error_bad_value); - return 0; - } - - if (addr_size > sizeof (bfd_vma)) - { - (*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."), - addr_size, - (unsigned int) sizeof (bfd_vma)); - bfd_set_error (bfd_error_bad_value); - return 0; - } - - if (addr_size != 2 && addr_size != 4 && addr_size != 8) - { - (*_bfd_error_handler) ("Dwarf Error: found address size '%u', this reader can only handle address sizes '2', '4' and '8'.", addr_size); - bfd_set_error (bfd_error_bad_value); - return 0; - } - - /* Read the abbrevs for this compilation unit into a table. */ - abbrevs = read_abbrevs (abfd, abbrev_offset, stash); - if (! abbrevs) - return 0; - - abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - if (! abbrev_number) - { - (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."), - abbrev_number); - bfd_set_error (bfd_error_bad_value); - return 0; - } - - abbrev = lookup_abbrev (abbrev_number, abbrevs); - if (! abbrev) - { - (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), - abbrev_number); - bfd_set_error (bfd_error_bad_value); - return 0; - } - - amt = sizeof (struct comp_unit); - unit = (struct comp_unit *) bfd_zalloc (abfd, amt); - if (unit == NULL) - return NULL; - unit->abfd = abfd; - unit->version = version; - unit->addr_size = addr_size; - unit->offset_size = offset_size; - unit->abbrevs = abbrevs; - unit->end_ptr = end_ptr; - unit->stash = stash; - unit->info_ptr_unit = info_ptr_unit; - unit->sec_info_ptr = stash->sec_info_ptr; - - for (i = 0; i < abbrev->num_attrs; ++i) - { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr); - if (info_ptr == NULL) - return NULL; - - /* Store the data if it is of an attribute we want to keep in a - partial symbol table. */ - switch (attr.name) - { - case DW_AT_stmt_list: - unit->stmtlist = 1; - unit->line_offset = attr.u.val; - break; - - case DW_AT_name: - unit->name = attr.u.str; - break; - - case DW_AT_low_pc: - low_pc = attr.u.val; - /* If the compilation unit DIE has a DW_AT_low_pc attribute, - this is the base address to use when reading location - lists or range lists. */ - unit->base_address = low_pc; - break; - - case DW_AT_high_pc: - high_pc = attr.u.val; - break; - - case DW_AT_ranges: - if (!read_rangelist (unit, &unit->arange, attr.u.val)) - return NULL; - break; - - case DW_AT_comp_dir: - { - char *comp_dir = attr.u.str; - if (comp_dir) - { - /* Irix 6.2 native cc prepends .: to the compilation - directory, get rid of it. */ - char *cp = strchr (comp_dir, ':'); - - if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/') - comp_dir = cp + 1; - } - unit->comp_dir = comp_dir; - break; - } - - default: - break; - } - } - if (high_pc != 0) - { - if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc)) - return NULL; - } - - unit->first_child_die_ptr = info_ptr; - return unit; -} - -/* Return TRUE if UNIT may contain the address given by ADDR. When - there are functions written entirely with inline asm statements, the - range info in the compilation unit header may not be correct. We - need to consult the line info table to see if a compilation unit - really contains the given address. */ - -static bfd_boolean -comp_unit_contains_address (struct comp_unit *unit, bfd_vma addr) -{ - struct arange *arange; - - if (unit->error) - return FALSE; - - arange = &unit->arange; - do - { - if (addr >= arange->low && addr < arange->high) - return TRUE; - arange = arange->next; - } - while (arange); - - return FALSE; -} - -/* If UNIT contains ADDR, set the output parameters to the values for - the line containing ADDR. The output parameters, FILENAME_PTR, - FUNCTIONNAME_PTR, and LINENUMBER_PTR, are pointers to the objects - to be filled in. - - Return TRUE if UNIT contains ADDR, and no errors were encountered; - FALSE otherwise. */ - -static bfd_boolean -comp_unit_find_nearest_line (struct comp_unit *unit, - bfd_vma addr, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr, - struct dwarf2_debug *stash) -{ - bfd_boolean line_p; - bfd_boolean func_p; - struct funcinfo *function; - - if (unit->error) - return FALSE; - - if (! unit->line_table) - { - if (! unit->stmtlist) - { - unit->error = 1; - return FALSE; - } - - unit->line_table = decode_line_info (unit, stash); - - if (! unit->line_table) - { - unit->error = 1; - return FALSE; - } - - if (unit->first_child_die_ptr < unit->end_ptr - && ! scan_unit_for_symbols (unit)) - { - unit->error = 1; - return FALSE; - } - } - - function = NULL; - func_p = lookup_address_in_function_table (unit, addr, - &function, functionname_ptr); - if (func_p && (function->tag == DW_TAG_inlined_subroutine)) - stash->inliner_chain = function; - line_p = lookup_address_in_line_info_table (unit->line_table, addr, - filename_ptr, - linenumber_ptr); - return line_p || func_p; -} - -/* Check to see if line info is already decoded in a comp_unit. - If not, decode it. Returns TRUE if no errors were encountered; - FALSE otherwise. */ - -static bfd_boolean -comp_unit_maybe_decode_line_info (struct comp_unit *unit, - struct dwarf2_debug *stash) -{ - if (unit->error) - return FALSE; - - if (! unit->line_table) - { - if (! unit->stmtlist) - { - unit->error = 1; - return FALSE; - } - - unit->line_table = decode_line_info (unit, stash); - - if (! unit->line_table) - { - unit->error = 1; - return FALSE; - } - - if (unit->first_child_die_ptr < unit->end_ptr - && ! scan_unit_for_symbols (unit)) - { - unit->error = 1; - return FALSE; - } - } - - return TRUE; -} - -/* If UNIT contains SYM at ADDR, set the output parameters to the - values for the line containing SYM. The output parameters, - FILENAME_PTR, and LINENUMBER_PTR, are pointers to the objects to be - filled in. - - Return TRUE if UNIT contains SYM, and no errors were encountered; - FALSE otherwise. */ - -static bfd_boolean -comp_unit_find_line (struct comp_unit *unit, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr, - struct dwarf2_debug *stash) -{ - if (!comp_unit_maybe_decode_line_info (unit, stash)) - return FALSE; - - if (sym->flags & BSF_FUNCTION) - return lookup_symbol_in_function_table (unit, sym, addr, - filename_ptr, - linenumber_ptr); - - return lookup_symbol_in_variable_table (unit, sym, addr, - filename_ptr, - linenumber_ptr); -} - -static struct funcinfo * -reverse_funcinfo_list (struct funcinfo *head) -{ - struct funcinfo *rhead; - struct funcinfo *temp; - - for (rhead = NULL; head; head = temp) - { - temp = head->prev_func; - head->prev_func = rhead; - rhead = head; - } - return rhead; -} - -static struct varinfo * -reverse_varinfo_list (struct varinfo *head) -{ - struct varinfo *rhead; - struct varinfo *temp; - - for (rhead = NULL; head; head = temp) - { - temp = head->prev_var; - head->prev_var = rhead; - rhead = head; - } - return rhead; -} - -/* Extract all interesting funcinfos and varinfos of a compilation - unit into hash tables for faster lookup. Returns TRUE if no - errors were enountered; FALSE otherwise. */ - -static bfd_boolean -comp_unit_hash_info (struct dwarf2_debug *stash, - struct comp_unit *unit, - struct info_hash_table *funcinfo_hash_table, - struct info_hash_table *varinfo_hash_table) -{ - struct funcinfo* each_func; - struct varinfo* each_var; - bfd_boolean okay = TRUE; - - BFD_ASSERT (stash->info_hash_status != STASH_INFO_HASH_DISABLED); - - if (!comp_unit_maybe_decode_line_info (unit, stash)) - return FALSE; - - BFD_ASSERT (!unit->cached); - - /* To preserve the original search order, we went to visit the function - infos in the reversed order of the list. However, making the list - bi-directional use quite a bit of extra memory. So we reverse - the list first, traverse the list in the now reversed order and - finally reverse the list again to get back the original order. */ - unit->function_table = reverse_funcinfo_list (unit->function_table); - for (each_func = unit->function_table; - each_func && okay; - each_func = each_func->prev_func) - { - /* Skip nameless functions. */ - if (each_func->name) - /* There is no need to copy name string into hash table as - name string is either in the dwarf string buffer or - info in the stash. */ - okay = insert_info_hash_table (funcinfo_hash_table, each_func->name, - (void*) each_func, FALSE); - } - unit->function_table = reverse_funcinfo_list (unit->function_table); - if (!okay) - return FALSE; - - /* We do the same for variable infos. */ - unit->variable_table = reverse_varinfo_list (unit->variable_table); - for (each_var = unit->variable_table; - each_var && okay; - each_var = each_var->prev_var) - { - /* Skip stack vars and vars with no files or names. */ - if (each_var->stack == 0 - && each_var->file != NULL - && each_var->name != NULL) - /* There is no need to copy name string into hash table as - name string is either in the dwarf string buffer or - info in the stash. */ - okay = insert_info_hash_table (varinfo_hash_table, each_var->name, - (void*) each_var, FALSE); - } - - unit->variable_table = reverse_varinfo_list (unit->variable_table); - unit->cached = TRUE; - return okay; -} - -/* Locate a section in a BFD containing debugging info. The search starts - from the section after AFTER_SEC, or from the first section in the BFD if - AFTER_SEC is NULL. The search works by examining the names of the - sections. There are two permissiable names. The first is .debug_info. - This is the standard DWARF2 name. The second is a prefix .gnu.linkonce.wi. - This is a variation on the .debug_info section which has a checksum - describing the contents appended onto the name. This allows the linker to - identify and discard duplicate debugging sections for different - compilation units. */ -#define DWARF2_DEBUG_INFO ".debug_info" -#define DWARF2_COMPRESSED_DEBUG_INFO ".zdebug_info" -#define GNU_LINKONCE_INFO ".gnu.linkonce.wi." - -static asection * -find_debug_info (bfd *abfd, asection *after_sec) -{ - asection * msec; - - msec = after_sec != NULL ? after_sec->next : abfd->sections; - - while (msec) - { - if (strcmp (msec->name, DWARF2_DEBUG_INFO) == 0) - return msec; - - if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0) - return msec; - - if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO)) - return msec; - - msec = msec->next; - } - - return NULL; -} - -/* Unset vmas for adjusted sections in STASH. */ - -static void -unset_sections (struct dwarf2_debug *stash) -{ - unsigned int i; - struct adjusted_section *p; - - i = stash->adjusted_section_count; - p = stash->adjusted_sections; - for (; i > 0; i--, p++) - p->section->vma = 0; -} - -/* Set unique VMAs for loadable and DWARF sections in ABFD and save - VMAs in STASH for unset_sections. */ - -static bfd_boolean -place_sections (bfd *abfd, struct dwarf2_debug *stash) -{ - struct adjusted_section *p; - unsigned int i; - - if (stash->adjusted_section_count != 0) - { - i = stash->adjusted_section_count; - p = stash->adjusted_sections; - for (; i > 0; i--, p++) - p->section->vma = p->adj_vma; - } - else - { - asection *sect; - bfd_vma last_vma = 0, last_dwarf = 0; - bfd_size_type amt; - - i = 0; - for (sect = abfd->sections; sect != NULL; sect = sect->next) - { - bfd_size_type sz; - int is_debug_info; - - if (sect->vma != 0) - continue; - - /* We need to adjust the VMAs of any .debug_info sections. - Skip compressed ones, since no relocations could target - them - they should not appear in object files anyway. */ - if (strcmp (sect->name, DWARF2_DEBUG_INFO) == 0) - is_debug_info = 1; - else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO)) - is_debug_info = 1; - else - is_debug_info = 0; - - if (!is_debug_info && (sect->flags & SEC_LOAD) == 0) - continue; - - sz = sect->rawsize ? sect->rawsize : sect->size; - if (sz == 0) - continue; - - i++; - } - - amt = i * sizeof (struct adjusted_section); - p = (struct adjusted_section *) bfd_zalloc (abfd, amt); - if (! p) - return FALSE; - - stash->adjusted_sections = p; - stash->adjusted_section_count = i; - - for (sect = abfd->sections; sect != NULL; sect = sect->next) - { - bfd_size_type sz; - int is_debug_info; - - if (sect->vma != 0) - continue; - - /* We need to adjust the VMAs of any .debug_info sections. - Skip compressed ones, since no relocations could target - them - they should not appear in object files anyway. */ - if (strcmp (sect->name, DWARF2_DEBUG_INFO) == 0) - is_debug_info = 1; - else if (CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO)) - is_debug_info = 1; - else - is_debug_info = 0; - - if (!is_debug_info && (sect->flags & SEC_LOAD) == 0) - continue; - - sz = sect->rawsize ? sect->rawsize : sect->size; - if (sz == 0) - continue; - - p->section = sect; - if (is_debug_info) - { - BFD_ASSERT (sect->alignment_power == 0); - sect->vma = last_dwarf; - last_dwarf += sz; - } - else if (last_vma != 0) - { - /* Align the new address to the current section - alignment. */ - last_vma = ((last_vma - + ~((bfd_vma) -1 << sect->alignment_power)) - & ((bfd_vma) -1 << sect->alignment_power)); - sect->vma = last_vma; - last_vma += sect->vma + sz; - } - else - last_vma += sect->vma + sz; - - p->adj_vma = sect->vma; - - p++; - } - } - - return TRUE; -} - -/* Look up a funcinfo by name using the given info hash table. If found, - also update the locations pointed to by filename_ptr and linenumber_ptr. - - This function returns TRUE if a funcinfo that matches the given symbol - and address is found with any error; otherwise it returns FALSE. */ - -static bfd_boolean -info_hash_lookup_funcinfo (struct info_hash_table *hash_table, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - struct funcinfo* each_func; - struct funcinfo* best_fit = NULL; - struct info_list_node *node; - struct arange *arange; - const char *name = bfd_asymbol_name (sym); - asection *sec = bfd_get_section (sym); - - for (node = lookup_info_hash_table (hash_table, name); - node; - node = node->next) - { - each_func = (struct funcinfo *) node->info; - for (arange = &each_func->arange; - arange; - arange = arange->next) - { - if ((!each_func->sec || each_func->sec == sec) - && addr >= arange->low - && addr < arange->high - && (!best_fit - || ((arange->high - arange->low) - < (best_fit->arange.high - best_fit->arange.low)))) - best_fit = each_func; - } - } - - if (best_fit) - { - best_fit->sec = sec; - *filename_ptr = best_fit->file; - *linenumber_ptr = best_fit->line; - return TRUE; - } - - return FALSE; -} - -/* Look up a varinfo by name using the given info hash table. If found, - also update the locations pointed to by filename_ptr and linenumber_ptr. - - This function returns TRUE if a varinfo that matches the given symbol - and address is found with any error; otherwise it returns FALSE. */ - -static bfd_boolean -info_hash_lookup_varinfo (struct info_hash_table *hash_table, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - const char *name = bfd_asymbol_name (sym); - asection *sec = bfd_get_section (sym); - struct varinfo* each; - struct info_list_node *node; - - for (node = lookup_info_hash_table (hash_table, name); - node; - node = node->next) - { - each = (struct varinfo *) node->info; - if (each->addr == addr - && (!each->sec || each->sec == sec)) - { - each->sec = sec; - *filename_ptr = each->file; - *linenumber_ptr = each->line; - return TRUE; - } - } - - return FALSE; -} - -/* Update the funcinfo and varinfo info hash tables if they are - not up to date. Returns TRUE if there is no error; otherwise - returns FALSE and disable the info hash tables. */ - -static bfd_boolean -stash_maybe_update_info_hash_tables (struct dwarf2_debug *stash) -{ - struct comp_unit *each; - - /* Exit if hash tables are up-to-date. */ - if (stash->all_comp_units == stash->hash_units_head) - return TRUE; - - if (stash->hash_units_head) - each = stash->hash_units_head->prev_unit; - else - each = stash->last_comp_unit; - - while (each) - { - if (!comp_unit_hash_info (stash, each, stash->funcinfo_hash_table, - stash->varinfo_hash_table)) - { - stash->info_hash_status = STASH_INFO_HASH_DISABLED; - return FALSE; - } - each = each->prev_unit; - } - - stash->hash_units_head = stash->all_comp_units; - return TRUE; -} - -/* Check consistency of info hash tables. This is for debugging only. */ - -static void ATTRIBUTE_UNUSED -stash_verify_info_hash_table (struct dwarf2_debug *stash) -{ - struct comp_unit *each_unit; - struct funcinfo *each_func; - struct varinfo *each_var; - struct info_list_node *node; - bfd_boolean found; - - for (each_unit = stash->all_comp_units; - each_unit; - each_unit = each_unit->next_unit) - { - for (each_func = each_unit->function_table; - each_func; - each_func = each_func->prev_func) - { - if (!each_func->name) - continue; - node = lookup_info_hash_table (stash->funcinfo_hash_table, - each_func->name); - BFD_ASSERT (node); - found = FALSE; - while (node && !found) - { - found = node->info == each_func; - node = node->next; - } - BFD_ASSERT (found); - } - - for (each_var = each_unit->variable_table; - each_var; - each_var = each_var->prev_var) - { - if (!each_var->name || !each_var->file || each_var->stack) - continue; - node = lookup_info_hash_table (stash->varinfo_hash_table, - each_var->name); - BFD_ASSERT (node); - found = FALSE; - while (node && !found) - { - found = node->info == each_var; - node = node->next; - } - BFD_ASSERT (found); - } - } -} - -/* Check to see if we want to enable the info hash tables, which consume - quite a bit of memory. Currently we only check the number times - bfd_dwarf2_find_line is called. In the future, we may also want to - take the number of symbols into account. */ - -static void -stash_maybe_enable_info_hash_tables (bfd *abfd, struct dwarf2_debug *stash) -{ - BFD_ASSERT (stash->info_hash_status == STASH_INFO_HASH_OFF); - - if (stash->info_hash_count++ < STASH_INFO_HASH_TRIGGER) - return; - - /* FIXME: Maybe we should check the reduce_memory_overheads - and optimize fields in the bfd_link_info structure ? */ - - /* Create hash tables. */ - stash->funcinfo_hash_table = create_info_hash_table (abfd); - stash->varinfo_hash_table = create_info_hash_table (abfd); - if (!stash->funcinfo_hash_table || !stash->varinfo_hash_table) - { - /* Turn off info hashes if any allocation above fails. */ - stash->info_hash_status = STASH_INFO_HASH_DISABLED; - return; - } - /* We need a forced update so that the info hash tables will - be created even though there is no compilation unit. That - happens if STASH_INFO_HASH_TRIGGER is 0. */ - stash_maybe_update_info_hash_tables (stash); - stash->info_hash_status = STASH_INFO_HASH_ON; -} - -/* Find the file and line associated with a symbol and address using the - info hash tables of a stash. If there is a match, the function returns - TRUE and update the locations pointed to by filename_ptr and linenumber_ptr; - otherwise it returns FALSE. */ - -static bfd_boolean -stash_find_line_fast (struct dwarf2_debug *stash, - asymbol *sym, - bfd_vma addr, - const char **filename_ptr, - unsigned int *linenumber_ptr) -{ - BFD_ASSERT (stash->info_hash_status == STASH_INFO_HASH_ON); - - if (sym->flags & BSF_FUNCTION) - return info_hash_lookup_funcinfo (stash->funcinfo_hash_table, sym, addr, - filename_ptr, linenumber_ptr); - return info_hash_lookup_varinfo (stash->varinfo_hash_table, sym, addr, - filename_ptr, linenumber_ptr); -} - -/* Find the source code location of SYMBOL. If SYMBOL is NULL - then find the nearest source code location corresponding to - the address SECTION + OFFSET. - Returns TRUE if the line is found without error and fills in - FILENAME_PTR and LINENUMBER_PTR. In the case where SYMBOL was - NULL the FUNCTIONNAME_PTR is also filled in. - SYMBOLS contains the symbol table for ABFD. - ADDR_SIZE is the number of bytes in the initial .debug_info length - field and in the abbreviation offset, or zero to indicate that the - default value should be used. */ - -static bfd_boolean -find_line (bfd *abfd, - asection *section, - bfd_vma offset, - asymbol *symbol, - asymbol **symbols, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr, - unsigned int addr_size, - void **pinfo) -{ - /* Read each compilation unit from the section .debug_info, and check - to see if it contains the address we are searching for. If yes, - lookup the address, and return the line number info. If no, go - on to the next compilation unit. - - We keep a list of all the previously read compilation units, and - a pointer to the next un-read compilation unit. Check the - previously read units before reading more. */ - struct dwarf2_debug *stash; - /* What address are we looking for? */ - bfd_vma addr; - struct comp_unit* each; - bfd_vma found = FALSE; - bfd_boolean do_line; - - stash = (struct dwarf2_debug *) *pinfo; - - if (! stash) - { - bfd_size_type amt = sizeof (struct dwarf2_debug); - - stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt); - if (! stash) - return FALSE; - } - - /* In a relocatable file, 2 functions may have the same address. - We change the section vma so that they won't overlap. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - { - if (! place_sections (abfd, stash)) - return FALSE; - } - - do_line = (section == NULL - && offset == 0 - && functionname_ptr == NULL - && symbol != NULL); - if (do_line) - { - addr = symbol->value; - section = bfd_get_section (symbol); - } - else if (section != NULL - && functionname_ptr != NULL - && symbol == NULL) - addr = offset; - else - abort (); - - if (section->output_section) - addr += section->output_section->vma + section->output_offset; - else - addr += section->vma; - *filename_ptr = NULL; - if (! do_line) - *functionname_ptr = NULL; - *linenumber_ptr = 0; - - if (! *pinfo) - { - bfd *debug_bfd; - bfd_size_type total_size; - asection *msec; - - *pinfo = stash; - - msec = find_debug_info (abfd, NULL); - if (msec == NULL) - { - char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR); - - if (debug_filename == NULL) - /* No dwarf2 info, and no gnu_debuglink to follow. - Note that at this point the stash has been allocated, but - contains zeros. This lets future calls to this function - fail more quickly. */ - goto done; - - if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL - || ! bfd_check_format (debug_bfd, bfd_object) - || (msec = find_debug_info (debug_bfd, NULL)) == NULL) - { - if (debug_bfd) - bfd_close (debug_bfd); - /* FIXME: Should we report our failure to follow the debuglink ? */ - free (debug_filename); - goto done; - } - } - else - debug_bfd = abfd; - - /* There can be more than one DWARF2 info section in a BFD these - days. First handle the easy case when there's only one. If - there's more than one, try case two: none of the sections is - compressed. In that case, read them all in and produce one - large stash. We do this in two passes - in the first pass we - just accumulate the section sizes, and in the second pass we - read in the section's contents. (The allows us to avoid - reallocing the data as we add sections to the stash.) If - some or all sections are compressed, then do things the slow - way, with a bunch of reallocs. */ - - if (! find_debug_info (debug_bfd, msec)) - { - /* Case 1: only one info section. */ - total_size = msec->size; - if (! read_section (debug_bfd, debug_info, symbols, 0, - &stash->info_ptr_memory, &total_size)) - goto done; - } - else - { - /* Case 2: multiple sections. */ - for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec)) - total_size += msec->size; - - stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size); - if (stash->info_ptr_memory == NULL) - goto done; - - total_size = 0; - for (msec = find_debug_info (debug_bfd, NULL); - msec; - msec = find_debug_info (debug_bfd, msec)) - { - bfd_size_type size; - - size = msec->size; - if (size == 0) - continue; - - if (!(bfd_simple_get_relocated_section_contents - (debug_bfd, msec, stash->info_ptr_memory + total_size, - symbols))) - goto done; - - total_size += size; - } - } - - stash->info_ptr = stash->info_ptr_memory; - stash->info_ptr_end = stash->info_ptr + total_size; - stash->sec = find_debug_info (debug_bfd, NULL); - stash->sec_info_ptr = stash->info_ptr; - stash->syms = symbols; - stash->bfd_ptr = debug_bfd; - } - - /* A null info_ptr indicates that there is no dwarf2 info - (or that an error occured while setting up the stash). */ - if (! stash->info_ptr) - goto done; - - stash->inliner_chain = NULL; - - /* Check the previously read comp. units first. */ - if (do_line) - { - /* The info hash tables use quite a bit of memory. We may not want to - always use them. We use some heuristics to decide if and when to - turn it on. */ - if (stash->info_hash_status == STASH_INFO_HASH_OFF) - stash_maybe_enable_info_hash_tables (abfd, stash); - - /* Keep info hash table up to date if they are available. Note that we - may disable the hash tables if there is any error duing update. */ - if (stash->info_hash_status == STASH_INFO_HASH_ON) - stash_maybe_update_info_hash_tables (stash); - - if (stash->info_hash_status == STASH_INFO_HASH_ON) - { - found = stash_find_line_fast (stash, symbol, addr, filename_ptr, - linenumber_ptr); - if (found) - goto done; - } - else - { - /* Check the previously read comp. units first. */ - for (each = stash->all_comp_units; each; each = each->next_unit) - if ((symbol->flags & BSF_FUNCTION) == 0 - || comp_unit_contains_address (each, addr)) - { - found = comp_unit_find_line (each, symbol, addr, filename_ptr, - linenumber_ptr, stash); - if (found) - goto done; - } - } - } - else - { - for (each = stash->all_comp_units; each; each = each->next_unit) - { - found = (comp_unit_contains_address (each, addr) - && comp_unit_find_nearest_line (each, addr, - filename_ptr, - functionname_ptr, - linenumber_ptr, - stash)); - if (found) - goto done; - } - } - - /* The DWARF2 spec says that the initial length field, and the - offset of the abbreviation table, should both be 4-byte values. - However, some compilers do things differently. */ - if (addr_size == 0) - addr_size = 4; - BFD_ASSERT (addr_size == 4 || addr_size == 8); - - /* Read each remaining comp. units checking each as they are read. */ - while (stash->info_ptr < stash->info_ptr_end) - { - bfd_vma length; - unsigned int offset_size = addr_size; - bfd_byte *info_ptr_unit = stash->info_ptr; - - length = read_4_bytes (stash->bfd_ptr, stash->info_ptr); - /* A 0xffffff length is the DWARF3 way of indicating - we use 64-bit offsets, instead of 32-bit offsets. */ - if (length == 0xffffffff) - { - offset_size = 8; - length = read_8_bytes (stash->bfd_ptr, stash->info_ptr + 4); - stash->info_ptr += 12; - } - /* A zero length is the IRIX way of indicating 64-bit offsets, - mostly because the 64-bit length will generally fit in 32 - bits, and the endianness helps. */ - else if (length == 0) - { - offset_size = 8; - length = read_4_bytes (stash->bfd_ptr, stash->info_ptr + 4); - stash->info_ptr += 8; - } - /* In the absence of the hints above, we assume 32-bit DWARF2 - offsets even for targets with 64-bit addresses, because: - a) most of the time these targets will not have generated - more than 2Gb of debug info and so will not need 64-bit - offsets, - and - b) if they do use 64-bit offsets but they are not using - the size hints that are tested for above then they are - not conforming to the DWARF3 standard anyway. */ - else if (addr_size == 8) - { - offset_size = 4; - stash->info_ptr += 4; - } - else - stash->info_ptr += 4; - - if (length > 0) - { - each = parse_comp_unit (stash, length, info_ptr_unit, - offset_size); - if (!each) - /* The dwarf information is damaged, don't trust it any - more. */ - break; - stash->info_ptr += length; - - if (stash->all_comp_units) - stash->all_comp_units->prev_unit = each; - else - stash->last_comp_unit = each; - - each->next_unit = stash->all_comp_units; - stash->all_comp_units = each; - - /* DW_AT_low_pc and DW_AT_high_pc are optional for - compilation units. If we don't have them (i.e., - unit->high == 0), we need to consult the line info table - to see if a compilation unit contains the given - address. */ - if (do_line) - found = (((symbol->flags & BSF_FUNCTION) == 0 - || each->arange.high == 0 - || comp_unit_contains_address (each, addr)) - && comp_unit_find_line (each, symbol, addr, - filename_ptr, - linenumber_ptr, - stash)); - else - found = ((each->arange.high == 0 - || comp_unit_contains_address (each, addr)) - && comp_unit_find_nearest_line (each, addr, - filename_ptr, - functionname_ptr, - linenumber_ptr, - stash)); - - if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr) - == stash->sec->size) - { - stash->sec = find_debug_info (stash->bfd_ptr, stash->sec); - stash->sec_info_ptr = stash->info_ptr; - } - - if (found) - goto done; - } - } - -done: - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - unset_sections (stash); - - return found; -} - -/* The DWARF2 version of find_nearest_line. - Return TRUE if the line is found without error. */ - -bfd_boolean -_bfd_dwarf2_find_nearest_line (bfd *abfd, - asection *section, - asymbol **symbols, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr, - unsigned int addr_size, - void **pinfo) -{ - return find_line (abfd, section, offset, NULL, symbols, filename_ptr, - functionname_ptr, linenumber_ptr, addr_size, - pinfo); -} - -/* The DWARF2 version of find_line. - Return TRUE if the line is found without error. */ - -bfd_boolean -_bfd_dwarf2_find_line (bfd *abfd, - asymbol **symbols, - asymbol *symbol, - const char **filename_ptr, - unsigned int *linenumber_ptr, - unsigned int addr_size, - void **pinfo) -{ - return find_line (abfd, NULL, 0, symbol, symbols, filename_ptr, - NULL, linenumber_ptr, addr_size, - pinfo); -} - -bfd_boolean -_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *linenumber_ptr, - void **pinfo) -{ - struct dwarf2_debug *stash; - - stash = (struct dwarf2_debug *) *pinfo; - if (stash) - { - struct funcinfo *func = stash->inliner_chain; - - if (func && func->caller_func) - { - *filename_ptr = func->caller_file; - *functionname_ptr = func->caller_func->name; - *linenumber_ptr = func->caller_line; - stash->inliner_chain = func->caller_func; - return TRUE; - } - } - - return FALSE; -} - -void -_bfd_dwarf2_cleanup_debug_info (bfd *abfd) -{ - struct comp_unit *each; - struct dwarf2_debug *stash; - - if (abfd == NULL || elf_tdata (abfd) == NULL) - return; - - stash = (struct dwarf2_debug *) elf_tdata (abfd)->dwarf2_find_line_info; - - if (stash == NULL) - return; - - for (each = stash->all_comp_units; each; each = each->next_unit) - { - struct abbrev_info **abbrevs = each->abbrevs; - struct funcinfo *function_table = each->function_table; - struct varinfo *variable_table = each->variable_table; - size_t i; - - for (i = 0; i < ABBREV_HASH_SIZE; i++) - { - struct abbrev_info *abbrev = abbrevs[i]; - - while (abbrev) - { - free (abbrev->attrs); - abbrev = abbrev->next; - } - } - - if (each->line_table) - { - free (each->line_table->dirs); - free (each->line_table->files); - } - - while (function_table) - { - if (function_table->file) - { - free (function_table->file); - function_table->file = NULL; - } - - if (function_table->caller_file) - { - free (function_table->caller_file); - function_table->caller_file = NULL; - } - function_table = function_table->prev_func; - } - - while (variable_table) - { - if (variable_table->file) - { - free (variable_table->file); - variable_table->file = NULL; - } - - variable_table = variable_table->prev_var; - } - } - - if (stash->dwarf_abbrev_buffer) - free (stash->dwarf_abbrev_buffer); - if (stash->dwarf_line_buffer) - free (stash->dwarf_line_buffer); - if (stash->dwarf_str_buffer) - free (stash->dwarf_str_buffer); - if (stash->dwarf_ranges_buffer) - free (stash->dwarf_ranges_buffer); - if (stash->info_ptr_memory) - free (stash->info_ptr_memory); -} diff --git a/contrib/binutils-2.22/bfd/elf-attrs.c b/contrib/binutils-2.22/bfd/elf-attrs.c deleted file mode 100644 index 569e846cc5..0000000000 --- a/contrib/binutils-2.22/bfd/elf-attrs.c +++ /dev/null @@ -1,699 +0,0 @@ -/* ELF attributes support (based on ARM EABI attributes). - Copyright 2005, 2006, 2007, 2009, 2010 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* Return the number of bytes needed by I in uleb128 format. */ -static int -uleb128_size (unsigned int i) -{ - int size; - size = 1; - while (i >= 0x80) - { - i >>= 7; - size++; - } - return size; -} - -/* Return TRUE if the attribute has the default value (0/""). */ -static bfd_boolean -is_default_attr (obj_attribute *attr) -{ - if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0) - return FALSE; - if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s) - return FALSE; - if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type)) - return FALSE; - - return TRUE; -} - -/* Return the size of a single attribute. */ -static bfd_vma -obj_attr_size (int tag, obj_attribute *attr) -{ - bfd_vma size; - - if (is_default_attr (attr)) - return 0; - - size = uleb128_size (tag); - if (ATTR_TYPE_HAS_INT_VAL (attr->type)) - size += uleb128_size (attr->i); - if (ATTR_TYPE_HAS_STR_VAL (attr->type)) - size += strlen ((char *)attr->s) + 1; - return size; -} - -/* Return the vendor name for a given object attributes section. */ -static const char * -vendor_obj_attr_name (bfd *abfd, int vendor) -{ - return (vendor == OBJ_ATTR_PROC - ? get_elf_backend_data (abfd)->obj_attrs_vendor - : "gnu"); -} - -/* Return the size of the object attributes section for VENDOR - (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes - for that vendor to record and the vendor is OBJ_ATTR_GNU. */ -static bfd_vma -vendor_obj_attr_size (bfd *abfd, int vendor) -{ - bfd_vma size; - obj_attribute *attr; - obj_attribute_list *list; - int i; - const char *vendor_name = vendor_obj_attr_name (abfd, vendor); - - if (!vendor_name) - return 0; - - attr = elf_known_obj_attributes (abfd)[vendor]; - size = 0; - for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) - size += obj_attr_size (i, &attr[i]); - - for (list = elf_other_obj_attributes (abfd)[vendor]; - list; - list = list->next) - size += obj_attr_size (list->tag, &list->attr); - - /* NUL 0x1 */ - return ((size || vendor == OBJ_ATTR_PROC) - ? size + 10 + strlen (vendor_name) - : 0); -} - -/* Return the size of the object attributes section. */ -bfd_vma -bfd_elf_obj_attr_size (bfd *abfd) -{ - bfd_vma size; - - size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC); - size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU); - - /* 'A' */ - return (size ? size + 1 : 0); -} - -/* Write VAL in uleb128 format to P, returning a pointer to the - following byte. */ -static bfd_byte * -write_uleb128 (bfd_byte *p, unsigned int val) -{ - bfd_byte c; - do - { - c = val & 0x7f; - val >>= 7; - if (val) - c |= 0x80; - *(p++) = c; - } - while (val); - return p; -} - -/* Write attribute ATTR to butter P, and return a pointer to the following - byte. */ -static bfd_byte * -write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr) -{ - /* Suppress default entries. */ - if (is_default_attr (attr)) - return p; - - p = write_uleb128 (p, tag); - if (ATTR_TYPE_HAS_INT_VAL (attr->type)) - p = write_uleb128 (p, attr->i); - if (ATTR_TYPE_HAS_STR_VAL (attr->type)) - { - int len; - - len = strlen (attr->s) + 1; - memcpy (p, attr->s, len); - p += len; - } - - return p; -} - -/* Write the contents of the object attributes section (length SIZE) - for VENDOR to CONTENTS. */ -static void -vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size, - int vendor) -{ - bfd_byte *p; - obj_attribute *attr; - obj_attribute_list *list; - int i; - const char *vendor_name = vendor_obj_attr_name (abfd, vendor); - size_t vendor_length = strlen (vendor_name) + 1; - - p = contents; - bfd_put_32 (abfd, size, p); - p += 4; - memcpy (p, vendor_name, vendor_length); - p += vendor_length; - *(p++) = Tag_File; - bfd_put_32 (abfd, size - 4 - vendor_length, p); - p += 4; - - attr = elf_known_obj_attributes (abfd)[vendor]; - for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) - { - int tag = i; - if (get_elf_backend_data (abfd)->obj_attrs_order) - tag = get_elf_backend_data (abfd)->obj_attrs_order (i); - p = write_obj_attribute (p, tag, &attr[tag]); - } - - for (list = elf_other_obj_attributes (abfd)[vendor]; - list; - list = list->next) - p = write_obj_attribute (p, list->tag, &list->attr); -} - -/* Write the contents of the object attributes section to CONTENTS. */ -void -bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size) -{ - bfd_byte *p; - int vendor; - bfd_vma my_size; - - p = contents; - *(p++) = 'A'; - my_size = 1; - for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) - { - bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor); - if (vendor_size) - vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor); - p += vendor_size; - my_size += vendor_size; - } - - if (size != my_size) - abort (); -} - -/* Allocate/find an object attribute. */ -static obj_attribute * -elf_new_obj_attr (bfd *abfd, int vendor, int tag) -{ - obj_attribute *attr; - obj_attribute_list *list; - obj_attribute_list *p; - obj_attribute_list **lastp; - - - if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) - { - /* Known tags are preallocated. */ - attr = &elf_known_obj_attributes (abfd)[vendor][tag]; - } - else - { - /* Create a new tag. */ - list = (obj_attribute_list *) - bfd_alloc (abfd, sizeof (obj_attribute_list)); - memset (list, 0, sizeof (obj_attribute_list)); - list->tag = tag; - /* Keep the tag list in order. */ - lastp = &elf_other_obj_attributes (abfd)[vendor]; - for (p = *lastp; p; p = p->next) - { - if (tag < p->tag) - break; - lastp = &p->next; - } - list->next = *lastp; - *lastp = list; - attr = &list->attr; - } - - return attr; -} - -/* Return the value of an integer object attribute. */ -int -bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag) -{ - obj_attribute_list *p; - - if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) - { - /* Known tags are preallocated. */ - return elf_known_obj_attributes (abfd)[vendor][tag].i; - } - else - { - for (p = elf_other_obj_attributes (abfd)[vendor]; - p; - p = p->next) - { - if (tag == p->tag) - return p->attr.i; - if (tag < p->tag) - break; - } - return 0; - } -} - -/* Add an integer object attribute. */ -void -bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i) -{ - obj_attribute *attr; - - attr = elf_new_obj_attr (abfd, vendor, tag); - attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); - attr->i = i; -} - -/* Duplicate an object attribute string value. */ -char * -_bfd_elf_attr_strdup (bfd *abfd, const char * s) -{ - char * p; - int len; - - len = strlen (s) + 1; - p = (char *) bfd_alloc (abfd, len); - return (char *) memcpy (p, s, len); -} - -/* Add a string object attribute. */ -void -bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s) -{ - obj_attribute *attr; - - attr = elf_new_obj_attr (abfd, vendor, tag); - attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); - attr->s = _bfd_elf_attr_strdup (abfd, s); -} - -/* Add a int+string object attribute. */ -void -bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag, - unsigned int i, const char *s) -{ - obj_attribute *attr; - - attr = elf_new_obj_attr (abfd, vendor, tag); - attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); - attr->i = i; - attr->s = _bfd_elf_attr_strdup (abfd, s); -} - -/* Copy the object attributes from IBFD to OBFD. */ -void -_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd) -{ - obj_attribute *in_attr; - obj_attribute *out_attr; - obj_attribute_list *list; - int i; - int vendor; - - for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) - { - in_attr - = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE]; - out_attr - = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE]; - for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) - { - out_attr->type = in_attr->type; - out_attr->i = in_attr->i; - if (in_attr->s && *in_attr->s) - out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s); - in_attr++; - out_attr++; - } - - for (list = elf_other_obj_attributes (ibfd)[vendor]; - list; - list = list->next) - { - in_attr = &list->attr; - switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) - { - case ATTR_TYPE_FLAG_INT_VAL: - bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i); - break; - case ATTR_TYPE_FLAG_STR_VAL: - bfd_elf_add_obj_attr_string (obfd, vendor, list->tag, - in_attr->s); - break; - case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: - bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag, - in_attr->i, in_attr->s); - break; - default: - abort (); - } - } - } -} - -/* Determine whether a GNU object attribute tag takes an integer, a - string or both. */ -static int -gnu_obj_attrs_arg_type (int tag) -{ - /* Except for Tag_compatibility, for GNU attributes we follow the - same rule ARM ones > 32 follow: odd-numbered tags take strings - and even-numbered tags take integers. In addition, tag & 2 is - nonzero for architecture-independent tags and zero for - architecture-dependent ones. */ - if (tag == Tag_compatibility) - return 3; - else - return (tag & 1) != 0 ? 2 : 1; -} - -/* Determine what arguments an attribute tag takes. */ -int -_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag) -{ - switch (vendor) - { - case OBJ_ATTR_PROC: - return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag); - break; - case OBJ_ATTR_GNU: - return gnu_obj_attrs_arg_type (tag); - break; - default: - abort (); - } -} - -/* Parse an object attributes section. */ -void -_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr) -{ - bfd_byte *contents; - bfd_byte *p; - bfd_vma len; - const char *std_section; - - contents = (bfd_byte *) bfd_malloc (hdr->sh_size); - if (!contents) - return; - if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0, - hdr->sh_size)) - { - free (contents); - return; - } - p = contents; - std_section = get_elf_backend_data (abfd)->obj_attrs_vendor; - if (*(p++) == 'A') - { - len = hdr->sh_size - 1; - while (len > 0) - { - int namelen; - bfd_vma section_len; - int vendor; - - section_len = bfd_get_32 (abfd, p); - p += 4; - if (section_len > len) - section_len = len; - len -= section_len; - namelen = strlen ((char *)p) + 1; - section_len -= namelen + 4; - if (std_section && strcmp ((char *)p, std_section) == 0) - vendor = OBJ_ATTR_PROC; - else if (strcmp ((char *)p, "gnu") == 0) - vendor = OBJ_ATTR_GNU; - else - { - /* Other vendor section. Ignore it. */ - p += namelen + section_len; - continue; - } - - p += namelen; - while (section_len > 0) - { - int tag; - unsigned int n; - unsigned int val; - bfd_vma subsection_len; - bfd_byte *end; - - tag = read_unsigned_leb128 (abfd, p, &n); - p += n; - subsection_len = bfd_get_32 (abfd, p); - p += 4; - if (subsection_len > section_len) - subsection_len = section_len; - section_len -= subsection_len; - subsection_len -= n + 4; - end = p + subsection_len; - switch (tag) - { - case Tag_File: - while (p < end) - { - int type; - - tag = read_unsigned_leb128 (abfd, p, &n); - p += n; - type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); - switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) - { - case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: - val = read_unsigned_leb128 (abfd, p, &n); - p += n; - bfd_elf_add_obj_attr_int_string (abfd, vendor, tag, - val, (char *)p); - p += strlen ((char *)p) + 1; - break; - case ATTR_TYPE_FLAG_STR_VAL: - bfd_elf_add_obj_attr_string (abfd, vendor, tag, - (char *)p); - p += strlen ((char *)p) + 1; - break; - case ATTR_TYPE_FLAG_INT_VAL: - val = read_unsigned_leb128 (abfd, p, &n); - p += n; - bfd_elf_add_obj_attr_int (abfd, vendor, tag, val); - break; - default: - abort (); - } - } - break; - case Tag_Section: - case Tag_Symbol: - /* Don't have anywhere convenient to attach these. - Fall through for now. */ - default: - /* Ignore things we don't kow about. */ - p += subsection_len; - subsection_len = 0; - break; - } - } - } - } - free (contents); -} - -/* Merge common object attributes from IBFD into OBFD. Raise an error - if there are conflicting attributes. Any processor-specific - attributes have already been merged. This must be called from the - bfd_elfNN_bfd_merge_private_bfd_data hook for each individual - target, along with any target-specific merging. Because there are - no common attributes other than Tag_compatibility at present, and - non-"gnu" Tag_compatibility is not expected in "gnu" sections, this - is not presently called for targets without their own - attributes. */ - -bfd_boolean -_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd) -{ - obj_attribute *in_attr; - obj_attribute *out_attr; - int vendor; - - /* The only common attribute is currently Tag_compatibility, - accepted in both processor and "gnu" sections. */ - for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) - { - /* Handle Tag_compatibility. The tags are only compatible if the flags - are identical and, if the flags are '1', the strings are identical. - If the flags are non-zero, then we can only use the string "gnu". */ - in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility]; - out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility]; - - if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0) - { - _bfd_error_handler - (_("error: %B: Object has vendor-specific contents that " - "must be processed by the '%s' toolchain"), - ibfd, in_attr->s); - return FALSE; - } - - if (in_attr->i != out_attr->i - || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0)) - { - _bfd_error_handler (_("error: %B: Object tag '%d, %s' is " - "incompatible with tag '%d, %s'"), - ibfd, - in_attr->i, in_attr->s ? in_attr->s : "", - out_attr->i, out_attr->s ? out_attr->s : ""); - return FALSE; - } - } - - return TRUE; -} - -/* Merge an unknown processor-specific attribute TAG, within the range - of known attributes, from IBFD into OBFD; return TRUE if the link - is OK, FALSE if it must fail. */ - -bfd_boolean -_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag) -{ - obj_attribute *in_attr; - obj_attribute *out_attr; - bfd *err_bfd = NULL; - bfd_boolean result = TRUE; - - in_attr = elf_known_obj_attributes_proc (ibfd); - out_attr = elf_known_obj_attributes_proc (obfd); - - if (out_attr[tag].i != 0 || out_attr[tag].s != NULL) - err_bfd = obfd; - else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL) - err_bfd = ibfd; - - if (err_bfd != NULL) - result - = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag); - - /* Only pass on attributes that match in both inputs. */ - if (in_attr[tag].i != out_attr[tag].i - || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL) - || (in_attr[tag].s != NULL && out_attr[tag].s != NULL - && strcmp (in_attr[tag].s, out_attr[tag].s) != 0)) - { - out_attr[tag].i = 0; - out_attr[tag].s = NULL; - } - - return result; -} - -/* Merge the lists of unknown processor-specific attributes, outside - the known range, from IBFD into OBFD; return TRUE if the link is - OK, FALSE if it must fail. */ - -bfd_boolean -_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd) -{ - obj_attribute_list *in_list; - obj_attribute_list *out_list; - obj_attribute_list **out_listp; - bfd_boolean result = TRUE; - - in_list = elf_other_obj_attributes_proc (ibfd); - out_listp = &elf_other_obj_attributes_proc (obfd); - out_list = *out_listp; - - for (; in_list || out_list; ) - { - bfd *err_bfd = NULL; - int err_tag = 0; - - /* The tags for each list are in numerical order. */ - /* If the tags are equal, then merge. */ - if (out_list && (!in_list || in_list->tag > out_list->tag)) - { - /* This attribute only exists in obfd. We can't merge, and we don't - know what the tag means, so delete it. */ - err_bfd = obfd; - err_tag = out_list->tag; - *out_listp = out_list->next; - out_list = *out_listp; - } - else if (in_list && (!out_list || in_list->tag < out_list->tag)) - { - /* This attribute only exists in ibfd. We can't merge, and we don't - know what the tag means, so ignore it. */ - err_bfd = ibfd; - err_tag = in_list->tag; - in_list = in_list->next; - } - else /* The tags are equal. */ - { - /* As present, all attributes in the list are unknown, and - therefore can't be merged meaningfully. */ - err_bfd = obfd; - err_tag = out_list->tag; - - /* Only pass on attributes that match in both inputs. */ - if (in_list->attr.i != out_list->attr.i - || (in_list->attr.s == NULL) != (out_list->attr.s == NULL) - || (in_list->attr.s && out_list->attr.s - && strcmp (in_list->attr.s, out_list->attr.s) != 0)) - { - /* No match. Delete the attribute. */ - *out_listp = out_list->next; - out_list = *out_listp; - } - else - { - /* Matched. Keep the attribute and move to the next. */ - out_list = out_list->next; - in_list = in_list->next; - } - } - - if (err_bfd) - result = result - && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, - err_tag); - } - - return result; -} diff --git a/contrib/binutils-2.22/bfd/elf-bfd.h b/contrib/binutils-2.22/bfd/elf-bfd.h deleted file mode 100644 index d6e2ab29ce..0000000000 --- a/contrib/binutils-2.22/bfd/elf-bfd.h +++ /dev/null @@ -1,2443 +0,0 @@ -/* BFD back-end data structures for ELF files. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ 1 - -#include "elf/common.h" -#include "elf/external.h" -#include "elf/internal.h" -#include "bfdlink.h" - -/* The number of entries in a section is its size divided by the size - of a single entry. This is normally only applicable to reloc and - symbol table sections. - PR 9934: It is possible to have relocations that do not refer to - symbols, thus it is also possible to have a relocation section in - an object file, but no symbol table. */ -#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0) - -/* If size isn't specified as 64 or 32, NAME macro should fail. */ -#ifndef NAME -#if ARCH_SIZE == 64 -#define NAME(x, y) x ## 64 ## _ ## y -#endif -#if ARCH_SIZE == 32 -#define NAME(x, y) x ## 32 ## _ ## y -#endif -#endif - -#ifndef NAME -#define NAME(x, y) x ## NOSIZE ## _ ## y -#endif - -#define ElfNAME(X) NAME(Elf,X) -#define elfNAME(X) NAME(elf,X) - -/* Information held for an ELF symbol. The first field is the - corresponding asymbol. Every symbol is an ELF file is actually a - pointer to this structure, although it is often handled as a - pointer to an asymbol. */ - -typedef struct -{ - /* The BFD symbol. */ - asymbol symbol; - /* ELF symbol information. */ - Elf_Internal_Sym internal_elf_sym; - /* Backend specific information. */ - union - { - unsigned int hppa_arg_reloc; - void *mips_extr; - void *any; - } - tc_data; - - /* Version information. This is from an Elf_Internal_Versym - structure in a SHT_GNU_versym section. It is zero if there is no - version information. */ - unsigned short version; - -} elf_symbol_type; - -struct elf_strtab_hash; -struct got_entry; -struct plt_entry; - -union gotplt_union - { - bfd_signed_vma refcount; - bfd_vma offset; - struct got_entry *glist; - struct plt_entry *plist; - }; - -struct elf_link_virtual_table_entry - { - /* Virtual table entry use information. This array is nominally of size - size/sizeof(target_void_pointer), though we have to be able to assume - and track a size while the symbol is still undefined. It is indexed - via offset/sizeof(target_void_pointer). */ - size_t size; - bfd_boolean *used; - - /* Virtual table derivation info. */ - struct elf_link_hash_entry *parent; - }; - -/* ELF linker hash table entries. */ - -struct elf_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. This is initialized to -1. It is - set to -2 if the symbol is used by a reloc. */ - long indx; - - /* Symbol index as a dynamic symbol. Initialized to -1, and remains - -1 if this is not a dynamic symbol. */ - /* ??? Note that this is consistently used as a synonym for tests - against whether we can perform various simplifying transformations - to the code. (E.g. changing a pc-relative jump to a PLT entry - into a pc-relative jump to the target function.) That test, which - is often relatively complex, and someplaces wrong or incomplete, - should really be replaced by a predicate in elflink.c. - - End result: this field -1 does not indicate that the symbol is - not in the dynamic symbol table, but rather that the symbol is - not visible outside this DSO. */ - long dynindx; - - /* If this symbol requires an entry in the global offset table, the - processor specific backend uses this field to track usage and - final offset. Two schemes are supported: The first assumes that - a symbol may only have one GOT entry, and uses REFCOUNT until - size_dynamic_sections, at which point the contents of the .got is - fixed. Afterward, if OFFSET is -1, then the symbol does not - require a global offset table entry. The second scheme allows - multiple GOT entries per symbol, managed via a linked list - pointed to by GLIST. */ - union gotplt_union got; - - /* Same, but tracks a procedure linkage table entry. */ - union gotplt_union plt; - - /* Symbol size. */ - bfd_size_type size; - - /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */ - unsigned int type : 8; - - /* Symbol st_other value, symbol visibility. */ - unsigned int other : 8; - - /* The symbol's st_target_internal value (see Elf_Internal_Sym). */ - unsigned int target_internal : 8; - - /* Symbol is referenced by a non-shared object (other than the object - in which it is defined). */ - unsigned int ref_regular : 1; - /* Symbol is defined by a non-shared object. */ - unsigned int def_regular : 1; - /* Symbol is referenced by a shared object. */ - unsigned int ref_dynamic : 1; - /* Symbol is defined by a shared object. */ - unsigned int def_dynamic : 1; - /* Symbol has a non-weak reference from a non-shared object (other than - the object in which it is defined). */ - unsigned int ref_regular_nonweak : 1; - /* Dynamic symbol has been adjustd. */ - unsigned int dynamic_adjusted : 1; - /* Symbol needs a copy reloc. */ - unsigned int needs_copy : 1; - /* Symbol needs a procedure linkage table entry. */ - unsigned int needs_plt : 1; - /* Symbol appears in a non-ELF input file. */ - unsigned int non_elf : 1; - /* Symbol should be marked as hidden in the version information. */ - unsigned int hidden : 1; - /* Symbol was forced to local scope due to a version script file. */ - unsigned int forced_local : 1; - /* Symbol was forced to be dynamic due to a version script file. */ - unsigned int dynamic : 1; - /* Symbol was marked during garbage collection. */ - unsigned int mark : 1; - /* Symbol is referenced by a non-GOT/non-PLT relocation. This is - not currently set by all the backends. */ - unsigned int non_got_ref : 1; - /* Symbol has a definition in a shared object. - FIXME: There is no real need for this field if def_dynamic is never - cleared and all places that test def_dynamic also test def_regular. */ - unsigned int dynamic_def : 1; - /* Symbol is weak in all shared objects. */ - unsigned int dynamic_weak : 1; - /* Symbol is referenced with a relocation where C/C++ pointer equality - matters. */ - unsigned int pointer_equality_needed : 1; - /* Symbol is a unique global symbol. */ - unsigned int unique_global : 1; - - /* String table index in .dynstr if this is a dynamic symbol. */ - unsigned long dynstr_index; - - union - { - /* If this is a weak defined symbol from a dynamic object, this - field points to a defined symbol with the same value, if there is - one. Otherwise it is NULL. */ - struct elf_link_hash_entry *weakdef; - - /* Hash value of the name computed using the ELF hash function. - Used part way through size_dynamic_sections, after we've finished - with weakdefs. */ - unsigned long elf_hash_value; - } u; - - /* Version information. */ - union - { - /* This field is used for a symbol which is not defined in a - regular object. It points to the version information read in - from the dynamic object. */ - Elf_Internal_Verdef *verdef; - /* This field is used for a symbol which is defined in a regular - object. It is set up in size_dynamic_sections. It points to - the version information we should write out for this symbol. */ - struct bfd_elf_version_tree *vertree; - } verinfo; - - struct elf_link_virtual_table_entry *vtable; -}; - -/* Will references to this symbol always reference the symbol - in this object? */ -#define SYMBOL_REFERENCES_LOCAL(INFO, H) \ - _bfd_elf_symbol_refs_local_p (H, INFO, 0) - -/* Will _calls_ to this symbol always call the version in this object? */ -#define SYMBOL_CALLS_LOCAL(INFO, H) \ - _bfd_elf_symbol_refs_local_p (H, INFO, 1) - -/* Common symbols that are turned into definitions don't have the - DEF_REGULAR flag set, so they might appear to be undefined. */ -#define ELF_COMMON_DEF_P(H) \ - (!(H)->def_regular \ - && !(H)->def_dynamic \ - && (H)->root.type == bfd_link_hash_defined) - -/* Records local symbols to be emitted in the dynamic symbol table. */ - -struct elf_link_local_dynamic_entry -{ - struct elf_link_local_dynamic_entry *next; - - /* The input bfd this symbol came from. */ - bfd *input_bfd; - - /* The index of the local symbol being copied. */ - long input_indx; - - /* The index in the outgoing dynamic symbol table. */ - long dynindx; - - /* A copy of the input symbol. */ - Elf_Internal_Sym isym; -}; - -struct elf_link_loaded_list -{ - struct elf_link_loaded_list *next; - bfd *abfd; -}; - -/* Structures used by the eh_frame optimization code. */ -struct eh_cie_fde -{ - union { - struct { - /* If REMOVED == 1, this is the CIE that the FDE originally used. - The CIE belongs to the same .eh_frame input section as the FDE. - - If REMOVED == 0, this is the CIE that we have chosen to use for - the output FDE. The CIE's REMOVED field is also 0, but the CIE - might belong to a different .eh_frame input section from the FDE. */ - struct eh_cie_fde *cie_inf; - struct eh_cie_fde *next_for_section; - } fde; - struct { - /* CIEs have three states: - - - REMOVED && !MERGED: Slated for removal because we haven't yet - proven that an FDE needs it. FULL_CIE, if nonnull, points to - more detailed information about the CIE. - - - REMOVED && MERGED: We have merged this CIE with MERGED_WITH, - which may not belong to the same input section. - - - !REMOVED: We have decided to keep this CIE. SEC is the - .eh_frame input section that contains the CIE. */ - union { - struct cie *full_cie; - struct eh_cie_fde *merged_with; - asection *sec; - } u; - - /* The offset of the personality data from the start of the CIE, - or 0 if the CIE doesn't have any. */ - unsigned int personality_offset : 8; - - /* True if we have marked relocations associated with this CIE. */ - unsigned int gc_mark : 1; - - /* True if we have decided to turn an absolute LSDA encoding into - a PC-relative one. */ - unsigned int make_lsda_relative : 1; - - /* True if we have decided to turn an absolute personality - encoding into a PC-relative one. */ - unsigned int make_per_encoding_relative : 1; - - /* True if the CIE contains personality data and if that - data uses a PC-relative encoding. Always true when - make_per_encoding_relative is. */ - unsigned int per_encoding_relative : 1; - - /* True if we need to add an 'R' (FDE encoding) entry to the - CIE's augmentation data. */ - unsigned int add_fde_encoding : 1; - - /* True if we have merged this CIE with another. */ - unsigned int merged : 1; - - /* Unused bits. */ - unsigned int pad1 : 18; - } cie; - } u; - unsigned int reloc_index; - unsigned int size; - unsigned int offset; - unsigned int new_offset; - unsigned int fde_encoding : 8; - unsigned int lsda_encoding : 8; - unsigned int lsda_offset : 8; - - /* True if this entry represents a CIE, false if it represents an FDE. */ - unsigned int cie : 1; - - /* True if this entry is currently marked for removal. */ - unsigned int removed : 1; - - /* True if we need to add a 'z' (augmentation size) entry to the CIE's - augmentation data, and an associated byte to each of the CIE's FDEs. */ - unsigned int add_augmentation_size : 1; - - /* True if we have decided to convert absolute FDE relocations into - relative ones. This applies to the first relocation in the FDE, - which is against the code that the FDE describes. */ - unsigned int make_relative : 1; - - /* Unused bits. */ - unsigned int pad1 : 4; - - unsigned int *set_loc; -}; - -struct eh_frame_sec_info -{ - unsigned int count; - struct cie *cies; - struct eh_cie_fde entry[1]; -}; - -struct eh_frame_array_ent -{ - bfd_vma initial_loc; - bfd_vma fde; -}; - -struct htab; - -struct eh_frame_hdr_info -{ - struct htab *cies; - asection *hdr_sec; - unsigned int fde_count, array_count; - struct eh_frame_array_ent *array; - /* TRUE if we should try to merge CIEs between input sections. */ - bfd_boolean merge_cies; - /* TRUE if all .eh_frames have been parsd. */ - bfd_boolean parsed_eh_frames; - /* TRUE if .eh_frame_hdr should contain the sorted search table. - We build it if we successfully read all .eh_frame input sections - and recognize them. */ - bfd_boolean table; -}; - -/* Enum used to identify target specific extensions to the elf_obj_tdata - and elf_link_hash_table structures. Note the enums deliberately start - from 1 so that we can detect an uninitialized field. The generic value - is last so that additions to this enum do not need to modify more than - one line. */ -enum elf_target_id -{ - ALPHA_ELF_DATA = 1, - ARM_ELF_DATA, - AVR_ELF_DATA, - BFIN_ELF_DATA, - CRIS_ELF_DATA, - FRV_ELF_DATA, - HPPA32_ELF_DATA, - HPPA64_ELF_DATA, - I386_ELF_DATA, - IA64_ELF_DATA, - LM32_ELF_DATA, - M32R_ELF_DATA, - M68HC11_ELF_DATA, - M68K_ELF_DATA, - MICROBLAZE_ELF_DATA, - MIPS_ELF_DATA, - MN10300_ELF_DATA, - PPC32_ELF_DATA, - PPC64_ELF_DATA, - S390_ELF_DATA, - SH_ELF_DATA, - SPARC_ELF_DATA, - SPU_ELF_DATA, - TIC6X_ELF_DATA, - X86_64_ELF_DATA, - XTENSA_ELF_DATA, - TILEGX_ELF_DATA, - TILEPRO_ELF_DATA, - GENERIC_ELF_DATA -}; - -/* ELF linker hash table. */ - -struct elf_link_hash_table -{ - struct bfd_link_hash_table root; - - /* An identifier used to distinguish different target - specific extensions to this structure. */ - enum elf_target_id hash_table_id; - - /* Whether we have created the special dynamic sections required - when linking against or generating a shared object. */ - bfd_boolean dynamic_sections_created; - - /* True if this target has relocatable executables, so needs dynamic - section symbols. */ - bfd_boolean is_relocatable_executable; - - /* The BFD used to hold special sections created by the linker. - This will be the first BFD found which requires these sections to - be created. */ - bfd *dynobj; - - /* The value to use when initialising got.refcount/offset and - plt.refcount/offset in an elf_link_hash_entry. Set to zero when - the values are refcounts. Set to init_got_offset/init_plt_offset - in size_dynamic_sections when the values may be offsets. */ - union gotplt_union init_got_refcount; - union gotplt_union init_plt_refcount; - - /* The value to use for got.refcount/offset and plt.refcount/offset - when the values may be offsets. Normally (bfd_vma) -1. */ - union gotplt_union init_got_offset; - union gotplt_union init_plt_offset; - - /* The number of symbols found in the link which must be put into - the .dynsym section. */ - bfd_size_type dynsymcount; - - /* The string table of dynamic symbols, which becomes the .dynstr - section. */ - struct elf_strtab_hash *dynstr; - - /* The number of buckets in the hash table in the .hash section. - This is based on the number of dynamic symbols. */ - bfd_size_type bucketcount; - - /* A linked list of DT_NEEDED names found in dynamic objects - included in the link. */ - struct bfd_link_needed_list *needed; - - /* Sections in the output bfd that provides a section symbol - to be used by relocations emitted against local symbols. - Most targets will not use data_index_section. */ - asection *text_index_section; - asection *data_index_section; - - /* The _GLOBAL_OFFSET_TABLE_ symbol. */ - struct elf_link_hash_entry *hgot; - - /* The _PROCEDURE_LINKAGE_TABLE_ symbol. */ - struct elf_link_hash_entry *hplt; - - /* A pointer to information used to merge SEC_MERGE sections. */ - void *merge_info; - - /* Used to link stabs in sections. */ - struct stab_info stab_info; - - /* Used by eh_frame code when editing .eh_frame. */ - struct eh_frame_hdr_info eh_info; - - /* A linked list of local symbols to be added to .dynsym. */ - struct elf_link_local_dynamic_entry *dynlocal; - - /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic - objects included in the link. */ - struct bfd_link_needed_list *runpath; - - /* Cached first output tls section and size of PT_TLS segment. */ - asection *tls_sec; - bfd_size_type tls_size; - - /* A linked list of BFD's loaded in the link. */ - struct elf_link_loaded_list *loaded; - - /* Short-cuts to get to dynamic linker sections. */ - asection *sgot; - asection *sgotplt; - asection *srelgot; - asection *splt; - asection *srelplt; - asection *igotplt; - asection *iplt; - asection *irelplt; - asection *irelifunc; -}; - -/* Look up an entry in an ELF linker hash table. */ - -#define elf_link_hash_lookup(table, string, create, copy, follow) \ - ((struct elf_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse an ELF linker hash table. */ - -#define elf_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ - (info))) - -/* Get the ELF linker hash table from a link_info structure. */ - -#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash)) - -#define elf_hash_table_id(table) ((table) -> hash_table_id) - -/* Returns TRUE if the hash table is a struct elf_link_hash_table. */ -#define is_elf_hash_table(htab) \ - (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table) - -/* Used by bfd_sym_from_r_symndx to cache a small number of local - symbols. */ -#define LOCAL_SYM_CACHE_SIZE 32 -struct sym_cache -{ - bfd *abfd; - unsigned long indx[LOCAL_SYM_CACHE_SIZE]; - Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE]; -}; - -/* Constant information held for an ELF backend. */ - -struct elf_size_info { - unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr; - unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note; - - /* The size of entries in the .hash section. */ - unsigned char sizeof_hash_entry; - - /* The number of internal relocations to allocate per external - relocation entry. */ - unsigned char int_rels_per_ext_rel; - /* We use some fixed size arrays. This should be large enough to - handle all back-ends. */ -#define MAX_INT_RELS_PER_EXT_REL 3 - - unsigned char arch_size, log_file_align; - unsigned char elfclass, ev_current; - int (*write_out_phdrs) - (bfd *, const Elf_Internal_Phdr *, unsigned int); - bfd_boolean - (*write_shdrs_and_ehdr) (bfd *); - bfd_boolean (*checksum_contents) - (bfd * , void (*) (const void *, size_t, void *), void *); - void (*write_relocs) - (bfd *, asection *, void *); - bfd_boolean (*swap_symbol_in) - (bfd *, const void *, const void *, Elf_Internal_Sym *); - void (*swap_symbol_out) - (bfd *, const Elf_Internal_Sym *, void *, void *); - bfd_boolean (*slurp_reloc_table) - (bfd *, asection *, asymbol **, bfd_boolean); - long (*slurp_symbol_table) - (bfd *, asymbol **, bfd_boolean); - void (*swap_dyn_in) - (bfd *, const void *, Elf_Internal_Dyn *); - void (*swap_dyn_out) - (bfd *, const Elf_Internal_Dyn *, void *); - - /* This function is called to swap in a REL relocation. If an - external relocation corresponds to more than one internal - relocation, then all relocations are swapped in at once. */ - void (*swap_reloc_in) - (bfd *, const bfd_byte *, Elf_Internal_Rela *); - - /* This function is called to swap out a REL relocation. */ - void (*swap_reloc_out) - (bfd *, const Elf_Internal_Rela *, bfd_byte *); - - /* This function is called to swap in a RELA relocation. If an - external relocation corresponds to more than one internal - relocation, then all relocations are swapped in at once. */ - void (*swap_reloca_in) - (bfd *, const bfd_byte *, Elf_Internal_Rela *); - - /* This function is called to swap out a RELA relocation. */ - void (*swap_reloca_out) - (bfd *, const Elf_Internal_Rela *, bfd_byte *); -}; - -#define elf_symbol_from(ABFD,S) \ - (((S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \ - && (S)->the_bfd->tdata.elf_obj_data != 0) \ - ? (elf_symbol_type *) (S) \ - : 0) - -enum elf_reloc_type_class { - reloc_class_normal, - reloc_class_relative, - reloc_class_plt, - reloc_class_copy -}; - -struct elf_reloc_cookie -{ - Elf_Internal_Rela *rels, *rel, *relend; - Elf_Internal_Sym *locsyms; - bfd *abfd; - size_t locsymcount; - size_t extsymoff; - struct elf_link_hash_entry **sym_hashes; - int r_sym_shift; - bfd_boolean bad_symtab; -}; - -/* The level of IRIX compatibility we're striving for. */ - -typedef enum { - ict_none, - ict_irix5, - ict_irix6 -} irix_compat_t; - -/* Mapping of ELF section names and types. */ -struct bfd_elf_special_section -{ - const char *prefix; - int prefix_length; - /* 0 means name must match PREFIX exactly. - -1 means name must start with PREFIX followed by an arbitrary string. - -2 means name must match PREFIX exactly or consist of PREFIX followed - by a dot then anything. - > 0 means name must start with the first PREFIX_LENGTH chars of - PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */ - int suffix_length; - int type; - bfd_vma attr; -}; - -enum action_discarded - { - COMPLAIN = 1, - PRETEND = 2 - }; - -typedef asection * (*elf_gc_mark_hook_fn) - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *); - -struct elf_backend_data -{ - /* The architecture for this backend. */ - enum bfd_architecture arch; - - /* An identifier used to distinguish different target specific - extensions to elf_obj_tdata and elf_link_hash_table structures. */ - enum elf_target_id target_id; - - /* The ELF machine code (EM_xxxx) for this backend. */ - int elf_machine_code; - - /* EI_OSABI. */ - int elf_osabi; - - /* The maximum page size for this backend. */ - bfd_vma maxpagesize; - - /* The minimum page size for this backend. An input object will not be - considered page aligned unless its sections are correctly aligned for - pages at least this large. May be smaller than maxpagesize. */ - bfd_vma minpagesize; - - /* The common page size for this backend. */ - bfd_vma commonpagesize; - - /* The BFD flags applied to sections created for dynamic linking. */ - flagword dynamic_sec_flags; - - /* Architecture-specific data for this backend. - This is actually a pointer to some type like struct elf_ARCH_data. */ - const void *arch_data; - - /* A function to translate an ELF RELA relocation to a BFD arelent - structure. */ - void (*elf_info_to_howto) - (bfd *, arelent *, Elf_Internal_Rela *); - - /* A function to translate an ELF REL relocation to a BFD arelent - structure. */ - void (*elf_info_to_howto_rel) - (bfd *, arelent *, Elf_Internal_Rela *); - - /* A function to determine whether a symbol is global when - partitioning the symbol table into local and global symbols. - This should be NULL for most targets, in which case the correct - thing will be done. MIPS ELF, at least on the Irix 5, has - special requirements. */ - bfd_boolean (*elf_backend_sym_is_global) - (bfd *, asymbol *); - - /* The remaining functions are hooks which are called only if they - are not NULL. */ - - /* A function to permit a backend specific check on whether a - particular BFD format is relevant for an object file, and to - permit the backend to set any global information it wishes. When - this is called elf_elfheader is set, but anything else should be - used with caution. If this returns FALSE, the check_format - routine will return a bfd_error_wrong_format error. */ - bfd_boolean (*elf_backend_object_p) - (bfd *); - - /* A function to do additional symbol processing when reading the - ELF symbol table. This is where any processor-specific special - section indices are handled. */ - void (*elf_backend_symbol_processing) - (bfd *, asymbol *); - - /* A function to do additional symbol processing after reading the - entire ELF symbol table. */ - bfd_boolean (*elf_backend_symbol_table_processing) - (bfd *, elf_symbol_type *, unsigned int); - - /* A function to set the type of the info field. Processor-specific - types should be handled here. */ - int (*elf_backend_get_symbol_type) - (Elf_Internal_Sym *, int); - - /* A function to return the linker hash table entry of a symbol that - might be satisfied by an archive symbol. */ - struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup) - (bfd *, struct bfd_link_info *, const char *); - - /* Return true if local section symbols should have a non-null st_name. - NULL implies false. */ - bfd_boolean (*elf_backend_name_local_section_symbols) - (bfd *); - - /* A function to do additional processing on the ELF section header - just before writing it out. This is used to set the flags and - type fields for some sections, or to actually write out data for - unusual sections. */ - bfd_boolean (*elf_backend_section_processing) - (bfd *, Elf_Internal_Shdr *); - - /* A function to handle unusual section types when creating BFD - sections from ELF sections. */ - bfd_boolean (*elf_backend_section_from_shdr) - (bfd *, Elf_Internal_Shdr *, const char *, int); - - /* A function to convert machine dependent ELF section header flags to - BFD internal section header flags. */ - bfd_boolean (*elf_backend_section_flags) - (flagword *, const Elf_Internal_Shdr *); - - /* A function that returns a struct containing ELF section flags and - type for the given BFD section. */ - const struct bfd_elf_special_section * (*get_sec_type_attr) - (bfd *, asection *); - - /* A function to handle unusual program segment types when creating BFD - sections from ELF program segments. */ - bfd_boolean (*elf_backend_section_from_phdr) - (bfd *, Elf_Internal_Phdr *, int, const char *); - - /* A function to set up the ELF section header for a BFD section in - preparation for writing it out. This is where the flags and type - fields are set for unusual sections. */ - bfd_boolean (*elf_backend_fake_sections) - (bfd *, Elf_Internal_Shdr *, asection *); - - /* A function to get the ELF section index for a BFD section. If - this returns TRUE, the section was found. If it is a normal ELF - section, *RETVAL should be left unchanged. If it is not a normal - ELF section *RETVAL should be set to the SHN_xxxx index. */ - bfd_boolean (*elf_backend_section_from_bfd_section) - (bfd *, asection *, int *retval); - - /* If this field is not NULL, it is called by the add_symbols phase - of a link just before adding a symbol to the global linker hash - table. It may modify any of the fields as it wishes. If *NAME - is set to NULL, the symbol will be skipped rather than being - added to the hash table. This function is responsible for - handling all processor dependent symbol bindings and section - indices, and must set at least *FLAGS and *SEC for each processor - dependent case; failure to do so will cause a link error. */ - bfd_boolean (*elf_add_symbol_hook) - (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *, - const char **name, flagword *flags, asection **sec, bfd_vma *value); - - /* If this field is not NULL, it is called by the elf_link_output_sym - phase of a link for each symbol which will appear in the object file. - On error, this function returns 0. 1 is returned when the symbol - should be output, 2 is returned when the symbol should be discarded. */ - int (*elf_backend_link_output_symbol_hook) - (struct bfd_link_info *info, const char *, Elf_Internal_Sym *, - asection *, struct elf_link_hash_entry *); - - /* The CREATE_DYNAMIC_SECTIONS function is called by the ELF backend - linker the first time it encounters a dynamic object in the link. - This function must create any sections required for dynamic - linking. The ABFD argument is a dynamic object. The .interp, - .dynamic, .dynsym, .dynstr, and .hash functions have already been - created, and this function may modify the section flags if - desired. This function will normally create the .got and .plt - sections, but different backends have different requirements. */ - bfd_boolean (*elf_backend_create_dynamic_sections) - (bfd *abfd, struct bfd_link_info *info); - - /* When creating a shared library, determine whether to omit the - dynamic symbol for the section. */ - bfd_boolean (*elf_backend_omit_section_dynsym) - (bfd *output_bfd, struct bfd_link_info *info, asection *osec); - - /* Return TRUE if relocations of targets are compatible to the extent - that CHECK_RELOCS will properly process them. PR 4424. */ - bfd_boolean (*relocs_compatible) (const bfd_target *, const bfd_target *); - - /* The CHECK_RELOCS function is called by the add_symbols phase of - the ELF backend linker. It is called once for each section with - relocs of an object file, just after the symbols for the object - file have been added to the global linker hash table. The - function must look through the relocs and do any special handling - required. This generally means allocating space in the global - offset table, and perhaps allocating space for a reloc. The - relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. */ - bfd_boolean (*check_relocs) - (bfd *abfd, struct bfd_link_info *info, asection *o, - const Elf_Internal_Rela *relocs); - - /* The CHECK_DIRECTIVES function is called once per input file by - the add_symbols phase of the ELF backend linker. The function - must inspect the bfd and create any additional symbols according - to any custom directives in the bfd. */ - bfd_boolean (*check_directives) - (bfd *abfd, struct bfd_link_info *info); - - /* The AS_NEEDED_CLEANUP function is called once per --as-needed - input file that was not needed by the add_symbols phase of the - ELF backend linker. The function must undo any target specific - changes in the symbol hash table. */ - bfd_boolean (*as_needed_cleanup) - (bfd *abfd, struct bfd_link_info *info); - - /* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend - linker for every symbol which is defined by a dynamic object and - referenced by a regular object. This is called after all the - input files have been seen, but before the SIZE_DYNAMIC_SECTIONS - function has been called. The hash table entry should be - bfd_link_hash_defined ore bfd_link_hash_defweak, and it should be - defined in a section from a dynamic object. Dynamic object - sections are not included in the final link, and this function is - responsible for changing the value to something which the rest of - the link can deal with. This will normally involve adding an - entry to the .plt or .got or some such section, and setting the - symbol to point to that. */ - bfd_boolean (*elf_backend_adjust_dynamic_symbol) - (struct bfd_link_info *info, struct elf_link_hash_entry *h); - - /* The ALWAYS_SIZE_SECTIONS function is called by the backend linker - after all the linker input files have been seen but before the - section sizes have been set. This is called after - ADJUST_DYNAMIC_SYMBOL, but before SIZE_DYNAMIC_SECTIONS. */ - bfd_boolean (*elf_backend_always_size_sections) - (bfd *output_bfd, struct bfd_link_info *info); - - /* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend - linker after all the linker input files have been seen but before - the sections sizes have been set. This is called after - ADJUST_DYNAMIC_SYMBOL has been called on all appropriate symbols. - It is only called when linking against a dynamic object. It must - set the sizes of the dynamic sections, and may fill in their - contents as well. The generic ELF linker can handle the .dynsym, - .dynstr and .hash sections. This function must handle the - .interp section and any sections created by the - CREATE_DYNAMIC_SECTIONS entry point. */ - bfd_boolean (*elf_backend_size_dynamic_sections) - (bfd *output_bfd, struct bfd_link_info *info); - - /* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections - we keep to use as a base for relocs and symbols. */ - void (*elf_backend_init_index_section) - (bfd *output_bfd, struct bfd_link_info *info); - - /* The RELOCATE_SECTION function is called by the ELF backend linker - to handle the relocations for a section. - - The relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. - - This function is responsible for adjust the section contents as - necessary, and (if using Rela relocs and generating a - relocatable output file) adjusting the reloc addend as - necessary. - - This function does not have to worry about setting the reloc - address or the reloc symbol index. - - LOCAL_SYMS is a pointer to the swapped in local symbols. - - LOCAL_SECTIONS is an array giving the section in the input file - corresponding to the st_shndx field of each local symbol. - - The global hash table entry for the global symbols can be found - via elf_sym_hashes (input_bfd). - - When generating relocatable output, this function must handle - STB_LOCAL/STT_SECTION symbols specially. The output symbol is - going to be the section symbol corresponding to the output - section, which means that the addend must be adjusted - accordingly. - - Returns FALSE on error, TRUE on success, 2 if successful and - relocations should be written for this section. */ - int (*elf_backend_relocate_section) - (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, - asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, asection **local_sections); - - /* The FINISH_DYNAMIC_SYMBOL function is called by the ELF backend - linker just before it writes a symbol out to the .dynsym section. - The processor backend may make any required adjustment to the - symbol. It may also take the opportunity to set contents of the - dynamic sections. Note that FINISH_DYNAMIC_SYMBOL is called on - all .dynsym symbols, while ADJUST_DYNAMIC_SYMBOL is only called - on those symbols which are defined by a dynamic object. */ - bfd_boolean (*elf_backend_finish_dynamic_symbol) - (bfd *output_bfd, struct bfd_link_info *info, - struct elf_link_hash_entry *h, Elf_Internal_Sym *sym); - - /* The FINISH_DYNAMIC_SECTIONS function is called by the ELF backend - linker just before it writes all the dynamic sections out to the - output file. The FINISH_DYNAMIC_SYMBOL will have been called on - all dynamic symbols. */ - bfd_boolean (*elf_backend_finish_dynamic_sections) - (bfd *output_bfd, struct bfd_link_info *info); - - /* A function to do any beginning processing needed for the ELF file - before building the ELF headers and computing file positions. */ - void (*elf_backend_begin_write_processing) - (bfd *, struct bfd_link_info *); - - /* A function to do any final processing needed for the ELF file - before writing it out. The LINKER argument is TRUE if this BFD - was created by the ELF backend linker. */ - void (*elf_backend_final_write_processing) - (bfd *, bfd_boolean linker); - - /* This function is called by get_program_header_size. It should - return the number of additional program segments which this BFD - will need. It should return -1 on error. */ - int (*elf_backend_additional_program_headers) - (bfd *, struct bfd_link_info *); - - /* This function is called to modify an existing segment map in a - backend specific fashion. */ - bfd_boolean (*elf_backend_modify_segment_map) - (bfd *, struct bfd_link_info *); - - /* This function is called to modify program headers just before - they are written. */ - bfd_boolean (*elf_backend_modify_program_headers) - (bfd *, struct bfd_link_info *); - - /* This function is called before section garbage collection to - mark entry symbol sections. */ - void (*gc_keep) - (struct bfd_link_info *); - - /* This function is called during section garbage collection to - mark sections that define global symbols. */ - bfd_boolean (*gc_mark_dynamic_ref) - (struct elf_link_hash_entry *, void *); - - /* This function is called during section gc to discover the section a - particular relocation refers to. */ - elf_gc_mark_hook_fn gc_mark_hook; - - /* This function, if defined, is called after the first gc marking pass - to allow the backend to mark additional sections. */ - bfd_boolean (*gc_mark_extra_sections) - (struct bfd_link_info *, elf_gc_mark_hook_fn); - - /* This function, if defined, is called during the sweep phase of gc - in order that a backend might update any data structures it might - be maintaining. */ - bfd_boolean (*gc_sweep_hook) - (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); - - /* This function, if defined, is called after the ELF headers have - been created. This allows for things like the OS and ABI versions - to be changed. */ - void (*elf_backend_post_process_headers) - (bfd *, struct bfd_link_info *); - - /* This function, if defined, prints a symbol to file and returns the - name of the symbol to be printed. It should return NULL to fall - back to default symbol printing. */ - const char *(*elf_backend_print_symbol_all) - (bfd *, void *, asymbol *); - - /* This function, if defined, is called after all local symbols and - global symbols converted to locals are emitted into the symtab - section. It allows the backend to emit special local symbols - not handled in the hash table. */ - bfd_boolean (*elf_backend_output_arch_local_syms) - (bfd *, struct bfd_link_info *, void *, - bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *)); - - /* This function, if defined, is called after all symbols are emitted - into the symtab section. It allows the backend to emit special - global symbols not handled in the hash table. */ - bfd_boolean (*elf_backend_output_arch_syms) - (bfd *, struct bfd_link_info *, void *, - bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *)); - - /* Copy any information related to dynamic linking from a pre-existing - symbol to a newly created symbol. Also called to copy flags and - other back-end info to a weakdef, in which case the symbol is not - newly created and plt/got refcounts and dynamic indices should not - be copied. */ - void (*elf_backend_copy_indirect_symbol) - (struct bfd_link_info *, struct elf_link_hash_entry *, - struct elf_link_hash_entry *); - - /* Modify any information related to dynamic linking such that the - symbol is not exported. */ - void (*elf_backend_hide_symbol) - (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); - - /* A function to do additional symbol fixup, called by - _bfd_elf_fix_symbol_flags. */ - bfd_boolean (*elf_backend_fixup_symbol) - (struct bfd_link_info *, struct elf_link_hash_entry *); - - /* Merge the backend specific symbol attribute. */ - void (*elf_backend_merge_symbol_attribute) - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, - bfd_boolean); - - /* This function, if defined, will return a string containing the - name of a target-specific dynamic tag. */ - char *(*elf_backend_get_target_dtag) - (bfd_vma); - - /* Decide whether an undefined symbol is special and can be ignored. - This is the case for OPTIONAL symbols on IRIX. */ - bfd_boolean (*elf_backend_ignore_undef_symbol) - (struct elf_link_hash_entry *); - - /* Emit relocations. Overrides default routine for emitting relocs, - except during a relocatable link, or if all relocs are being emitted. */ - bfd_boolean (*elf_backend_emit_relocs) - (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, - struct elf_link_hash_entry **); - - /* Count relocations. Not called for relocatable links - or if all relocs are being preserved in the output. */ - unsigned int (*elf_backend_count_relocs) - (struct bfd_link_info *, asection *); - - /* This function, if defined, is called when an NT_PRSTATUS note is found - in a core file. */ - bfd_boolean (*elf_backend_grok_prstatus) - (bfd *, Elf_Internal_Note *); - - /* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO - note is found in a core file. */ - bfd_boolean (*elf_backend_grok_psinfo) - (bfd *, Elf_Internal_Note *); - - /* This function, if defined, is called to write a note to a corefile. */ - char *(*elf_backend_write_core_note) - (bfd *abfd, char *buf, int *bufsiz, int note_type, ...); - - /* This function, if defined, is called to convert target-specific - section flag names into hex values. */ - flagword (*elf_backend_lookup_section_flags_hook) - (char *); - - /* This function returns class of a reloc type. */ - enum elf_reloc_type_class (*elf_backend_reloc_type_class) - (const Elf_Internal_Rela *); - - /* This function, if defined, removes information about discarded functions - from other sections which mention them. */ - bfd_boolean (*elf_backend_discard_info) - (bfd *, struct elf_reloc_cookie *, struct bfd_link_info *); - - /* This function, if defined, signals that the function above has removed - the discarded relocations for this section. */ - bfd_boolean (*elf_backend_ignore_discarded_relocs) - (asection *); - - /* What to do when ld finds relocations against symbols defined in - discarded sections. */ - unsigned int (*action_discarded) - (asection *); - - /* This function returns the width of FDE pointers in bytes, or 0 if - that can't be determined for some reason. The default definition - goes by the bfd's EI_CLASS. */ - unsigned int (*elf_backend_eh_frame_address_size) - (bfd *, asection *); - - /* These functions tell elf-eh-frame whether to attempt to turn - absolute or lsda encodings into pc-relative ones. The default - definition enables these transformations. */ - bfd_boolean (*elf_backend_can_make_relative_eh_frame) - (bfd *, struct bfd_link_info *, asection *); - bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame) - (bfd *, struct bfd_link_info *, asection *); - - /* This function returns an encoding after computing the encoded - value (and storing it in ENCODED) for the given OFFSET into OSEC, - to be stored in at LOC_OFFSET into the LOC_SEC input section. - The default definition chooses a 32-bit PC-relative encoding. */ - bfd_byte (*elf_backend_encode_eh_address) - (bfd *abfd, struct bfd_link_info *info, - asection *osec, bfd_vma offset, - asection *loc_sec, bfd_vma loc_offset, - bfd_vma *encoded); - - /* This function, if defined, may write out the given section. - Returns TRUE if it did so and FALSE if the caller should. */ - bfd_boolean (*elf_backend_write_section) - (bfd *, struct bfd_link_info *, asection *, bfd_byte *); - - /* The level of IRIX compatibility we're striving for. - MIPS ELF specific function. */ - irix_compat_t (*elf_backend_mips_irix_compat) - (bfd *); - - reloc_howto_type *(*elf_backend_mips_rtype_to_howto) - (unsigned int, bfd_boolean); - - /* The swapping table to use when dealing with ECOFF information. - Used for the MIPS ELF .mdebug section. */ - const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap; - - /* This function implements `bfd_elf_bfd_from_remote_memory'; - see elf.c, elfcode.h. */ - bfd *(*elf_backend_bfd_from_remote_memory) - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len)); - - /* This function is used by `_bfd_elf_get_synthetic_symtab'; - see elf.c. */ - bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *); - - /* Is symbol defined in common section? */ - bfd_boolean (*common_definition) (Elf_Internal_Sym *); - - /* Return a common section index for section. */ - unsigned int (*common_section_index) (asection *); - - /* Return a common section for section. */ - asection *(*common_section) (asection *); - - /* Return TRUE if we can merge 2 definitions. */ - bfd_boolean (*merge_symbol) (struct bfd_link_info *, - struct elf_link_hash_entry **, - struct elf_link_hash_entry *, - Elf_Internal_Sym *, asection **, - bfd_vma *, unsigned int *, - bfd_boolean *, bfd_boolean *, - bfd_boolean *, bfd_boolean *, - bfd_boolean *, bfd_boolean *, - bfd_boolean *, bfd_boolean *, - bfd *, asection **, - bfd_boolean *, bfd_boolean *, - bfd_boolean *, bfd_boolean *, - bfd *, asection **); - - /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ - bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *); - - /* Return TRUE if type is a function symbol type. */ - bfd_boolean (*is_function_type) (unsigned int type); - - /* Used to handle bad SHF_LINK_ORDER input. */ - bfd_error_handler_type link_order_error_handler; - - /* Name of the PLT relocation section. */ - const char *relplt_name; - - /* Alternate EM_xxxx machine codes for this backend. */ - int elf_machine_alt1; - int elf_machine_alt2; - - const struct elf_size_info *s; - - /* An array of target specific special sections. */ - const struct bfd_elf_special_section *special_sections; - - /* The size in bytes of the header for the GOT. This includes the - so-called reserved entries on some systems. */ - bfd_vma got_header_size; - - /* The size of the GOT entry for the symbol pointed to by H if non-NULL, - otherwise by the local symbol with index SYMNDX in IBFD. */ - bfd_vma (*got_elt_size) (bfd *, struct bfd_link_info *, - struct elf_link_hash_entry *h, - bfd *ibfd, unsigned long symndx); - - /* The vendor name to use for a processor-standard attributes section. */ - const char *obj_attrs_vendor; - - /* The section name to use for a processor-standard attributes section. */ - const char *obj_attrs_section; - - /* Return 1, 2 or 3 to indicate what type of arguments a - processor-specific tag takes. */ - int (*obj_attrs_arg_type) (int); - - /* The section type to use for an attributes section. */ - unsigned int obj_attrs_section_type; - - /* This function determines the order in which any attributes are - written. It must be defined for input in the range - LEAST_KNOWN_OBJ_ATTRIBUTE..NUM_KNOWN_OBJ_ATTRIBUTES-1 (this range - is used in order to make unity easy). The returned value is the - actual tag number to place in the input position. */ - int (*obj_attrs_order) (int); - - /* Handle merging unknown attributes; either warn and return TRUE, - or give an error and return FALSE. */ - bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int); - - /* This is non-zero if static TLS segments require a special alignment. */ - unsigned static_tls_alignment; - - /* This is TRUE if the linker should act like collect and gather - global constructors and destructors by name. This is TRUE for - MIPS ELF because the Irix 5 tools can not handle the .init - section. */ - unsigned collect : 1; - - /* This is TRUE if the linker should ignore changes to the type of a - symbol. This is TRUE for MIPS ELF because some Irix 5 objects - record undefined functions as STT_OBJECT although the definitions - are STT_FUNC. */ - unsigned type_change_ok : 1; - - /* Whether the backend may use REL relocations. (Some backends use - both REL and RELA relocations, and this flag is set for those - backends.) */ - unsigned may_use_rel_p : 1; - - /* Whether the backend may use RELA relocations. (Some backends use - both REL and RELA relocations, and this flag is set for those - backends.) */ - unsigned may_use_rela_p : 1; - - /* Whether the default relocation type is RELA. If a backend with - this flag set wants REL relocations for a particular section, - it must note that explicitly. Similarly, if this flag is clear, - and the backend wants RELA relocations for a particular - section. */ - unsigned default_use_rela_p : 1; - - /* True if PLT and copy relocations should be RELA by default. */ - unsigned rela_plts_and_copies_p : 1; - - /* Set if RELA relocations for a relocatable link can be handled by - generic code. Backends that set this flag need do nothing in the - backend relocate_section routine for relocatable linking. */ - unsigned rela_normal : 1; - - /* TRUE if addresses "naturally" sign extend. This is used when - swapping in from Elf32 when BFD64. */ - unsigned sign_extend_vma : 1; - - unsigned want_got_plt : 1; - unsigned plt_readonly : 1; - unsigned want_plt_sym : 1; - unsigned plt_not_loaded : 1; - unsigned plt_alignment : 4; - unsigned can_gc_sections : 1; - unsigned can_refcount : 1; - unsigned want_got_sym : 1; - unsigned want_dynbss : 1; - - /* Targets which do not support physical addressing often require - that the p_paddr field in the section header to be set to zero. - This field indicates whether this behavior is required. */ - unsigned want_p_paddr_set_to_zero : 1; - - /* True if an object file lacking a .note.GNU-stack section - should be assumed to be requesting exec stack. At least one - other file in the link needs to have a .note.GNU-stack section - for a PT_GNU_STACK segment to be created. */ - unsigned default_execstack : 1; -}; - -/* Information about reloc sections associated with a bfd_elf_section_data - structure. */ -struct bfd_elf_section_reloc_data -{ - /* The ELF header for the reloc section associated with this - section, if any. */ - Elf_Internal_Shdr *hdr; - /* The number of relocations currently assigned to HDR. */ - unsigned int count; - /* The ELF section number of the reloc section. Only used for an - output file. */ - int idx; - /* Used by the backend linker to store the symbol hash table entries - associated with relocs against global symbols. */ - struct elf_link_hash_entry **hashes; -}; - -/* Information stored for each BFD section in an ELF file. This - structure is allocated by elf_new_section_hook. */ - -struct bfd_elf_section_data -{ - /* The ELF header for this section. */ - Elf_Internal_Shdr this_hdr; - - /* Information about the REL and RELA reloc sections associated - with this section, if any. */ - struct bfd_elf_section_reloc_data rel, rela; - - /* The ELF section number of this section. */ - int this_idx; - - /* Used by the backend linker when generating a shared library to - record the dynamic symbol index for a section symbol - corresponding to this section. A value of 0 means that there is - no dynamic symbol for this section. */ - int dynindx; - - /* A pointer to the linked-to section for SHF_LINK_ORDER. */ - asection *linked_to; - - /* A pointer to the swapped relocs. If the section uses REL relocs, - rather than RELA, all the r_addend fields will be zero. This - pointer may be NULL. It is used by the backend linker. */ - Elf_Internal_Rela *relocs; - - /* A pointer to a linked list tracking dynamic relocs copied for - local symbols. */ - void *local_dynrel; - - /* A pointer to the bfd section used for dynamic relocs. */ - asection *sreloc; - - union { - /* Group name, if this section is a member of a group. */ - const char *name; - - /* Group signature sym, if this is the SHT_GROUP section. */ - struct bfd_symbol *id; - } group; - - /* For a member of a group, points to the SHT_GROUP section. - NULL for the SHT_GROUP section itself and non-group sections. */ - asection *sec_group; - - /* A linked list of member sections in the group. Circular when used by - the linker. For the SHT_GROUP section, points at first member. */ - asection *next_in_group; - - /* The FDEs associated with this section. The u.fde.next_in_section - field acts as a chain pointer. */ - struct eh_cie_fde *fde_list; - - /* A pointer used for various section optimizations. */ - void *sec_info; -}; - -#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd) -#define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to) -#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type) -#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags) -#define elf_group_name(sec) (elf_section_data(sec)->group.name) -#define elf_group_id(sec) (elf_section_data(sec)->group.id) -#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group) -#define elf_fde_list(sec) (elf_section_data(sec)->fde_list) -#define elf_sec_group(sec) (elf_section_data(sec)->sec_group) - -#define xvec_get_elf_backend_data(xvec) \ - ((const struct elf_backend_data *) (xvec)->backend_data) - -#define get_elf_backend_data(abfd) \ - xvec_get_elf_backend_data ((abfd)->xvec) - -/* The least object attributes (within an attributes subsection) known - for any target. Some code assumes that the value 0 is not used and - the field for that attribute can instead be used as a marker to - indicate that attributes have been initialized. */ -#define LEAST_KNOWN_OBJ_ATTRIBUTE 2 - -/* The maximum number of known object attributes for any target. */ -#define NUM_KNOWN_OBJ_ATTRIBUTES 71 - -/* The value of an object attribute. The type indicates whether the attribute - holds and integer, a string, or both. It can also indicate that there can - be no default (i.e. all values must be written to file, even zero). */ - -typedef struct obj_attribute -{ -#define ATTR_TYPE_FLAG_INT_VAL (1 << 0) -#define ATTR_TYPE_FLAG_STR_VAL (1 << 1) -#define ATTR_TYPE_FLAG_NO_DEFAULT (1 << 2) - -#define ATTR_TYPE_HAS_INT_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_INT_VAL) -#define ATTR_TYPE_HAS_STR_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_STR_VAL) -#define ATTR_TYPE_HAS_NO_DEFAULT(TYPE) ((TYPE) & ATTR_TYPE_FLAG_NO_DEFAULT) - - int type; - unsigned int i; - char *s; -} obj_attribute; - -typedef struct obj_attribute_list -{ - struct obj_attribute_list *next; - int tag; - obj_attribute attr; -} obj_attribute_list; - -/* Object attributes may either be defined by the processor ABI, index - OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific - (and possibly also processor-specific), index OBJ_ATTR_GNU. */ -#define OBJ_ATTR_PROC 0 -#define OBJ_ATTR_GNU 1 -#define OBJ_ATTR_FIRST OBJ_ATTR_PROC -#define OBJ_ATTR_LAST OBJ_ATTR_GNU - -/* The following object attribute tags are taken as generic, for all - targets and for "gnu" where there is no target standard. */ -enum -{ - Tag_NULL = 0, - Tag_File = 1, - Tag_Section = 2, - Tag_Symbol = 3, - Tag_compatibility = 32 -}; - -/* The following struct stores information about every SystemTap section - found in the object file. */ -struct sdt_note -{ - struct sdt_note *next; - bfd_size_type size; - bfd_byte data[1]; -}; - -/* Some private data is stashed away for future use using the tdata pointer - in the bfd structure. */ - -struct elf_obj_tdata -{ - Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */ - Elf_Internal_Shdr **elf_sect_ptr; - Elf_Internal_Phdr *phdr; - struct elf_segment_map *segment_map; - struct elf_strtab_hash *strtab_ptr; - int num_locals; - int num_globals; - unsigned int num_elf_sections; /* elf_sect_ptr size */ - int num_section_syms; - asymbol **section_syms; /* STT_SECTION symbols for each section */ - Elf_Internal_Shdr symtab_hdr; - Elf_Internal_Shdr shstrtab_hdr; - Elf_Internal_Shdr strtab_hdr; - Elf_Internal_Shdr dynsymtab_hdr; - Elf_Internal_Shdr dynstrtab_hdr; - Elf_Internal_Shdr dynversym_hdr; - Elf_Internal_Shdr dynverref_hdr; - Elf_Internal_Shdr dynverdef_hdr; - Elf_Internal_Shdr symtab_shndx_hdr; - unsigned int symtab_section, shstrtab_section; - unsigned int strtab_section, dynsymtab_section; - unsigned int symtab_shndx_section; - unsigned int dynversym_section, dynverdef_section, dynverref_section; - file_ptr next_file_pos; - bfd_vma gp; /* The gp value */ - unsigned int gp_size; /* The gp size */ - - /* Information grabbed from an elf core file. */ - int core_signal; - int core_pid; - int core_lwpid; - char* core_program; - char* core_command; - - /* A mapping from external symbols to entries in the linker hash - table, used when linking. This is indexed by the symbol index - minus the sh_info field of the symbol table header. */ - struct elf_link_hash_entry **sym_hashes; - - /* Track usage and final offsets of GOT entries for local symbols. - This array is indexed by symbol index. Elements are used - identically to "got" in struct elf_link_hash_entry. */ - union - { - bfd_signed_vma *refcounts; - bfd_vma *offsets; - struct got_entry **ents; - } local_got; - - /* The linker ELF emulation code needs to let the backend ELF linker - know what filename should be used for a dynamic object if the - dynamic object is found using a search. The emulation code then - sometimes needs to know what name was actually used. Until the - file has been added to the linker symbol table, this field holds - the name the linker wants. After it has been added, it holds the - name actually used, which will be the DT_SONAME entry if there is - one. */ - const char *dt_name; - - /* The linker emulation needs to know what audit libs - are used by a dynamic object. */ - const char *dt_audit; - - /* Records the result of `get_program_header_size'. */ - bfd_size_type program_header_size; - - /* Used by find_nearest_line entry point. */ - void *line_info; - - /* Used by MIPS ELF find_nearest_line entry point. The structure - could be included directly in this one, but there's no point to - wasting the memory just for the infrequently called - find_nearest_line. */ - struct mips_elf_find_line *find_line_info; - - /* A place to stash dwarf1 info for this bfd. */ - struct dwarf1_debug *dwarf1_find_line_info; - - /* A place to stash dwarf2 info for this bfd. */ - void *dwarf2_find_line_info; - - /* An array of stub sections indexed by symbol number, used by the - MIPS ELF linker. FIXME: We should figure out some way to only - include this field for a MIPS ELF target. */ - asection **local_stubs; - asection **local_call_stubs; - - /* Used to determine if PT_GNU_EH_FRAME segment header should be - created. */ - asection *eh_frame_hdr; - - Elf_Internal_Shdr **group_sect_ptr; - int num_group; - - /* Number of symbol version definitions we are about to emit. */ - unsigned int cverdefs; - - /* Number of symbol version references we are about to emit. */ - unsigned int cverrefs; - - /* Segment flags for the PT_GNU_STACK segment. */ - unsigned int stack_flags; - - /* Symbol version definitions in external objects. */ - Elf_Internal_Verdef *verdef; - - /* Symbol version references to external objects. */ - Elf_Internal_Verneed *verref; - - /* The Irix 5 support uses two virtual sections, which represent - text/data symbols defined in dynamic objects. */ - asymbol *elf_data_symbol; - asymbol *elf_text_symbol; - asection *elf_data_section; - asection *elf_text_section; - - /* A pointer to the .eh_frame section. */ - asection *eh_frame_section; - - /* Whether a dyanmic object was specified normally on the linker - command line, or was specified when --as-needed was in effect, - or was found via a DT_NEEDED entry. */ - enum dynamic_lib_link_class dyn_lib_class; - - /* This is set to TRUE if the object was created by the backend - linker. */ - bfd_boolean linker; - - /* Irix 5 often screws up the symbol table, sorting local symbols - after global symbols. This flag is set if the symbol table in - this BFD appears to be screwed up. If it is, we ignore the - sh_info field in the symbol table header, and always read all the - symbols. */ - bfd_boolean bad_symtab; - - /* Used to determine if the e_flags field has been initialized */ - bfd_boolean flags_init; - - /* Symbol buffer. */ - void *symbuf; - - obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES]; - obj_attribute_list *other_obj_attributes[2]; - - /* Called at the end of _bfd_elf_write_object_contents if not NULL. */ - bfd_boolean (*after_write_object_contents) (bfd *); - void *after_write_object_contents_info; - - /* NT_GNU_BUILD_ID note type. */ - bfd_size_type build_id_size; - bfd_byte *build_id; - - /* Linked-list containing information about every Systemtap section - found in the object file. Each section corresponds to one entry - in the list. */ - struct sdt_note *sdt_note_head; - - /* True if the bfd contains symbols that have the STT_GNU_IFUNC - symbol type or STB_GNU_UNIQUE binding. Used to set the osabi - field in the ELF header structure. */ - bfd_boolean has_gnu_symbols; - - /* An identifier used to distinguish different target - specific extensions to this structure. */ - enum elf_target_id object_id; -}; - -#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) - -#define elf_object_id(bfd) (elf_tdata(bfd) -> object_id) -#define elf_program_header_size(bfd) (elf_tdata(bfd) -> program_header_size) -#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) -#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) -#define elf_numsections(bfd) (elf_tdata(bfd) -> num_elf_sections) -#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) -#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) -#define elf_symtab_shndx(bfd) (elf_tdata(bfd) -> symtab_shndx_section) -#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr) -#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section) -#define elf_dynversym(bfd) (elf_tdata(bfd) -> dynversym_section) -#define elf_dynverdef(bfd) (elf_tdata(bfd) -> dynverdef_section) -#define elf_dynverref(bfd) (elf_tdata(bfd) -> dynverref_section) -#define elf_eh_frame_section(bfd) \ - (elf_tdata(bfd) -> eh_frame_section) -#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals) -#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals) -#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms) -#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms) -#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) -#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) -#define elf_gp(bfd) (elf_tdata(bfd) -> gp) -#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size) -#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes) -#define elf_local_got_refcounts(bfd) (elf_tdata(bfd) -> local_got.refcounts) -#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets) -#define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents) -#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name) -#define elf_dt_audit(bfd) (elf_tdata(bfd) -> dt_audit) -#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class) -#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) -#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init) -#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes) -#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes) -#define elf_known_obj_attributes_proc(bfd) \ - (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC]) -#define elf_other_obj_attributes_proc(bfd) \ - (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC]) - -extern void _bfd_elf_swap_verdef_in - (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *); -extern void _bfd_elf_swap_verdef_out - (bfd *, const Elf_Internal_Verdef *, Elf_External_Verdef *); -extern void _bfd_elf_swap_verdaux_in - (bfd *, const Elf_External_Verdaux *, Elf_Internal_Verdaux *); -extern void _bfd_elf_swap_verdaux_out - (bfd *, const Elf_Internal_Verdaux *, Elf_External_Verdaux *); -extern void _bfd_elf_swap_verneed_in - (bfd *, const Elf_External_Verneed *, Elf_Internal_Verneed *); -extern void _bfd_elf_swap_verneed_out - (bfd *, const Elf_Internal_Verneed *, Elf_External_Verneed *); -extern void _bfd_elf_swap_vernaux_in - (bfd *, const Elf_External_Vernaux *, Elf_Internal_Vernaux *); -extern void _bfd_elf_swap_vernaux_out - (bfd *, const Elf_Internal_Vernaux *, Elf_External_Vernaux *); -extern void _bfd_elf_swap_versym_in - (bfd *, const Elf_External_Versym *, Elf_Internal_Versym *); -extern void _bfd_elf_swap_versym_out - (bfd *, const Elf_Internal_Versym *, Elf_External_Versym *); - -extern unsigned int _bfd_elf_section_from_bfd_section - (bfd *, asection *); -extern char *bfd_elf_string_from_elf_section - (bfd *, unsigned, unsigned); -extern Elf_Internal_Sym *bfd_elf_get_elf_syms - (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *, - Elf_External_Sym_Shndx *); -extern const char *bfd_elf_sym_name - (bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, asection *); - -extern bfd_boolean _bfd_elf_copy_private_bfd_data - (bfd *, bfd *); -extern bfd_boolean _bfd_elf_print_private_bfd_data - (bfd *, void *); -extern void bfd_elf_print_symbol - (bfd *, void *, asymbol *, bfd_print_symbol_type); - -extern unsigned int _bfd_elf_eh_frame_address_size - (bfd *, asection *); -extern bfd_byte _bfd_elf_encode_eh_address - (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset, - asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded); -extern bfd_boolean _bfd_elf_can_make_relative - (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section); - -extern enum elf_reloc_type_class _bfd_elf_reloc_type_class - (const Elf_Internal_Rela *); -extern bfd_vma _bfd_elf_rela_local_sym - (bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *); -extern bfd_vma _bfd_elf_rel_local_sym - (bfd *, Elf_Internal_Sym *, asection **, bfd_vma); -extern bfd_vma _bfd_elf_section_offset - (bfd *, struct bfd_link_info *, asection *, bfd_vma); - -extern unsigned long bfd_elf_hash - (const char *); -extern unsigned long bfd_elf_gnu_hash - (const char *); - -extern bfd_reloc_status_type bfd_elf_generic_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -extern bfd_boolean bfd_elf_allocate_object - (bfd *, size_t, enum elf_target_id); -extern bfd_boolean bfd_elf_make_object - (bfd *); -extern bfd_boolean bfd_elf_mkcorefile - (bfd *); -extern bfd_boolean _bfd_elf_make_section_from_shdr - (bfd *, Elf_Internal_Shdr *, const char *, int); -extern bfd_boolean _bfd_elf_make_section_from_phdr - (bfd *, Elf_Internal_Phdr *, int, const char *); -extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create - (bfd *); -extern void _bfd_elf_link_hash_copy_indirect - (struct bfd_link_info *, struct elf_link_hash_entry *, - struct elf_link_hash_entry *); -extern void _bfd_elf_link_hash_hide_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); -extern bfd_boolean _bfd_elf_link_hash_fixup_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *); -extern bfd_boolean _bfd_elf_link_hash_table_init - (struct elf_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *), - unsigned int, enum elf_target_id); -extern bfd_boolean _bfd_elf_slurp_version_tables - (bfd *, bfd_boolean); -extern bfd_boolean _bfd_elf_merge_sections - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_match_sections_by_type - (bfd *, const asection *, bfd *, const asection *); -extern bfd_boolean bfd_elf_is_group_section - (bfd *, const struct bfd_section *); -extern bfd_boolean _bfd_elf_section_already_linked - (bfd *, asection *, struct bfd_link_info *); -extern void bfd_elf_set_group_contents - (bfd *, asection *, void *); -extern asection *_bfd_elf_check_kept_section - (asection *, struct bfd_link_info *); -extern void _bfd_elf_link_just_syms - (asection *, struct bfd_link_info *); -extern void _bfd_elf_copy_link_hash_symbol_type - (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); -extern bfd_boolean _bfd_elf_size_group_sections - (struct bfd_link_info *); -extern bfd_boolean _bfd_elf_fixup_group_sections -(bfd *, asection *); -extern bfd_boolean _bfd_elf_copy_private_header_data - (bfd *, bfd *); -extern bfd_boolean _bfd_elf_copy_private_symbol_data - (bfd *, asymbol *, bfd *, asymbol *); -#define _bfd_generic_init_private_section_data \ - _bfd_elf_init_private_section_data -extern bfd_boolean _bfd_elf_init_private_section_data - (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_copy_private_section_data - (bfd *, asection *, bfd *, asection *); -extern bfd_boolean _bfd_elf_write_object_contents - (bfd *); -extern bfd_boolean _bfd_elf_write_corefile_contents - (bfd *); -extern bfd_boolean _bfd_elf_set_section_contents - (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); -extern long _bfd_elf_get_symtab_upper_bound - (bfd *); -extern long _bfd_elf_canonicalize_symtab - (bfd *, asymbol **); -extern long _bfd_elf_get_dynamic_symtab_upper_bound - (bfd *); -extern long _bfd_elf_canonicalize_dynamic_symtab - (bfd *, asymbol **); -extern long _bfd_elf_get_synthetic_symtab - (bfd *, long, asymbol **, long, asymbol **, asymbol **); -extern long _bfd_elf_get_reloc_upper_bound - (bfd *, sec_ptr); -extern long _bfd_elf_canonicalize_reloc - (bfd *, sec_ptr, arelent **, asymbol **); -extern asection * _bfd_elf_get_dynamic_reloc_section - (bfd *, asection *, bfd_boolean); -extern asection * _bfd_elf_make_dynamic_reloc_section - (asection *, bfd *, unsigned int, bfd *, bfd_boolean); -extern long _bfd_elf_get_dynamic_reloc_upper_bound - (bfd *); -extern long _bfd_elf_canonicalize_dynamic_reloc - (bfd *, arelent **, asymbol **); -extern asymbol *_bfd_elf_make_empty_symbol - (bfd *); -extern void _bfd_elf_get_symbol_info - (bfd *, asymbol *, symbol_info *); -extern bfd_boolean _bfd_elf_is_local_label_name - (bfd *, const char *); -extern alent *_bfd_elf_get_lineno - (bfd *, asymbol *); -extern bfd_boolean _bfd_elf_set_arch_mach - (bfd *, enum bfd_architecture, unsigned long); -extern bfd_boolean _bfd_elf_find_nearest_line - (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, - unsigned int *); -extern bfd_boolean _bfd_elf_find_line - (bfd *, asymbol **, asymbol *, const char **, unsigned int *); -#define _bfd_generic_find_line _bfd_elf_find_line -extern bfd_boolean _bfd_elf_find_inliner_info - (bfd *, const char **, const char **, unsigned int *); -#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols -#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -extern int _bfd_elf_sizeof_headers - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_new_section_hook - (bfd *, asection *); -extern bfd_boolean _bfd_elf_init_reloc_shdr - (bfd *, struct bfd_elf_section_reloc_data *, asection *, bfd_boolean); -extern const struct bfd_elf_special_section *_bfd_elf_get_special_section - (const char *, const struct bfd_elf_special_section *, unsigned int); -extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr - (bfd *, asection *); - -/* If the target doesn't have reloc handling written yet: */ -extern void _bfd_elf_no_info_to_howto - (bfd *, arelent *, Elf_Internal_Rela *); - -extern bfd_boolean bfd_section_from_shdr - (bfd *, unsigned int shindex); -extern bfd_boolean bfd_section_from_phdr - (bfd *, Elf_Internal_Phdr *, int); - -extern int _bfd_elf_symbol_from_bfd_symbol - (bfd *, asymbol **); - -extern Elf_Internal_Sym *bfd_sym_from_r_symndx - (struct sym_cache *, bfd *, unsigned long); -extern asection *bfd_section_from_elf_index - (bfd *, unsigned int); -extern struct bfd_strtab_hash *_bfd_elf_stringtab_init - (void); - -extern struct elf_strtab_hash * _bfd_elf_strtab_init - (void); -extern void _bfd_elf_strtab_free - (struct elf_strtab_hash *); -extern bfd_size_type _bfd_elf_strtab_add - (struct elf_strtab_hash *, const char *, bfd_boolean); -extern void _bfd_elf_strtab_addref - (struct elf_strtab_hash *, bfd_size_type); -extern void _bfd_elf_strtab_delref - (struct elf_strtab_hash *, bfd_size_type); -extern void _bfd_elf_strtab_clear_all_refs - (struct elf_strtab_hash *); -extern bfd_size_type _bfd_elf_strtab_size - (struct elf_strtab_hash *); -extern bfd_size_type _bfd_elf_strtab_offset - (struct elf_strtab_hash *, bfd_size_type); -extern bfd_boolean _bfd_elf_strtab_emit - (bfd *, struct elf_strtab_hash *); -extern void _bfd_elf_strtab_finalize - (struct elf_strtab_hash *); - -extern void _bfd_elf_begin_eh_frame_parsing - (struct bfd_link_info *info); -extern void _bfd_elf_parse_eh_frame - (bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *); -extern void _bfd_elf_end_eh_frame_parsing - (struct bfd_link_info *info); - -extern bfd_boolean _bfd_elf_discard_section_eh_frame - (bfd *, struct bfd_link_info *, asection *, - bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *); -extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr - (bfd *, struct bfd_link_info *); -extern bfd_vma _bfd_elf_eh_frame_section_offset - (bfd *, struct bfd_link_info *, asection *, bfd_vma); -extern bfd_boolean _bfd_elf_write_section_eh_frame - (bfd *, struct bfd_link_info *, asection *, bfd_byte *); -extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr - (struct bfd_link_info *); - -extern bfd_boolean _bfd_elf_merge_symbol - (bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *, - asection **, bfd_vma *, unsigned int *, - struct elf_link_hash_entry **, bfd_boolean *, - bfd_boolean *, bfd_boolean *, bfd_boolean *); - -extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *); - -extern long _bfd_elf_link_lookup_local_dynindx - (struct bfd_link_info *, bfd *, long); -extern bfd_boolean _bfd_elf_compute_section_file_positions - (bfd *, struct bfd_link_info *); -extern void _bfd_elf_assign_file_positions_for_relocs - (bfd *); -extern file_ptr _bfd_elf_assign_file_position_for_section - (Elf_Internal_Shdr *, file_ptr, bfd_boolean); - -extern bfd_boolean _bfd_elf_validate_reloc - (bfd *, arelent *); - -extern bfd_boolean _bfd_elf_link_create_dynamic_sections - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_link_omit_section_dynsym - (bfd *, struct bfd_link_info *, asection *); -extern bfd_boolean _bfd_elf_create_dynamic_sections - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_create_got_section - (bfd *, struct bfd_link_info *); -extern struct elf_link_hash_entry *_bfd_elf_define_linkage_sym - (bfd *, struct bfd_link_info *, asection *, const char *); -extern void _bfd_elf_init_1_index_section - (bfd *, struct bfd_link_info *); -extern void _bfd_elf_init_2_index_sections - (bfd *, struct bfd_link_info *); - -extern bfd_boolean _bfd_elfcore_make_pseudosection - (bfd *, char *, size_t, ufile_ptr); -extern char *_bfd_elfcore_strndup - (bfd *, char *, size_t); - -extern Elf_Internal_Rela *_bfd_elf_link_read_relocs - (bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean); - -extern bfd_boolean _bfd_elf_link_output_relocs - (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, - struct elf_link_hash_entry **); - -extern bfd_boolean _bfd_elf_adjust_dynamic_copy - (struct elf_link_hash_entry *, asection *); - -extern bfd_boolean _bfd_elf_dynamic_symbol_p - (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); - -extern bfd_boolean _bfd_elf_symbol_refs_local_p - (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean); - -extern bfd_reloc_status_type bfd_elf_perform_complex_relocation - (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma); - -extern bfd_boolean _bfd_elf_setup_sections - (bfd *); - -extern void _bfd_elf_set_osabi (bfd * , struct bfd_link_info *); - -extern const bfd_target *bfd_elf32_object_p - (bfd *); -extern const bfd_target *bfd_elf32_core_file_p - (bfd *); -extern char *bfd_elf32_core_file_failing_command - (bfd *); -extern int bfd_elf32_core_file_failing_signal - (bfd *); -extern bfd_boolean bfd_elf32_core_file_matches_executable_p - (bfd *, bfd *); -extern int bfd_elf32_core_file_pid - (bfd *); - -extern bfd_boolean bfd_elf32_swap_symbol_in - (bfd *, const void *, const void *, Elf_Internal_Sym *); -extern void bfd_elf32_swap_symbol_out - (bfd *, const Elf_Internal_Sym *, void *, void *); -extern void bfd_elf32_swap_reloc_in - (bfd *, const bfd_byte *, Elf_Internal_Rela *); -extern void bfd_elf32_swap_reloc_out - (bfd *, const Elf_Internal_Rela *, bfd_byte *); -extern void bfd_elf32_swap_reloca_in - (bfd *, const bfd_byte *, Elf_Internal_Rela *); -extern void bfd_elf32_swap_reloca_out - (bfd *, const Elf_Internal_Rela *, bfd_byte *); -extern void bfd_elf32_swap_phdr_in - (bfd *, const Elf32_External_Phdr *, Elf_Internal_Phdr *); -extern void bfd_elf32_swap_phdr_out - (bfd *, const Elf_Internal_Phdr *, Elf32_External_Phdr *); -extern void bfd_elf32_swap_dyn_in - (bfd *, const void *, Elf_Internal_Dyn *); -extern void bfd_elf32_swap_dyn_out - (bfd *, const Elf_Internal_Dyn *, void *); -extern long bfd_elf32_slurp_symbol_table - (bfd *, asymbol **, bfd_boolean); -extern bfd_boolean bfd_elf32_write_shdrs_and_ehdr - (bfd *); -extern int bfd_elf32_write_out_phdrs - (bfd *, const Elf_Internal_Phdr *, unsigned int); -extern bfd_boolean bfd_elf32_checksum_contents - (bfd * , void (*) (const void *, size_t, void *), void *); -extern void bfd_elf32_write_relocs - (bfd *, asection *, void *); -extern bfd_boolean bfd_elf32_slurp_reloc_table - (bfd *, asection *, asymbol **, bfd_boolean); - -extern const bfd_target *bfd_elf64_object_p - (bfd *); -extern const bfd_target *bfd_elf64_core_file_p - (bfd *); -extern char *bfd_elf64_core_file_failing_command - (bfd *); -extern int bfd_elf64_core_file_failing_signal - (bfd *); -extern bfd_boolean bfd_elf64_core_file_matches_executable_p - (bfd *, bfd *); -extern int bfd_elf64_core_file_pid - (bfd *); - -extern bfd_boolean bfd_elf64_swap_symbol_in - (bfd *, const void *, const void *, Elf_Internal_Sym *); -extern void bfd_elf64_swap_symbol_out - (bfd *, const Elf_Internal_Sym *, void *, void *); -extern void bfd_elf64_swap_reloc_in - (bfd *, const bfd_byte *, Elf_Internal_Rela *); -extern void bfd_elf64_swap_reloc_out - (bfd *, const Elf_Internal_Rela *, bfd_byte *); -extern void bfd_elf64_swap_reloca_in - (bfd *, const bfd_byte *, Elf_Internal_Rela *); -extern void bfd_elf64_swap_reloca_out - (bfd *, const Elf_Internal_Rela *, bfd_byte *); -extern void bfd_elf64_swap_phdr_in - (bfd *, const Elf64_External_Phdr *, Elf_Internal_Phdr *); -extern void bfd_elf64_swap_phdr_out - (bfd *, const Elf_Internal_Phdr *, Elf64_External_Phdr *); -extern void bfd_elf64_swap_dyn_in - (bfd *, const void *, Elf_Internal_Dyn *); -extern void bfd_elf64_swap_dyn_out - (bfd *, const Elf_Internal_Dyn *, void *); -extern long bfd_elf64_slurp_symbol_table - (bfd *, asymbol **, bfd_boolean); -extern bfd_boolean bfd_elf64_write_shdrs_and_ehdr - (bfd *); -extern int bfd_elf64_write_out_phdrs - (bfd *, const Elf_Internal_Phdr *, unsigned int); -extern bfd_boolean bfd_elf64_checksum_contents - (bfd * , void (*) (const void *, size_t, void *), void *); -extern void bfd_elf64_write_relocs - (bfd *, asection *, void *); -extern bfd_boolean bfd_elf64_slurp_reloc_table - (bfd *, asection *, asymbol **, bfd_boolean); - -extern bfd_boolean _bfd_elf_default_relocs_compatible - (const bfd_target *, const bfd_target *); - -extern bfd_boolean _bfd_elf_relocs_compatible - (const bfd_target *, const bfd_target *); - -extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup - (bfd *, struct bfd_link_info *, const char *); -extern bfd_boolean bfd_elf_link_add_symbols - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf_add_dynamic_entry - (struct bfd_link_info *, bfd_vma, bfd_vma); - -extern bfd_boolean bfd_elf_link_record_dynamic_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *); - -extern int bfd_elf_link_record_local_dynamic_symbol - (struct bfd_link_info *, bfd *, long); - -extern bfd_boolean _bfd_elf_close_and_cleanup - (bfd *); - -extern bfd_boolean _bfd_elf_common_definition - (Elf_Internal_Sym *); - -extern unsigned int _bfd_elf_common_section_index - (asection *); - -extern asection *_bfd_elf_common_section - (asection *); - -extern void _bfd_dwarf2_cleanup_debug_info - (bfd *); - -extern bfd_vma _bfd_elf_default_got_elt_size -(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *, - unsigned long); - -extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn - (bfd *, arelent *, struct bfd_symbol *, void *, - asection *, bfd *, char **); - -extern bfd_boolean bfd_elf_final_link - (bfd *, struct bfd_link_info *); - -extern void _bfd_elf_gc_keep - (struct bfd_link_info *info); - -extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol - (struct elf_link_hash_entry *h, void *inf); - -extern bfd_boolean bfd_elf_gc_sections - (bfd *, struct bfd_link_info *); - -extern bfd_boolean bfd_elf_gc_record_vtinherit - (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); - -extern bfd_boolean bfd_elf_gc_record_vtentry - (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); - -extern asection *_bfd_elf_gc_mark_hook - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *); - -extern asection *_bfd_elf_gc_mark_rsec - (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn, - struct elf_reloc_cookie *); - -extern bfd_boolean _bfd_elf_gc_mark_reloc - (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn, - struct elf_reloc_cookie *); - -extern bfd_boolean _bfd_elf_gc_mark_fdes - (struct bfd_link_info *, asection *, asection *, elf_gc_mark_hook_fn, - struct elf_reloc_cookie *); - -extern bfd_boolean _bfd_elf_gc_mark - (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn); - -extern bfd_boolean _bfd_elf_gc_mark_extra_sections - (struct bfd_link_info *, elf_gc_mark_hook_fn); - -extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets - (bfd *, struct bfd_link_info *); - -extern bfd_boolean bfd_elf_gc_common_final_link - (bfd *, struct bfd_link_info *); - -extern bfd_boolean bfd_elf_reloc_symbol_deleted_p - (bfd_vma, void *); - -extern struct elf_segment_map * _bfd_elf_make_dynamic_segment - (bfd *, asection *); - -extern bfd_boolean _bfd_elf_map_sections_to_segments - (bfd *, struct bfd_link_info *); - -extern bfd_boolean _bfd_elf_is_function_type (unsigned int); - -extern int bfd_elf_get_default_section_type (flagword); - -extern void bfd_elf_lookup_section_flags - (struct bfd_link_info *, struct flag_info *); - -extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section - (bfd * abfd, asection * section); - -/* Exported interface for writing elf corefile notes. */ -extern char *elfcore_write_note - (bfd *, char *, int *, const char *, int, const void *, int); -extern char *elfcore_write_prpsinfo - (bfd *, char *, int *, const char *, const char *); -extern char *elfcore_write_prstatus - (bfd *, char *, int *, long, int, const void *); -extern char * elfcore_write_pstatus - (bfd *, char *, int *, long, int, const void *); -extern char *elfcore_write_prfpreg - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_prxfpreg - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_xstatereg - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_ppc_vmx - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_ppc_vsx - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_s390_timer - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_s390_todcmp - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_s390_todpreg - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_s390_ctrs - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_s390_prefix - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_arm_vfp - (bfd *, char *, int *, const void *, int); -extern char *elfcore_write_lwpstatus - (bfd *, char *, int *, long, int, const void *); -extern char *elfcore_write_register_note - (bfd *, char *, int *, const char *, const void *, int); - -extern bfd *_bfd_elf32_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma, bfd_byte *, int)); -extern bfd *_bfd_elf64_bfd_from_remote_memory - (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma, bfd_byte *, int)); - -extern bfd_vma bfd_elf_obj_attr_size (bfd *); -extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma); -extern int bfd_elf_get_obj_attr_int (bfd *, int, int); -extern void bfd_elf_add_obj_attr_int (bfd *, int, int, unsigned int); -#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \ - bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE)) -extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *); -#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \ - bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE)) -extern void bfd_elf_add_obj_attr_int_string (bfd *, int, int, unsigned int, - const char *); -#define bfd_elf_add_proc_attr_int_string(BFD, TAG, INTVAL, STRVAL) \ - bfd_elf_add_obj_attr_int_string ((BFD), OBJ_ATTR_PROC, (TAG), \ - (INTVAL), (STRVAL)) - -extern char *_bfd_elf_attr_strdup (bfd *, const char *); -extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *); -extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int); -extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *); -extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *); -extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int); -extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *); -extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec); - -/* The linker may need to keep track of the number of relocs that it - decides to copy as dynamic relocs in check_relocs for each symbol. - This is so that it can later discard them if they are found to be - unnecessary. We can store the information in a field extending the - regular ELF linker hash table. */ - -struct elf_dyn_relocs -{ - struct elf_dyn_relocs *next; - - /* The input section of the reloc. */ - asection *sec; - - /* Total number of relocs copied for the input section. */ - bfd_size_type count; - - /* Number of pc-relative relocs copied for the input section. */ - bfd_size_type pc_count; -}; - -extern bfd_boolean _bfd_elf_create_ifunc_sections - (bfd *, struct bfd_link_info *); -extern asection * _bfd_elf_create_ifunc_dyn_reloc - (bfd *, struct bfd_link_info *, asection *sec, asection *sreloc, - struct elf_dyn_relocs **); -extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs - (struct bfd_link_info *, struct elf_link_hash_entry *, - struct elf_dyn_relocs **, unsigned int, unsigned int); - -extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *); -extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *); - -extern bfd_vma elf64_r_info (bfd_vma, bfd_vma); -extern bfd_vma elf64_r_sym (bfd_vma); -extern bfd_vma elf32_r_info (bfd_vma, bfd_vma); -extern bfd_vma elf32_r_sym (bfd_vma); - -/* Large common section. */ -extern asection _bfd_elf_large_com_section; - -/* Hash for local symbol with the first section id, ID, in the input - file and the local symbol index, SYM. */ -#define ELF_LOCAL_SYMBOL_HASH(ID, SYM) \ - (((((ID) & 0xff) << 24) | (((ID) & 0xff00) << 8)) \ - ^ (SYM) ^ ((ID) >> 16)) - -/* This is the condition under which finish_dynamic_symbol will be called. - If our finish_dynamic_symbol isn't called, we'll need to do something - about initializing any .plt and .got entries in relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) || !(H)->forced_local) \ - && ((H)->dynindx != -1 || (H)->forced_local)) - -/* This macro is to avoid lots of duplicated code in the body - of xxx_relocate_section() in the various elfxx-xxxx.c files. */ -#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \ - r_symndx, symtab_hdr, sym_hashes, \ - h, sec, relocation, \ - unresolved_reloc, warned) \ - do \ - { \ - /* It seems this can happen with erroneous or unsupported \ - input (mixing a.out and elf in an archive, for example.) */ \ - if (sym_hashes == NULL) \ - return FALSE; \ - \ - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; \ - \ - while (h->root.type == bfd_link_hash_indirect \ - || h->root.type == bfd_link_hash_warning) \ - h = (struct elf_link_hash_entry *) h->root.u.i.link; \ - \ - warned = FALSE; \ - unresolved_reloc = FALSE; \ - relocation = 0; \ - if (h->root.type == bfd_link_hash_defined \ - || h->root.type == bfd_link_hash_defweak) \ - { \ - sec = h->root.u.def.section; \ - if (sec == NULL \ - || sec->output_section == NULL) \ - /* Set a flag that will be cleared later if we find a \ - relocation value for this symbol. output_section \ - is typically NULL for symbols satisfied by a shared \ - library. */ \ - unresolved_reloc = TRUE; \ - else \ - relocation = (h->root.u.def.value \ - + sec->output_section->vma \ - + sec->output_offset); \ - } \ - else if (h->root.type == bfd_link_hash_undefweak) \ - ; \ - else if (info->unresolved_syms_in_objects == RM_IGNORE \ - && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \ - ; \ - else if (!info->relocatable) \ - { \ - bfd_boolean err; \ - err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \ - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); \ - if (!info->callbacks->undefined_symbol (info, \ - h->root.root.string, \ - input_bfd, \ - input_section, \ - rel->r_offset, err)) \ - return FALSE; \ - warned = TRUE; \ - } \ - (void) unresolved_reloc; \ - (void) warned; \ - } \ - while (0) - -/* This macro is to avoid lots of duplicated code in the body of the - loop over relocations in xxx_relocate_section() in the various - elfxx-xxxx.c files. - - Handle relocations against symbols from removed linkonce sections, - or sections discarded by a linker script. When doing a relocatable - link, we remove such relocations. Otherwise, we just want the - section contents zeroed and avoid any special processing. */ -#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \ - rel, relend, howto, contents) \ - { \ - _bfd_clear_contents (howto, input_bfd, input_section, \ - contents + rel->r_offset); \ - \ - if (info->relocatable \ - && (input_section->flags & SEC_DEBUGGING)) \ - { \ - /* Only remove relocations in debug sections since other \ - sections may require relocations. */ \ - Elf_Internal_Shdr *rel_hdr; \ - \ - rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \ - \ - /* Avoid empty output section. */ \ - if (rel_hdr->sh_size > rel_hdr->sh_entsize) \ - { \ - rel_hdr->sh_size -= rel_hdr->sh_entsize; \ - rel_hdr = _bfd_elf_single_rel_hdr (input_section); \ - rel_hdr->sh_size -= rel_hdr->sh_entsize; \ - \ - memmove (rel, rel + 1, (relend - rel - 1) * sizeof (*rel)); \ - \ - input_section->reloc_count--; \ - relend--; \ - rel--; \ - continue; \ - } \ - } \ - \ - rel->r_info = 0; \ - rel->r_addend = 0; \ - continue; \ - } - -/* Will a symbol be bound to the the definition within the shared - library, if any. A unique symbol can never be bound locally. */ -#define SYMBOLIC_BIND(INFO, H) \ - (!(H)->unique_global \ - && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))) - -#endif /* _LIBELF_H_ */ diff --git a/contrib/binutils-2.22/bfd/elf-eh-frame.c b/contrib/binutils-2.22/bfd/elf-eh-frame.c deleted file mode 100644 index 54142b2952..0000000000 --- a/contrib/binutils-2.22/bfd/elf-eh-frame.c +++ /dev/null @@ -1,1873 +0,0 @@ -/* .eh_frame section optimization. - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Jakub Jelinek . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "dwarf2.h" - -#define EH_FRAME_HDR_SIZE 8 - -struct cie -{ - unsigned int length; - unsigned int hash; - unsigned char version; - unsigned char local_personality; - char augmentation[20]; - bfd_vma code_align; - bfd_signed_vma data_align; - bfd_vma ra_column; - bfd_vma augmentation_size; - union { - struct elf_link_hash_entry *h; - bfd_vma val; - unsigned int reloc_index; - } personality; - asection *output_sec; - struct eh_cie_fde *cie_inf; - unsigned char per_encoding; - unsigned char lsda_encoding; - unsigned char fde_encoding; - unsigned char initial_insn_length; - unsigned char can_make_lsda_relative; - unsigned char initial_instructions[50]; -}; - - - -/* If *ITER hasn't reached END yet, read the next byte into *RESULT and - move onto the next byte. Return true on success. */ - -static inline bfd_boolean -read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result) -{ - if (*iter >= end) - return FALSE; - *result = *((*iter)++); - return TRUE; -} - -/* Move *ITER over LENGTH bytes, or up to END, whichever is closer. - Return true it was possible to move LENGTH bytes. */ - -static inline bfd_boolean -skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length) -{ - if ((bfd_size_type) (end - *iter) < length) - { - *iter = end; - return FALSE; - } - *iter += length; - return TRUE; -} - -/* Move *ITER over an leb128, stopping at END. Return true if the end - of the leb128 was found. */ - -static bfd_boolean -skip_leb128 (bfd_byte **iter, bfd_byte *end) -{ - unsigned char byte; - do - if (!read_byte (iter, end, &byte)) - return FALSE; - while (byte & 0x80); - return TRUE; -} - -/* Like skip_leb128, but treat the leb128 as an unsigned value and - store it in *VALUE. */ - -static bfd_boolean -read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value) -{ - bfd_byte *start, *p; - - start = *iter; - if (!skip_leb128 (iter, end)) - return FALSE; - - p = *iter; - *value = *--p; - while (p > start) - *value = (*value << 7) | (*--p & 0x7f); - - return TRUE; -} - -/* Like read_uleb128, but for signed values. */ - -static bfd_boolean -read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value) -{ - bfd_byte *start, *p; - - start = *iter; - if (!skip_leb128 (iter, end)) - return FALSE; - - p = *iter; - *value = ((*--p & 0x7f) ^ 0x40) - 0x40; - while (p > start) - *value = (*value << 7) | (*--p & 0x7f); - - return TRUE; -} - -/* Return 0 if either encoding is variable width, or not yet known to bfd. */ - -static -int get_DW_EH_PE_width (int encoding, int ptr_size) -{ - /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame - was added to bfd. */ - if ((encoding & 0x60) == 0x60) - return 0; - - switch (encoding & 7) - { - case DW_EH_PE_udata2: return 2; - case DW_EH_PE_udata4: return 4; - case DW_EH_PE_udata8: return 8; - case DW_EH_PE_absptr: return ptr_size; - default: - break; - } - - return 0; -} - -#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0) - -/* Read a width sized value from memory. */ - -static bfd_vma -read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed) -{ - bfd_vma value; - - switch (width) - { - case 2: - if (is_signed) - value = bfd_get_signed_16 (abfd, buf); - else - value = bfd_get_16 (abfd, buf); - break; - case 4: - if (is_signed) - value = bfd_get_signed_32 (abfd, buf); - else - value = bfd_get_32 (abfd, buf); - break; - case 8: - if (is_signed) - value = bfd_get_signed_64 (abfd, buf); - else - value = bfd_get_64 (abfd, buf); - break; - default: - BFD_FAIL (); - return 0; - } - - return value; -} - -/* Store a width sized value to memory. */ - -static void -write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width) -{ - switch (width) - { - case 2: bfd_put_16 (abfd, value, buf); break; - case 4: bfd_put_32 (abfd, value, buf); break; - case 8: bfd_put_64 (abfd, value, buf); break; - default: BFD_FAIL (); - } -} - -/* Return one if C1 and C2 CIEs can be merged. */ - -static int -cie_eq (const void *e1, const void *e2) -{ - const struct cie *c1 = (const struct cie *) e1; - const struct cie *c2 = (const struct cie *) e2; - - if (c1->hash == c2->hash - && c1->length == c2->length - && c1->version == c2->version - && c1->local_personality == c2->local_personality - && strcmp (c1->augmentation, c2->augmentation) == 0 - && strcmp (c1->augmentation, "eh") != 0 - && c1->code_align == c2->code_align - && c1->data_align == c2->data_align - && c1->ra_column == c2->ra_column - && c1->augmentation_size == c2->augmentation_size - && memcmp (&c1->personality, &c2->personality, - sizeof (c1->personality)) == 0 - && c1->output_sec == c2->output_sec - && c1->per_encoding == c2->per_encoding - && c1->lsda_encoding == c2->lsda_encoding - && c1->fde_encoding == c2->fde_encoding - && c1->initial_insn_length == c2->initial_insn_length - && memcmp (c1->initial_instructions, - c2->initial_instructions, - c1->initial_insn_length) == 0) - return 1; - - return 0; -} - -static hashval_t -cie_hash (const void *e) -{ - const struct cie *c = (const struct cie *) e; - return c->hash; -} - -static hashval_t -cie_compute_hash (struct cie *c) -{ - hashval_t h = 0; - h = iterative_hash_object (c->length, h); - h = iterative_hash_object (c->version, h); - h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h); - h = iterative_hash_object (c->code_align, h); - h = iterative_hash_object (c->data_align, h); - h = iterative_hash_object (c->ra_column, h); - h = iterative_hash_object (c->augmentation_size, h); - h = iterative_hash_object (c->personality, h); - h = iterative_hash_object (c->output_sec, h); - h = iterative_hash_object (c->per_encoding, h); - h = iterative_hash_object (c->lsda_encoding, h); - h = iterative_hash_object (c->fde_encoding, h); - h = iterative_hash_object (c->initial_insn_length, h); - h = iterative_hash (c->initial_instructions, c->initial_insn_length, h); - c->hash = h; - return h; -} - -/* Return the number of extra bytes that we'll be inserting into - ENTRY's augmentation string. */ - -static INLINE unsigned int -extra_augmentation_string_bytes (struct eh_cie_fde *entry) -{ - unsigned int size = 0; - if (entry->cie) - { - if (entry->add_augmentation_size) - size++; - if (entry->u.cie.add_fde_encoding) - size++; - } - return size; -} - -/* Likewise ENTRY's augmentation data. */ - -static INLINE unsigned int -extra_augmentation_data_bytes (struct eh_cie_fde *entry) -{ - unsigned int size = 0; - if (entry->add_augmentation_size) - size++; - if (entry->cie && entry->u.cie.add_fde_encoding) - size++; - return size; -} - -/* Return the size that ENTRY will have in the output. ALIGNMENT is the - required alignment of ENTRY in bytes. */ - -static unsigned int -size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment) -{ - if (entry->removed) - return 0; - if (entry->size == 4) - return 4; - return (entry->size - + extra_augmentation_string_bytes (entry) - + extra_augmentation_data_bytes (entry) - + alignment - 1) & -alignment; -} - -/* Assume that the bytes between *ITER and END are CFA instructions. - Try to move *ITER past the first instruction and return true on - success. ENCODED_PTR_WIDTH gives the width of pointer entries. */ - -static bfd_boolean -skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width) -{ - bfd_byte op; - bfd_vma length; - - if (!read_byte (iter, end, &op)) - return FALSE; - - switch (op & 0xc0 ? op & 0xc0 : op) - { - case DW_CFA_nop: - case DW_CFA_advance_loc: - case DW_CFA_restore: - case DW_CFA_remember_state: - case DW_CFA_restore_state: - case DW_CFA_GNU_window_save: - /* No arguments. */ - return TRUE; - - case DW_CFA_offset: - case DW_CFA_restore_extended: - case DW_CFA_undefined: - case DW_CFA_same_value: - case DW_CFA_def_cfa_register: - case DW_CFA_def_cfa_offset: - case DW_CFA_def_cfa_offset_sf: - case DW_CFA_GNU_args_size: - /* One leb128 argument. */ - return skip_leb128 (iter, end); - - case DW_CFA_val_offset: - case DW_CFA_val_offset_sf: - case DW_CFA_offset_extended: - case DW_CFA_register: - case DW_CFA_def_cfa: - case DW_CFA_offset_extended_sf: - case DW_CFA_GNU_negative_offset_extended: - case DW_CFA_def_cfa_sf: - /* Two leb128 arguments. */ - return (skip_leb128 (iter, end) - && skip_leb128 (iter, end)); - - case DW_CFA_def_cfa_expression: - /* A variable-length argument. */ - return (read_uleb128 (iter, end, &length) - && skip_bytes (iter, end, length)); - - case DW_CFA_expression: - case DW_CFA_val_expression: - /* A leb128 followed by a variable-length argument. */ - return (skip_leb128 (iter, end) - && read_uleb128 (iter, end, &length) - && skip_bytes (iter, end, length)); - - case DW_CFA_set_loc: - return skip_bytes (iter, end, encoded_ptr_width); - - case DW_CFA_advance_loc1: - return skip_bytes (iter, end, 1); - - case DW_CFA_advance_loc2: - return skip_bytes (iter, end, 2); - - case DW_CFA_advance_loc4: - return skip_bytes (iter, end, 4); - - case DW_CFA_MIPS_advance_loc8: - return skip_bytes (iter, end, 8); - - default: - return FALSE; - } -} - -/* Try to interpret the bytes between BUF and END as CFA instructions. - If every byte makes sense, return a pointer to the first DW_CFA_nop - padding byte, or END if there is no padding. Return null otherwise. - ENCODED_PTR_WIDTH is as for skip_cfa_op. */ - -static bfd_byte * -skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width, - unsigned int *set_loc_count) -{ - bfd_byte *last; - - last = buf; - while (buf < end) - if (*buf == DW_CFA_nop) - buf++; - else - { - if (*buf == DW_CFA_set_loc) - ++*set_loc_count; - if (!skip_cfa_op (&buf, end, encoded_ptr_width)) - return 0; - last = buf; - } - return last; -} - -/* Convert absolute encoding ENCODING into PC-relative form. - SIZE is the size of a pointer. */ - -static unsigned char -make_pc_relative (unsigned char encoding, unsigned int ptr_size) -{ - if ((encoding & 0x7f) == DW_EH_PE_absptr) - switch (ptr_size) - { - case 2: - encoding |= DW_EH_PE_sdata2; - break; - case 4: - encoding |= DW_EH_PE_sdata4; - break; - case 8: - encoding |= DW_EH_PE_sdata8; - break; - } - return encoding | DW_EH_PE_pcrel; -} - -/* Called before calling _bfd_elf_parse_eh_frame on every input bfd's - .eh_frame section. */ - -void -_bfd_elf_begin_eh_frame_parsing (struct bfd_link_info *info) -{ - struct eh_frame_hdr_info *hdr_info; - - hdr_info = &elf_hash_table (info)->eh_info; - hdr_info->merge_cies = !info->relocatable; -} - -/* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the - information in the section's sec_info field on success. COOKIE - describes the relocations in SEC. */ - -void -_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, - asection *sec, struct elf_reloc_cookie *cookie) -{ -#define REQUIRE(COND) \ - do \ - if (!(COND)) \ - goto free_no_table; \ - while (0) - - bfd_byte *ehbuf = NULL, *buf, *end; - bfd_byte *last_fde; - struct eh_cie_fde *this_inf; - unsigned int hdr_length, hdr_id; - unsigned int cie_count; - struct cie *cie, *local_cies = NULL; - struct elf_link_hash_table *htab; - struct eh_frame_hdr_info *hdr_info; - struct eh_frame_sec_info *sec_info = NULL; - unsigned int ptr_size; - unsigned int num_cies; - unsigned int num_entries; - elf_gc_mark_hook_fn gc_mark_hook; - - htab = elf_hash_table (info); - hdr_info = &htab->eh_info; - if (hdr_info->parsed_eh_frames) - return; - - if (sec->size == 0 - || sec->sec_info_type != ELF_INFO_TYPE_NONE) - { - /* This file does not contain .eh_frame information. */ - return; - } - - if (bfd_is_abs_section (sec->output_section)) - { - /* At least one of the sections is being discarded from the - link, so we should just ignore them. */ - return; - } - - /* Read the frame unwind information from abfd. */ - - REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf)); - - if (sec->size >= 4 - && bfd_get_32 (abfd, ehbuf) == 0 - && cookie->rel == cookie->relend) - { - /* Empty .eh_frame section. */ - free (ehbuf); - return; - } - - /* If .eh_frame section size doesn't fit into int, we cannot handle - it (it would need to use 64-bit .eh_frame format anyway). */ - REQUIRE (sec->size == (unsigned int) sec->size); - - ptr_size = (get_elf_backend_data (abfd) - ->elf_backend_eh_frame_address_size (abfd, sec)); - REQUIRE (ptr_size != 0); - - /* Go through the section contents and work out how many FDEs and - CIEs there are. */ - buf = ehbuf; - end = ehbuf + sec->size; - num_cies = 0; - num_entries = 0; - while (buf != end) - { - num_entries++; - - /* Read the length of the entry. */ - REQUIRE (skip_bytes (&buf, end, 4)); - hdr_length = bfd_get_32 (abfd, buf - 4); - - /* 64-bit .eh_frame is not supported. */ - REQUIRE (hdr_length != 0xffffffff); - if (hdr_length == 0) - break; - - REQUIRE (skip_bytes (&buf, end, 4)); - hdr_id = bfd_get_32 (abfd, buf - 4); - if (hdr_id == 0) - num_cies++; - - REQUIRE (skip_bytes (&buf, end, hdr_length - 4)); - } - - sec_info = (struct eh_frame_sec_info *) - bfd_zmalloc (sizeof (struct eh_frame_sec_info) - + (num_entries - 1) * sizeof (struct eh_cie_fde)); - REQUIRE (sec_info); - - /* We need to have a "struct cie" for each CIE in this section. */ - local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies)); - REQUIRE (local_cies); - - /* FIXME: octets_per_byte. */ -#define ENSURE_NO_RELOCS(buf) \ - REQUIRE (!(cookie->rel < cookie->relend \ - && (cookie->rel->r_offset \ - < (bfd_size_type) ((buf) - ehbuf)) \ - && cookie->rel->r_info != 0)) - - /* FIXME: octets_per_byte. */ -#define SKIP_RELOCS(buf) \ - while (cookie->rel < cookie->relend \ - && (cookie->rel->r_offset \ - < (bfd_size_type) ((buf) - ehbuf))) \ - cookie->rel++ - - /* FIXME: octets_per_byte. */ -#define GET_RELOC(buf) \ - ((cookie->rel < cookie->relend \ - && (cookie->rel->r_offset \ - == (bfd_size_type) ((buf) - ehbuf))) \ - ? cookie->rel : NULL) - - buf = ehbuf; - cie_count = 0; - gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; - while ((bfd_size_type) (buf - ehbuf) != sec->size) - { - char *aug; - bfd_byte *start, *insns, *insns_end; - bfd_size_type length; - unsigned int set_loc_count; - - this_inf = sec_info->entry + sec_info->count; - last_fde = buf; - - /* Read the length of the entry. */ - REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4)); - hdr_length = bfd_get_32 (abfd, buf - 4); - - /* The CIE/FDE must be fully contained in this input section. */ - REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size); - end = buf + hdr_length; - - this_inf->offset = last_fde - ehbuf; - this_inf->size = 4 + hdr_length; - this_inf->reloc_index = cookie->rel - cookie->rels; - - if (hdr_length == 0) - { - /* A zero-length CIE should only be found at the end of - the section. */ - REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size); - ENSURE_NO_RELOCS (buf); - sec_info->count++; - break; - } - - REQUIRE (skip_bytes (&buf, end, 4)); - hdr_id = bfd_get_32 (abfd, buf - 4); - - if (hdr_id == 0) - { - unsigned int initial_insn_length; - - /* CIE */ - this_inf->cie = 1; - - /* Point CIE to one of the section-local cie structures. */ - cie = local_cies + cie_count++; - - cie->cie_inf = this_inf; - cie->length = hdr_length; - cie->output_sec = sec->output_section; - start = buf; - REQUIRE (read_byte (&buf, end, &cie->version)); - - /* Cannot handle unknown versions. */ - REQUIRE (cie->version == 1 - || cie->version == 3 - || cie->version == 4); - REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation)); - - strcpy (cie->augmentation, (char *) buf); - buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1; - ENSURE_NO_RELOCS (buf); - if (buf[0] == 'e' && buf[1] == 'h') - { - /* GCC < 3.0 .eh_frame CIE */ - /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__ - is private to each CIE, so we don't need it for anything. - Just skip it. */ - REQUIRE (skip_bytes (&buf, end, ptr_size)); - SKIP_RELOCS (buf); - } - if (cie->version >= 4) - { - REQUIRE (buf + 1 < end); - REQUIRE (buf[0] == ptr_size); - REQUIRE (buf[1] == 0); - buf += 2; - } - REQUIRE (read_uleb128 (&buf, end, &cie->code_align)); - REQUIRE (read_sleb128 (&buf, end, &cie->data_align)); - if (cie->version == 1) - { - REQUIRE (buf < end); - cie->ra_column = *buf++; - } - else - REQUIRE (read_uleb128 (&buf, end, &cie->ra_column)); - ENSURE_NO_RELOCS (buf); - cie->lsda_encoding = DW_EH_PE_omit; - cie->fde_encoding = DW_EH_PE_omit; - cie->per_encoding = DW_EH_PE_omit; - aug = cie->augmentation; - if (aug[0] != 'e' || aug[1] != 'h') - { - if (*aug == 'z') - { - aug++; - REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size)); - ENSURE_NO_RELOCS (buf); - } - - while (*aug != '\0') - switch (*aug++) - { - case 'L': - REQUIRE (read_byte (&buf, end, &cie->lsda_encoding)); - ENSURE_NO_RELOCS (buf); - REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size)); - break; - case 'R': - REQUIRE (read_byte (&buf, end, &cie->fde_encoding)); - ENSURE_NO_RELOCS (buf); - REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size)); - break; - case 'S': - break; - case 'P': - { - int per_width; - - REQUIRE (read_byte (&buf, end, &cie->per_encoding)); - per_width = get_DW_EH_PE_width (cie->per_encoding, - ptr_size); - REQUIRE (per_width); - if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned) - { - length = -(buf - ehbuf) & (per_width - 1); - REQUIRE (skip_bytes (&buf, end, length)); - } - this_inf->u.cie.personality_offset = buf - start; - ENSURE_NO_RELOCS (buf); - /* Ensure we have a reloc here. */ - REQUIRE (GET_RELOC (buf)); - cie->personality.reloc_index - = cookie->rel - cookie->rels; - /* Cope with MIPS-style composite relocations. */ - do - cookie->rel++; - while (GET_RELOC (buf) != NULL); - REQUIRE (skip_bytes (&buf, end, per_width)); - } - break; - default: - /* Unrecognized augmentation. Better bail out. */ - goto free_no_table; - } - } - - /* For shared libraries, try to get rid of as many RELATIVE relocs - as possible. */ - if (info->shared - && (get_elf_backend_data (abfd) - ->elf_backend_can_make_relative_eh_frame - (abfd, info, sec))) - { - if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr) - this_inf->make_relative = 1; - /* If the CIE doesn't already have an 'R' entry, it's fairly - easy to add one, provided that there's no aligned data - after the augmentation string. */ - else if (cie->fde_encoding == DW_EH_PE_omit - && (cie->per_encoding & 0x70) != DW_EH_PE_aligned) - { - if (*cie->augmentation == 0) - this_inf->add_augmentation_size = 1; - this_inf->u.cie.add_fde_encoding = 1; - this_inf->make_relative = 1; - } - - if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr) - cie->can_make_lsda_relative = 1; - } - - /* If FDE encoding was not specified, it defaults to - DW_EH_absptr. */ - if (cie->fde_encoding == DW_EH_PE_omit) - cie->fde_encoding = DW_EH_PE_absptr; - - initial_insn_length = end - buf; - if (initial_insn_length <= sizeof (cie->initial_instructions)) - { - cie->initial_insn_length = initial_insn_length; - memcpy (cie->initial_instructions, buf, initial_insn_length); - } - insns = buf; - buf += initial_insn_length; - ENSURE_NO_RELOCS (buf); - - if (hdr_info->merge_cies) - this_inf->u.cie.u.full_cie = cie; - this_inf->u.cie.per_encoding_relative - = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel; - } - else - { - /* Find the corresponding CIE. */ - unsigned int cie_offset = this_inf->offset + 4 - hdr_id; - for (cie = local_cies; cie < local_cies + cie_count; cie++) - if (cie_offset == cie->cie_inf->offset) - break; - - /* Ensure this FDE references one of the CIEs in this input - section. */ - REQUIRE (cie != local_cies + cie_count); - this_inf->u.fde.cie_inf = cie->cie_inf; - this_inf->make_relative = cie->cie_inf->make_relative; - this_inf->add_augmentation_size - = cie->cie_inf->add_augmentation_size; - - ENSURE_NO_RELOCS (buf); - if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL) - { - asection *rsec; - - REQUIRE (GET_RELOC (buf)); - - /* Chain together the FDEs for each section. */ - rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie); - /* RSEC will be NULL if FDE was cleared out as it was belonging to - a discarded SHT_GROUP. */ - if (rsec) - { - REQUIRE (rsec->owner == abfd); - this_inf->u.fde.next_for_section = elf_fde_list (rsec); - elf_fde_list (rsec) = this_inf; - } - } - - /* Skip the initial location and address range. */ - start = buf; - length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size); - REQUIRE (skip_bytes (&buf, end, 2 * length)); - - /* Skip the augmentation size, if present. */ - if (cie->augmentation[0] == 'z') - REQUIRE (read_uleb128 (&buf, end, &length)); - else - length = 0; - - /* Of the supported augmentation characters above, only 'L' - adds augmentation data to the FDE. This code would need to - be adjusted if any future augmentations do the same thing. */ - if (cie->lsda_encoding != DW_EH_PE_omit) - { - SKIP_RELOCS (buf); - if (cie->can_make_lsda_relative && GET_RELOC (buf)) - cie->cie_inf->u.cie.make_lsda_relative = 1; - this_inf->lsda_offset = buf - start; - /* If there's no 'z' augmentation, we don't know where the - CFA insns begin. Assume no padding. */ - if (cie->augmentation[0] != 'z') - length = end - buf; - } - - /* Skip over the augmentation data. */ - REQUIRE (skip_bytes (&buf, end, length)); - insns = buf; - - buf = last_fde + 4 + hdr_length; - - /* For NULL RSEC (cleared FDE belonging to a discarded section) - the relocations are commonly cleared. We do not sanity check if - all these relocations are cleared as (1) relocations to - .gcc_except_table will remain uncleared (they will get dropped - with the drop of this unused FDE) and (2) BFD already safely drops - relocations of any type to .eh_frame by - elf_section_ignore_discarded_relocs. - TODO: The .gcc_except_table entries should be also filtered as - .eh_frame entries; or GCC could rather use COMDAT for them. */ - SKIP_RELOCS (buf); - } - - /* Try to interpret the CFA instructions and find the first - padding nop. Shrink this_inf's size so that it doesn't - include the padding. */ - length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size); - set_loc_count = 0; - insns_end = skip_non_nops (insns, end, length, &set_loc_count); - /* If we don't understand the CFA instructions, we can't know - what needs to be adjusted there. */ - if (insns_end == NULL - /* For the time being we don't support DW_CFA_set_loc in - CIE instructions. */ - || (set_loc_count && this_inf->cie)) - goto free_no_table; - this_inf->size -= end - insns_end; - if (insns_end != end && this_inf->cie) - { - cie->initial_insn_length -= end - insns_end; - cie->length -= end - insns_end; - } - if (set_loc_count - && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel - || this_inf->make_relative)) - { - unsigned int cnt; - bfd_byte *p; - - this_inf->set_loc = (unsigned int *) - bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int)); - REQUIRE (this_inf->set_loc); - this_inf->set_loc[0] = set_loc_count; - p = insns; - cnt = 0; - while (p < end) - { - if (*p == DW_CFA_set_loc) - this_inf->set_loc[++cnt] = p + 1 - start; - REQUIRE (skip_cfa_op (&p, end, length)); - } - } - - this_inf->removed = 1; - this_inf->fde_encoding = cie->fde_encoding; - this_inf->lsda_encoding = cie->lsda_encoding; - sec_info->count++; - } - BFD_ASSERT (sec_info->count == num_entries); - BFD_ASSERT (cie_count == num_cies); - - elf_section_data (sec)->sec_info = sec_info; - sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME; - if (hdr_info->merge_cies) - { - sec_info->cies = local_cies; - local_cies = NULL; - } - goto success; - - free_no_table: - (*info->callbacks->einfo) - (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"), - abfd, sec); - hdr_info->table = FALSE; - if (sec_info) - free (sec_info); - success: - if (ehbuf) - free (ehbuf); - if (local_cies) - free (local_cies); -#undef REQUIRE -} - -/* Finish a pass over all .eh_frame sections. */ - -void -_bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info) -{ - struct eh_frame_hdr_info *hdr_info; - - hdr_info = &elf_hash_table (info)->eh_info; - hdr_info->parsed_eh_frames = TRUE; -} - -/* Mark all relocations against CIE or FDE ENT, which occurs in - .eh_frame section SEC. COOKIE describes the relocations in SEC; - its "rel" field can be changed freely. */ - -static bfd_boolean -mark_entry (struct bfd_link_info *info, asection *sec, - struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook, - struct elf_reloc_cookie *cookie) -{ - /* FIXME: octets_per_byte. */ - for (cookie->rel = cookie->rels + ent->reloc_index; - cookie->rel < cookie->relend - && cookie->rel->r_offset < ent->offset + ent->size; - cookie->rel++) - if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie)) - return FALSE; - - return TRUE; -} - -/* Mark all the relocations against FDEs that relate to code in input - section SEC. The FDEs belong to .eh_frame section EH_FRAME, whose - relocations are described by COOKIE. */ - -bfd_boolean -_bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec, - asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook, - struct elf_reloc_cookie *cookie) -{ - struct eh_cie_fde *fde, *cie; - - for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section) - { - if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie)) - return FALSE; - - /* At this stage, all cie_inf fields point to local CIEs, so we - can use the same cookie to refer to them. */ - cie = fde->u.fde.cie_inf; - if (!cie->u.cie.gc_mark) - { - cie->u.cie.gc_mark = 1; - if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie)) - return FALSE; - } - } - return TRUE; -} - -/* Input section SEC of ABFD is an .eh_frame section that contains the - CIE described by CIE_INF. Return a version of CIE_INF that is going - to be kept in the output, adding CIE_INF to the output if necessary. - - HDR_INFO is the .eh_frame_hdr information and COOKIE describes the - relocations in REL. */ - -static struct eh_cie_fde * -find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec, - struct eh_frame_hdr_info *hdr_info, - struct elf_reloc_cookie *cookie, - struct eh_cie_fde *cie_inf) -{ - unsigned long r_symndx; - struct cie *cie, *new_cie; - Elf_Internal_Rela *rel; - void **loc; - - /* Use CIE_INF if we have already decided to keep it. */ - if (!cie_inf->removed) - return cie_inf; - - /* If we have merged CIE_INF with another CIE, use that CIE instead. */ - if (cie_inf->u.cie.merged) - return cie_inf->u.cie.u.merged_with; - - cie = cie_inf->u.cie.u.full_cie; - - /* Assume we will need to keep CIE_INF. */ - cie_inf->removed = 0; - cie_inf->u.cie.u.sec = sec; - - /* If we are not merging CIEs, use CIE_INF. */ - if (cie == NULL) - return cie_inf; - - if (cie->per_encoding != DW_EH_PE_omit) - { - bfd_boolean per_binds_local; - - /* Work out the address of personality routine, either as an absolute - value or as a symbol. */ - rel = cookie->rels + cie->personality.reloc_index; - memset (&cie->personality, 0, sizeof (cie->personality)); -#ifdef BFD64 - if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) - r_symndx = ELF64_R_SYM (rel->r_info); - else -#endif - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx >= cookie->locsymcount - || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) - { - struct elf_link_hash_entry *h; - - r_symndx -= cookie->extsymoff; - h = cookie->sym_hashes[r_symndx]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - cie->personality.h = h; - per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h); - } - else - { - Elf_Internal_Sym *sym; - asection *sym_sec; - - sym = &cookie->locsyms[r_symndx]; - sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx); - if (sym_sec == NULL) - return cie_inf; - - if (sym_sec->kept_section != NULL) - sym_sec = sym_sec->kept_section; - if (sym_sec->output_section == NULL) - return cie_inf; - - cie->local_personality = 1; - cie->personality.val = (sym->st_value - + sym_sec->output_offset - + sym_sec->output_section->vma); - per_binds_local = TRUE; - } - - if (per_binds_local - && info->shared - && (cie->per_encoding & 0x70) == DW_EH_PE_absptr - && (get_elf_backend_data (abfd) - ->elf_backend_can_make_relative_eh_frame (abfd, info, sec))) - { - cie_inf->u.cie.make_per_encoding_relative = 1; - cie_inf->u.cie.per_encoding_relative = 1; - } - } - - /* See if we can merge this CIE with an earlier one. */ - cie->output_sec = sec->output_section; - cie_compute_hash (cie); - if (hdr_info->cies == NULL) - { - hdr_info->cies = htab_try_create (1, cie_hash, cie_eq, free); - if (hdr_info->cies == NULL) - return cie_inf; - } - loc = htab_find_slot_with_hash (hdr_info->cies, cie, cie->hash, INSERT); - if (loc == NULL) - return cie_inf; - - new_cie = (struct cie *) *loc; - if (new_cie == NULL) - { - /* Keep CIE_INF and record it in the hash table. */ - new_cie = (struct cie *) malloc (sizeof (struct cie)); - if (new_cie == NULL) - return cie_inf; - - memcpy (new_cie, cie, sizeof (struct cie)); - *loc = new_cie; - } - else - { - /* Merge CIE_INF with NEW_CIE->CIE_INF. */ - cie_inf->removed = 1; - cie_inf->u.cie.merged = 1; - cie_inf->u.cie.u.merged_with = new_cie->cie_inf; - if (cie_inf->u.cie.make_lsda_relative) - new_cie->cie_inf->u.cie.make_lsda_relative = 1; - } - return new_cie->cie_inf; -} - -/* This function is called for each input file before the .eh_frame - section is relocated. It discards duplicate CIEs and FDEs for discarded - functions. The function returns TRUE iff any entries have been - deleted. */ - -bfd_boolean -_bfd_elf_discard_section_eh_frame - (bfd *abfd, struct bfd_link_info *info, asection *sec, - bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *), - struct elf_reloc_cookie *cookie) -{ - struct eh_cie_fde *ent; - struct eh_frame_sec_info *sec_info; - struct eh_frame_hdr_info *hdr_info; - unsigned int ptr_size, offset; - - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) - return FALSE; - - sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; - if (sec_info == NULL) - return FALSE; - - ptr_size = (get_elf_backend_data (sec->owner) - ->elf_backend_eh_frame_address_size (sec->owner, sec)); - - hdr_info = &elf_hash_table (info)->eh_info; - for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) - if (ent->size == 4) - /* There should only be one zero terminator, on the last input - file supplying .eh_frame (crtend.o). Remove any others. */ - ent->removed = sec->map_head.s != NULL; - else if (!ent->cie) - { - bfd_boolean keep; - if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL) - { - unsigned int width - = get_DW_EH_PE_width (ent->fde_encoding, ptr_size); - bfd_vma value - = read_value (abfd, sec->contents + ent->offset + 8 + width, - width, get_DW_EH_PE_signed (ent->fde_encoding)); - keep = value != 0; - } - else - { - cookie->rel = cookie->rels + ent->reloc_index; - /* FIXME: octets_per_byte. */ - BFD_ASSERT (cookie->rel < cookie->relend - && cookie->rel->r_offset == ent->offset + 8); - keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie); - } - if (keep) - { - if (info->shared - && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr - && ent->make_relative == 0) - || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned)) - { - /* If a shared library uses absolute pointers - which we cannot turn into PC relative, - don't create the binary search table, - since it is affected by runtime relocations. */ - hdr_info->table = FALSE; - (*info->callbacks->einfo) - (_("%P: fde encoding in %B(%A) prevents .eh_frame_hdr" - " table being created.\n"), abfd, sec); - } - ent->removed = 0; - hdr_info->fde_count++; - ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info, - cookie, ent->u.fde.cie_inf); - } - } - - if (sec_info->cies) - { - free (sec_info->cies); - sec_info->cies = NULL; - } - - offset = 0; - for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) - if (!ent->removed) - { - ent->new_offset = offset; - offset += size_of_output_cie_fde (ent, ptr_size); - } - - sec->rawsize = sec->size; - sec->size = offset; - return offset != sec->rawsize; -} - -/* This function is called for .eh_frame_hdr section after - _bfd_elf_discard_section_eh_frame has been called on all .eh_frame - input sections. It finalizes the size of .eh_frame_hdr section. */ - -bfd_boolean -_bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) -{ - struct elf_link_hash_table *htab; - struct eh_frame_hdr_info *hdr_info; - asection *sec; - - htab = elf_hash_table (info); - hdr_info = &htab->eh_info; - - if (hdr_info->cies != NULL) - { - htab_delete (hdr_info->cies); - hdr_info->cies = NULL; - } - - sec = hdr_info->hdr_sec; - if (sec == NULL) - return FALSE; - - sec->size = EH_FRAME_HDR_SIZE; - if (hdr_info->table) - sec->size += 4 + hdr_info->fde_count * 8; - - elf_tdata (abfd)->eh_frame_hdr = sec; - return TRUE; -} - -/* This function is called from size_dynamic_sections. - It needs to decide whether .eh_frame_hdr should be output or not, - because when the dynamic symbol table has been sized it is too late - to strip sections. */ - -bfd_boolean -_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) -{ - asection *o; - bfd *abfd; - struct elf_link_hash_table *htab; - struct eh_frame_hdr_info *hdr_info; - - htab = elf_hash_table (info); - hdr_info = &htab->eh_info; - if (hdr_info->hdr_sec == NULL) - return TRUE; - - if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)) - { - hdr_info->hdr_sec = NULL; - return TRUE; - } - - abfd = NULL; - if (info->eh_frame_hdr) - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) - { - /* Count only sections which have at least a single CIE or FDE. - There cannot be any CIE or FDE <= 8 bytes. */ - o = bfd_get_section_by_name (abfd, ".eh_frame"); - if (o && o->size > 8 && !bfd_is_abs_section (o->output_section)) - break; - } - - if (abfd == NULL) - { - hdr_info->hdr_sec->flags |= SEC_EXCLUDE; - hdr_info->hdr_sec = NULL; - return TRUE; - } - - hdr_info->table = TRUE; - return TRUE; -} - -/* Adjust an address in the .eh_frame section. Given OFFSET within - SEC, this returns the new offset in the adjusted .eh_frame section, - or -1 if the address refers to a CIE/FDE which has been removed - or to offset with dynamic relocation which is no longer needed. */ - -bfd_vma -_bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - asection *sec, - bfd_vma offset) -{ - struct eh_frame_sec_info *sec_info; - unsigned int lo, hi, mid; - - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) - return offset; - sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; - - if (offset >= sec->rawsize) - return offset - sec->rawsize + sec->size; - - lo = 0; - hi = sec_info->count; - mid = 0; - while (lo < hi) - { - mid = (lo + hi) / 2; - if (offset < sec_info->entry[mid].offset) - hi = mid; - else if (offset - >= sec_info->entry[mid].offset + sec_info->entry[mid].size) - lo = mid + 1; - else - break; - } - - BFD_ASSERT (lo < hi); - - /* FDE or CIE was removed. */ - if (sec_info->entry[mid].removed) - return (bfd_vma) -1; - - /* If converting personality pointers to DW_EH_PE_pcrel, there will be - no need for run-time relocation against the personality field. */ - if (sec_info->entry[mid].cie - && sec_info->entry[mid].u.cie.make_per_encoding_relative - && offset == (sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].u.cie.personality_offset)) - return (bfd_vma) -2; - - /* If converting to DW_EH_PE_pcrel, there will be no need for run-time - relocation against FDE's initial_location field. */ - if (!sec_info->entry[mid].cie - && sec_info->entry[mid].make_relative - && offset == sec_info->entry[mid].offset + 8) - return (bfd_vma) -2; - - /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need - for run-time relocation against LSDA field. */ - if (!sec_info->entry[mid].cie - && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative - && offset == (sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].lsda_offset)) - return (bfd_vma) -2; - - /* If converting to DW_EH_PE_pcrel, there will be no need for run-time - relocation against DW_CFA_set_loc's arguments. */ - if (sec_info->entry[mid].set_loc - && sec_info->entry[mid].make_relative - && (offset >= sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].set_loc[1])) - { - unsigned int cnt; - - for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++) - if (offset == sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].set_loc[cnt]) - return (bfd_vma) -2; - } - - /* Any new augmentation bytes go before the first relocation. */ - return (offset + sec_info->entry[mid].new_offset - - sec_info->entry[mid].offset - + extra_augmentation_string_bytes (sec_info->entry + mid) - + extra_augmentation_data_bytes (sec_info->entry + mid)); -} - -/* Write out .eh_frame section. This is called with the relocated - contents. */ - -bfd_boolean -_bfd_elf_write_section_eh_frame (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - bfd_byte *contents) -{ - struct eh_frame_sec_info *sec_info; - struct elf_link_hash_table *htab; - struct eh_frame_hdr_info *hdr_info; - unsigned int ptr_size; - struct eh_cie_fde *ent; - - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) - /* FIXME: octets_per_byte. */ - return bfd_set_section_contents (abfd, sec->output_section, contents, - sec->output_offset, sec->size); - - ptr_size = (get_elf_backend_data (abfd) - ->elf_backend_eh_frame_address_size (abfd, sec)); - BFD_ASSERT (ptr_size != 0); - - sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; - htab = elf_hash_table (info); - hdr_info = &htab->eh_info; - - if (hdr_info->table && hdr_info->array == NULL) - hdr_info->array = (struct eh_frame_array_ent *) - bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array)); - if (hdr_info->array == NULL) - hdr_info = NULL; - - /* The new offsets can be bigger or smaller than the original offsets. - We therefore need to make two passes over the section: one backward - pass to move entries up and one forward pass to move entries down. - The two passes won't interfere with each other because entries are - not reordered */ - for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;) - if (!ent->removed && ent->new_offset > ent->offset) - memmove (contents + ent->new_offset, contents + ent->offset, ent->size); - - for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) - if (!ent->removed && ent->new_offset < ent->offset) - memmove (contents + ent->new_offset, contents + ent->offset, ent->size); - - for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent) - { - unsigned char *buf, *end; - unsigned int new_size; - - if (ent->removed) - continue; - - if (ent->size == 4) - { - /* Any terminating FDE must be at the end of the section. */ - BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1); - continue; - } - - buf = contents + ent->new_offset; - end = buf + ent->size; - new_size = size_of_output_cie_fde (ent, ptr_size); - - /* Update the size. It may be shrinked. */ - bfd_put_32 (abfd, new_size - 4, buf); - - /* Filling the extra bytes with DW_CFA_nops. */ - if (new_size != ent->size) - memset (end, 0, new_size - ent->size); - - if (ent->cie) - { - /* CIE */ - if (ent->make_relative - || ent->u.cie.make_lsda_relative - || ent->u.cie.per_encoding_relative) - { - char *aug; - unsigned int action, extra_string, extra_data; - unsigned int per_width, per_encoding; - - /* Need to find 'R' or 'L' augmentation's argument and modify - DW_EH_PE_* value. */ - action = ((ent->make_relative ? 1 : 0) - | (ent->u.cie.make_lsda_relative ? 2 : 0) - | (ent->u.cie.per_encoding_relative ? 4 : 0)); - extra_string = extra_augmentation_string_bytes (ent); - extra_data = extra_augmentation_data_bytes (ent); - - /* Skip length, id and version. */ - buf += 9; - aug = (char *) buf; - buf += strlen (aug) + 1; - skip_leb128 (&buf, end); - skip_leb128 (&buf, end); - skip_leb128 (&buf, end); - if (*aug == 'z') - { - /* The uleb128 will always be a single byte for the kind - of augmentation strings that we're prepared to handle. */ - *buf++ += extra_data; - aug++; - } - - /* Make room for the new augmentation string and data bytes. */ - memmove (buf + extra_string + extra_data, buf, end - buf); - memmove (aug + extra_string, aug, buf - (bfd_byte *) aug); - buf += extra_string; - end += extra_string + extra_data; - - if (ent->add_augmentation_size) - { - *aug++ = 'z'; - *buf++ = extra_data - 1; - } - if (ent->u.cie.add_fde_encoding) - { - BFD_ASSERT (action & 1); - *aug++ = 'R'; - *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size); - action &= ~1; - } - - while (action) - switch (*aug++) - { - case 'L': - if (action & 2) - { - BFD_ASSERT (*buf == ent->lsda_encoding); - *buf = make_pc_relative (*buf, ptr_size); - action &= ~2; - } - buf++; - break; - case 'P': - if (ent->u.cie.make_per_encoding_relative) - *buf = make_pc_relative (*buf, ptr_size); - per_encoding = *buf++; - per_width = get_DW_EH_PE_width (per_encoding, ptr_size); - BFD_ASSERT (per_width != 0); - BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel) - == ent->u.cie.per_encoding_relative); - if ((per_encoding & 0x70) == DW_EH_PE_aligned) - buf = (contents - + ((buf - contents + per_width - 1) - & ~((bfd_size_type) per_width - 1))); - if (action & 4) - { - bfd_vma val; - - val = read_value (abfd, buf, per_width, - get_DW_EH_PE_signed (per_encoding)); - if (ent->u.cie.make_per_encoding_relative) - val -= (sec->output_section->vma - + sec->output_offset - + (buf - contents)); - else - { - val += (bfd_vma) ent->offset - ent->new_offset; - val -= extra_string + extra_data; - } - write_value (abfd, buf, val, per_width); - action &= ~4; - } - buf += per_width; - break; - case 'R': - if (action & 1) - { - BFD_ASSERT (*buf == ent->fde_encoding); - *buf = make_pc_relative (*buf, ptr_size); - action &= ~1; - } - buf++; - break; - case 'S': - break; - default: - BFD_FAIL (); - } - } - } - else - { - /* FDE */ - bfd_vma value, address; - unsigned int width; - bfd_byte *start; - struct eh_cie_fde *cie; - - /* Skip length. */ - cie = ent->u.fde.cie_inf; - buf += 4; - value = ((ent->new_offset + sec->output_offset + 4) - - (cie->new_offset + cie->u.cie.u.sec->output_offset)); - bfd_put_32 (abfd, value, buf); - buf += 4; - width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size); - value = read_value (abfd, buf, width, - get_DW_EH_PE_signed (ent->fde_encoding)); - address = value; - if (value) - { - switch (ent->fde_encoding & 0x70) - { - case DW_EH_PE_textrel: - BFD_ASSERT (hdr_info == NULL); - break; - case DW_EH_PE_datarel: - { - switch (abfd->arch_info->arch) - { - case bfd_arch_ia64: - BFD_ASSERT (elf_gp (abfd) != 0); - address += elf_gp (abfd); - break; - default: - (*info->callbacks->einfo) - (_("%P: DW_EH_PE_datarel unspecified" - " for this architecture.\n")); - /* Fall thru */ - case bfd_arch_frv: - case bfd_arch_i386: - BFD_ASSERT (htab->hgot != NULL - && ((htab->hgot->root.type - == bfd_link_hash_defined) - || (htab->hgot->root.type - == bfd_link_hash_defweak))); - address - += (htab->hgot->root.u.def.value - + htab->hgot->root.u.def.section->output_offset - + (htab->hgot->root.u.def.section->output_section - ->vma)); - break; - } - } - break; - case DW_EH_PE_pcrel: - value += (bfd_vma) ent->offset - ent->new_offset; - address += (sec->output_section->vma - + sec->output_offset - + ent->offset + 8); - break; - } - if (ent->make_relative) - value -= (sec->output_section->vma - + sec->output_offset - + ent->new_offset + 8); - write_value (abfd, buf, value, width); - } - - start = buf; - - if (hdr_info) - { - /* The address calculation may overflow, giving us a - value greater than 4G on a 32-bit target when - dwarf_vma is 64-bit. */ - if (sizeof (address) > 4 && ptr_size == 4) - address &= 0xffffffff; - hdr_info->array[hdr_info->array_count].initial_loc = address; - hdr_info->array[hdr_info->array_count++].fde - = (sec->output_section->vma - + sec->output_offset - + ent->new_offset); - } - - if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel - || cie->u.cie.make_lsda_relative) - { - buf += ent->lsda_offset; - width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size); - value = read_value (abfd, buf, width, - get_DW_EH_PE_signed (ent->lsda_encoding)); - if (value) - { - if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel) - value += (bfd_vma) ent->offset - ent->new_offset; - else if (cie->u.cie.make_lsda_relative) - value -= (sec->output_section->vma - + sec->output_offset - + ent->new_offset + 8 + ent->lsda_offset); - write_value (abfd, buf, value, width); - } - } - else if (ent->add_augmentation_size) - { - /* Skip the PC and length and insert a zero byte for the - augmentation size. */ - buf += width * 2; - memmove (buf + 1, buf, end - buf); - *buf = 0; - } - - if (ent->set_loc) - { - /* Adjust DW_CFA_set_loc. */ - unsigned int cnt; - bfd_vma new_offset; - - width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size); - new_offset = ent->new_offset + 8 - + extra_augmentation_string_bytes (ent) - + extra_augmentation_data_bytes (ent); - - for (cnt = 1; cnt <= ent->set_loc[0]; cnt++) - { - buf = start + ent->set_loc[cnt]; - - value = read_value (abfd, buf, width, - get_DW_EH_PE_signed (ent->fde_encoding)); - if (!value) - continue; - - if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel) - value += (bfd_vma) ent->offset + 8 - new_offset; - if (ent->make_relative) - value -= (sec->output_section->vma - + sec->output_offset - + new_offset + ent->set_loc[cnt]); - write_value (abfd, buf, value, width); - } - } - } - } - - /* We don't align the section to its section alignment since the - runtime library only expects all CIE/FDE records aligned at - the pointer size. _bfd_elf_discard_section_eh_frame should - have padded CIE/FDE records to multiple of pointer size with - size_of_output_cie_fde. */ - if ((sec->size % ptr_size) != 0) - abort (); - - /* FIXME: octets_per_byte. */ - return bfd_set_section_contents (abfd, sec->output_section, - contents, (file_ptr) sec->output_offset, - sec->size); -} - -/* Helper function used to sort .eh_frame_hdr search table by increasing - VMA of FDE initial location. */ - -static int -vma_compare (const void *a, const void *b) -{ - const struct eh_frame_array_ent *p = (const struct eh_frame_array_ent *) a; - const struct eh_frame_array_ent *q = (const struct eh_frame_array_ent *) b; - if (p->initial_loc > q->initial_loc) - return 1; - if (p->initial_loc < q->initial_loc) - return -1; - return 0; -} - -/* Write out .eh_frame_hdr section. This must be called after - _bfd_elf_write_section_eh_frame has been called on all input - .eh_frame sections. - .eh_frame_hdr format: - ubyte version (currently 1) - ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of - .eh_frame section) - ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count - number (or DW_EH_PE_omit if there is no - binary search table computed)) - ubyte table_enc (DW_EH_PE_* encoding of binary search table, - or DW_EH_PE_omit if not present. - DW_EH_PE_datarel is using address of - .eh_frame_hdr section start as base) - [encoded] eh_frame_ptr (pointer to start of .eh_frame section) - optionally followed by: - [encoded] fde_count (total number of FDEs in .eh_frame section) - fde_count x [encoded] initial_loc, fde - (array of encoded pairs containing - FDE initial_location field and FDE address, - sorted by increasing initial_loc). */ - -bfd_boolean -_bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) -{ - struct elf_link_hash_table *htab; - struct eh_frame_hdr_info *hdr_info; - asection *sec; - bfd_byte *contents; - asection *eh_frame_sec; - bfd_size_type size; - bfd_boolean retval; - bfd_vma encoded_eh_frame; - - htab = elf_hash_table (info); - hdr_info = &htab->eh_info; - sec = hdr_info->hdr_sec; - if (sec == NULL) - return TRUE; - - size = EH_FRAME_HDR_SIZE; - if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) - size += 4 + hdr_info->fde_count * 8; - contents = (bfd_byte *) bfd_malloc (size); - if (contents == NULL) - return FALSE; - - eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame"); - if (eh_frame_sec == NULL) - { - free (contents); - return FALSE; - } - - memset (contents, 0, EH_FRAME_HDR_SIZE); - contents[0] = 1; /* Version. */ - contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address - (abfd, info, eh_frame_sec, 0, sec, 4, - &encoded_eh_frame); /* .eh_frame offset. */ - - if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) - { - contents[2] = DW_EH_PE_udata4; /* FDE count encoding. */ - contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc. */ - } - else - { - contents[2] = DW_EH_PE_omit; - contents[3] = DW_EH_PE_omit; - } - bfd_put_32 (abfd, encoded_eh_frame, contents + 4); - - if (contents[2] != DW_EH_PE_omit) - { - unsigned int i; - - bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE); - qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array), - vma_compare); - for (i = 0; i < hdr_info->fde_count; i++) - { - bfd_put_32 (abfd, - hdr_info->array[i].initial_loc - - sec->output_section->vma, - contents + EH_FRAME_HDR_SIZE + i * 8 + 4); - bfd_put_32 (abfd, - hdr_info->array[i].fde - sec->output_section->vma, - contents + EH_FRAME_HDR_SIZE + i * 8 + 8); - } - } - - /* FIXME: octets_per_byte. */ - retval = bfd_set_section_contents (abfd, sec->output_section, - contents, (file_ptr) sec->output_offset, - sec->size); - free (contents); - return retval; -} - -/* Return the width of FDE addresses. This is the default implementation. */ - -unsigned int -_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED) -{ - return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4; -} - -/* Decide whether we can use a PC-relative encoding within the given - EH frame section. This is the default implementation. */ - -bfd_boolean -_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - asection *eh_frame_section ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Select an encoding for the given address. Preference is given to - PC-relative addressing modes. */ - -bfd_byte -_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - asection *osec, bfd_vma offset, - asection *loc_sec, bfd_vma loc_offset, - bfd_vma *encoded) -{ - *encoded = osec->vma + offset - - (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset); - return DW_EH_PE_pcrel | DW_EH_PE_sdata4; -} diff --git a/contrib/binutils-2.22/bfd/elf-ifunc.c b/contrib/binutils-2.22/bfd/elf-ifunc.c deleted file mode 100644 index 3ba96c7961..0000000000 --- a/contrib/binutils-2.22/bfd/elf-ifunc.c +++ /dev/null @@ -1,323 +0,0 @@ -/* ELF STT_GNU_IFUNC support. - Copyright 2009 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" -#include "safe-ctype.h" -#include "libiberty.h" -#include "objalloc.h" - -/* Create sections needed by STT_GNU_IFUNC symbol. */ - -bfd_boolean -_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) -{ - flagword flags, pltflags; - asection *s; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_link_hash_table *htab = elf_hash_table (info); - - if (htab->irelifunc != NULL || htab->iplt != NULL) - return TRUE; - - flags = bed->dynamic_sec_flags; - pltflags = flags; - if (bed->plt_not_loaded) - /* We do not clear SEC_ALLOC here because we still want the OS to - allocate space for the section; it's just that there's nothing - to read in from the object file. */ - pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); - else - pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; - if (bed->plt_readonly) - pltflags |= SEC_READONLY; - - if (info->shared) - { - /* We need to create .rel[a].ifunc for shared objects. */ - const char *rel_sec = (bed->rela_plts_and_copies_p - ? ".rela.ifunc" : ".rel.ifunc"); - - s = bfd_make_section_with_flags (abfd, rel_sec, - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, - bed->s->log_file_align)) - return FALSE; - htab->irelifunc = s; - } - else - { - /* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt - for static executables. */ - s = bfd_make_section_with_flags (abfd, ".iplt", pltflags); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) - return FALSE; - htab->iplt = s; - - s = bfd_make_section_with_flags (abfd, - (bed->rela_plts_and_copies_p - ? ".rela.iplt" : ".rel.iplt"), - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, - bed->s->log_file_align)) - return FALSE; - htab->irelplt = s; - - /* We don't need the .igot section if we have the .igot.plt - section. */ - if (bed->want_got_plt) - s = bfd_make_section_with_flags (abfd, ".igot.plt", flags); - else - s = bfd_make_section_with_flags (abfd, ".igot", flags); - if (s == NULL - || !bfd_set_section_alignment (abfd, s, - bed->s->log_file_align)) - return FALSE; - htab->igotplt = s; - } - - return TRUE; -} - -/* For a STT_GNU_IFUNC symbol, create a dynamic reloc section, SRELOC, - for the input section, SEC, and append this reloc to HEAD. */ - -asection * -_bfd_elf_create_ifunc_dyn_reloc (bfd *abfd, struct bfd_link_info *info, - asection *sec, asection *sreloc, - struct elf_dyn_relocs **head) -{ - struct elf_dyn_relocs *p; - struct elf_link_hash_table *htab = elf_hash_table (info); - - if (sreloc == NULL) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (htab->dynobj == NULL) - htab->dynobj = abfd; - - sreloc = _bfd_elf_make_dynamic_reloc_section (sec, htab->dynobj, - bed->s->log_file_align, - abfd, - bed->rela_plts_and_copies_p); - if (sreloc == NULL) - return NULL; - } - - p = *head; - if (p == NULL || p->sec != sec) - { - bfd_size_type amt = sizeof *p; - - p = ((struct elf_dyn_relocs *) bfd_alloc (htab->dynobj, amt)); - if (p == NULL) - return NULL; - p->next = *head; - *head = p; - p->sec = sec; - p->count = 0; - p->pc_count = 0; - } - p->count += 1; - - return sreloc; -} - -/* Allocate space in .plt, .got and associated reloc sections for - dynamic relocs against a STT_GNU_IFUNC symbol definition. */ - -bfd_boolean -_bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, - struct elf_link_hash_entry *h, - struct elf_dyn_relocs **head, - unsigned int plt_entry_size, - unsigned int got_entry_size) -{ - asection *plt, *gotplt, *relplt; - struct elf_dyn_relocs *p; - unsigned int sizeof_reloc; - const struct elf_backend_data *bed; - struct elf_link_hash_table *htab; - - /* When a shared library references a STT_GNU_IFUNC symbol defined - in executable, the address of the resolved function may be used. - But in non-shared executable, the address of its .plt slot may - be used. Pointer equality may not work correctly. PIE should - be used if pointer equality is required here. */ - if (!info->shared - && (h->dynindx != -1 - || info->export_dynamic) - && h->pointer_equality_needed) - { - info->callbacks->einfo - (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer " - "equality in `%B' can not be used when making an " - "executable; recompile with -fPIE and relink with -pie\n"), - h->root.root.string, - h->root.u.def.section->owner); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - htab = elf_hash_table (info); - - /* Support garbage collection against STT_GNU_IFUNC symbols. */ - if (h->plt.refcount <= 0 && h->got.refcount <= 0) - { - /* When building shared library, we need to handle the case - where it is marked with regular reference, but not non-GOT - reference. It may happen if we didn't see STT_GNU_IFUNC - symbol at the time when checking relocations. */ - if (info->shared - && !h->non_got_ref - && h->ref_regular) - for (p = *head; p != NULL; p = p->next) - if (p->count) - { - h->non_got_ref = 1; - goto keep; - } - - h->got = htab->init_got_offset; - h->plt = htab->init_plt_offset; - *head = NULL; - return TRUE; - } - - /* Return and discard space for dynamic relocations against it if - it is never referenced in a non-shared object. */ - if (!h->ref_regular) - { - if (h->plt.refcount > 0 - || h->got.refcount > 0) - abort (); - h->got = htab->init_got_offset; - h->plt = htab->init_plt_offset; - *head = NULL; - return TRUE; - } - -keep: - bed = get_elf_backend_data (info->output_bfd); - if (bed->rela_plts_and_copies_p) - sizeof_reloc = bed->s->sizeof_rela; - else - sizeof_reloc = bed->s->sizeof_rel; - - /* When building a static executable, use .iplt, .igot.plt and - .rel[a].iplt sections for STT_GNU_IFUNC symbols. */ - if (htab->splt != NULL) - { - plt = htab->splt; - gotplt = htab->sgotplt; - relplt = htab->srelplt; - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (plt->size == 0) - plt->size += plt_entry_size; - } - else - { - plt = htab->iplt; - gotplt = htab->igotplt; - relplt = htab->irelplt; - } - - /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need - the original value for R_*_IRELATIVE. */ - h->plt.offset = plt->size; - - /* Make room for this entry in the .plt/.iplt section. */ - plt->size += plt_entry_size; - - /* We also need to make an entry in the .got.plt/.got.iplt section, - which will be placed in the .got section by the linker script. */ - gotplt->size += got_entry_size; - - /* We also need to make an entry in the .rel[a].plt/.rel[a].iplt - section. */ - relplt->size += sizeof_reloc; - relplt->reloc_count++; - - /* We need dynamic relocation for STT_GNU_IFUNC symbol only when - there is a non-GOT reference in a shared object. */ - if (!info->shared - || !h->non_got_ref) - *head = NULL; - - /* Finally, allocate space. */ - p = *head; - if (p != NULL) - { - bfd_size_type count = 0; - do - { - count += p->count; - p = p->next; - } - while (p != NULL); - htab->irelifunc->size += count * sizeof_reloc; - } - - /* For STT_GNU_IFUNC symbol, .got.plt has the real function address - and .got has the PLT entry adddress. We will load the GOT entry - with the PLT entry in finish_dynamic_symbol if it is used. For - branch, it uses .got.plt. For symbol value, - 1. Use .got.plt in a shared object if it is forced local or not - dynamic. - 2. Use .got.plt in a non-shared object if pointer equality isn't - needed. - 3. Use .got.plt in PIE. - 4. Use .got.plt if .got isn't used. - 5. Otherwise use .got so that it can be shared among different - objects at run-time. - We only need to relocate .got entry in shared object. */ - if (h->got.refcount <= 0 - || (info->shared - && (h->dynindx == -1 - || h->forced_local)) - || (!info->shared - && !h->pointer_equality_needed) - || (info->executable && info->shared) - || htab->sgot == NULL) - { - /* Use .got.plt. */ - h->got.offset = (bfd_vma) -1; - } - else - { - h->got.offset = htab->sgot->size; - htab->sgot->size += got_entry_size; - if (info->shared) - htab->srelgot->size += sizeof_reloc; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/elf-strtab.c b/contrib/binutils-2.22/bfd/elf-strtab.c deleted file mode 100644 index 7d2fad4e51..0000000000 --- a/contrib/binutils-2.22/bfd/elf-strtab.c +++ /dev/null @@ -1,395 +0,0 @@ -/* ELF strtab with GC and suffix merging support. - Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. - Written by Jakub Jelinek . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "hashtab.h" -#include "libiberty.h" - -/* An entry in the strtab hash table. */ - -struct elf_strtab_hash_entry -{ - struct bfd_hash_entry root; - /* Length of this entry. This includes the zero terminator. */ - int len; - unsigned int refcount; - union { - /* Index within the merged section. */ - bfd_size_type index; - /* Entry this is a suffix of (if len < 0). */ - struct elf_strtab_hash_entry *suffix; - } u; -}; - -/* The strtab hash table. */ - -struct elf_strtab_hash -{ - struct bfd_hash_table table; - /* Next available index. */ - bfd_size_type size; - /* Number of array entries alloced. */ - bfd_size_type alloced; - /* Final strtab size. */ - bfd_size_type sec_size; - /* Array of pointers to strtab entries. */ - struct elf_strtab_hash_entry **array; -}; - -/* Routine to create an entry in a section merge hashtab. */ - -static struct bfd_hash_entry * -elf_strtab_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct elf_strtab_hash_entry)); - if (entry == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - entry = bfd_hash_newfunc (entry, table, string); - - if (entry) - { - /* Initialize the local fields. */ - struct elf_strtab_hash_entry *ret; - - ret = (struct elf_strtab_hash_entry *) entry; - ret->u.index = -1; - ret->refcount = 0; - ret->len = 0; - } - - return entry; -} - -/* Create a new hash table. */ - -struct elf_strtab_hash * -_bfd_elf_strtab_init (void) -{ - struct elf_strtab_hash *table; - bfd_size_type amt = sizeof (struct elf_strtab_hash); - - table = (struct elf_strtab_hash *) bfd_malloc (amt); - if (table == NULL) - return NULL; - - if (!bfd_hash_table_init (&table->table, elf_strtab_hash_newfunc, - sizeof (struct elf_strtab_hash_entry))) - { - free (table); - return NULL; - } - - table->sec_size = 0; - table->size = 1; - table->alloced = 64; - amt = sizeof (struct elf_strtab_hasn_entry *); - table->array = (struct elf_strtab_hash_entry **) - bfd_malloc (table->alloced * amt); - if (table->array == NULL) - { - free (table); - return NULL; - } - - table->array[0] = NULL; - - return table; -} - -/* Free a strtab. */ - -void -_bfd_elf_strtab_free (struct elf_strtab_hash *tab) -{ - bfd_hash_table_free (&tab->table); - free (tab->array); - free (tab); -} - -/* Get the index of an entity in a hash table, adding it if it is not - already present. */ - -bfd_size_type -_bfd_elf_strtab_add (struct elf_strtab_hash *tab, - const char *str, - bfd_boolean copy) -{ - register struct elf_strtab_hash_entry *entry; - - /* We handle this specially, since we don't want to do refcounting - on it. */ - if (*str == '\0') - return 0; - - BFD_ASSERT (tab->sec_size == 0); - entry = (struct elf_strtab_hash_entry *) - bfd_hash_lookup (&tab->table, str, TRUE, copy); - - if (entry == NULL) - return (bfd_size_type) -1; - - entry->refcount++; - if (entry->len == 0) - { - entry->len = strlen (str) + 1; - /* 2G strings lose. */ - BFD_ASSERT (entry->len > 0); - if (tab->size == tab->alloced) - { - bfd_size_type amt = sizeof (struct elf_strtab_hash_entry *); - tab->alloced *= 2; - tab->array = (struct elf_strtab_hash_entry **) - bfd_realloc_or_free (tab->array, tab->alloced * amt); - if (tab->array == NULL) - return (bfd_size_type) -1; - } - - entry->u.index = tab->size++; - tab->array[entry->u.index] = entry; - } - return entry->u.index; -} - -void -_bfd_elf_strtab_addref (struct elf_strtab_hash *tab, bfd_size_type idx) -{ - if (idx == 0 || idx == (bfd_size_type) -1) - return; - BFD_ASSERT (tab->sec_size == 0); - BFD_ASSERT (idx < tab->size); - ++tab->array[idx]->refcount; -} - -void -_bfd_elf_strtab_delref (struct elf_strtab_hash *tab, bfd_size_type idx) -{ - if (idx == 0 || idx == (bfd_size_type) -1) - return; - BFD_ASSERT (tab->sec_size == 0); - BFD_ASSERT (idx < tab->size); - BFD_ASSERT (tab->array[idx]->refcount > 0); - --tab->array[idx]->refcount; -} - -void -_bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab) -{ - bfd_size_type idx; - - for (idx = 1; idx < tab->size; ++idx) - tab->array[idx]->refcount = 0; -} - -bfd_size_type -_bfd_elf_strtab_size (struct elf_strtab_hash *tab) -{ - return tab->sec_size ? tab->sec_size : tab->size; -} - -bfd_size_type -_bfd_elf_strtab_offset (struct elf_strtab_hash *tab, bfd_size_type idx) -{ - struct elf_strtab_hash_entry *entry; - - if (idx == 0) - return 0; - BFD_ASSERT (idx < tab->size); - BFD_ASSERT (tab->sec_size); - entry = tab->array[idx]; - BFD_ASSERT (entry->refcount > 0); - entry->refcount--; - return tab->array[idx]->u.index; -} - -bfd_boolean -_bfd_elf_strtab_emit (register bfd *abfd, struct elf_strtab_hash *tab) -{ - bfd_size_type off = 1, i; - - if (bfd_bwrite ("", 1, abfd) != 1) - return FALSE; - - for (i = 1; i < tab->size; ++i) - { - register const char *str; - register unsigned int len; - - BFD_ASSERT (tab->array[i]->refcount == 0); - len = tab->array[i]->len; - if ((int) len < 0) - continue; - - str = tab->array[i]->root.string; - if (bfd_bwrite (str, len, abfd) != len) - return FALSE; - - off += len; - } - - BFD_ASSERT (off == tab->sec_size); - return TRUE; -} - -/* Compare two elf_strtab_hash_entry structures. Called via qsort. */ - -static int -strrevcmp (const void *a, const void *b) -{ - struct elf_strtab_hash_entry *A = *(struct elf_strtab_hash_entry **) a; - struct elf_strtab_hash_entry *B = *(struct elf_strtab_hash_entry **) b; - unsigned int lenA = A->len; - unsigned int lenB = B->len; - const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1; - const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1; - int l = lenA < lenB ? lenA : lenB; - - while (l) - { - if (*s != *t) - return (int) *s - (int) *t; - s--; - t--; - l--; - } - return lenA - lenB; -} - -static inline int -is_suffix (const struct elf_strtab_hash_entry *A, - const struct elf_strtab_hash_entry *B) -{ - if (A->len <= B->len) - /* B cannot be a suffix of A unless A is equal to B, which is guaranteed - not to be equal by the hash table. */ - return 0; - - return memcmp (A->root.string + (A->len - B->len), - B->root.string, B->len - 1) == 0; -} - -/* This function assigns final string table offsets for used strings, - merging strings matching suffixes of longer strings if possible. */ - -void -_bfd_elf_strtab_finalize (struct elf_strtab_hash *tab) -{ - struct elf_strtab_hash_entry **array, **a, *e; - bfd_size_type size, amt; - - /* GCC 2.91.66 (egcs-1.1.2) on i386 miscompiles this function when i is - a 64-bit bfd_size_type: a 64-bit target or --enable-64-bit-bfd. - Besides, indexing with a long long wouldn't give anything but extra - cycles. */ - size_t i; - - /* Sort the strings by suffix and length. */ - amt = tab->size * sizeof (struct elf_strtab_hash_entry *); - array = (struct elf_strtab_hash_entry **) bfd_malloc (amt); - if (array == NULL) - goto alloc_failure; - - for (i = 1, a = array; i < tab->size; ++i) - { - e = tab->array[i]; - if (e->refcount) - { - *a++ = e; - /* Adjust the length to not include the zero terminator. */ - e->len -= 1; - } - else - e->len = 0; - } - - size = a - array; - if (size != 0) - { - qsort (array, size, sizeof (struct elf_strtab_hash_entry *), strrevcmp); - - /* Loop over the sorted array and merge suffixes. Start from the - end because we want eg. - - s1 -> "d" - s2 -> "bcd" - s3 -> "abcd" - - to end up as - - s3 -> "abcd" - s2 _____^ - s1 _______^ - - ie. we don't want s1 pointing into the old s2. */ - e = *--a; - e->len += 1; - while (--a >= array) - { - struct elf_strtab_hash_entry *cmp = *a; - - cmp->len += 1; - if (is_suffix (e, cmp)) - { - cmp->u.suffix = e; - cmp->len = -cmp->len; - } - else - e = cmp; - } - } - -alloc_failure: - if (array) - free (array); - - /* Assign positions to the strings we want to keep. */ - size = 1; - for (i = 1; i < tab->size; ++i) - { - e = tab->array[i]; - if (e->refcount && e->len > 0) - { - e->u.index = size; - size += e->len; - } - } - - tab->sec_size = size; - - /* Adjust the rest. */ - for (i = 1; i < tab->size; ++i) - { - e = tab->array[i]; - if (e->refcount && e->len < 0) - e->u.index = e->u.suffix->u.index + (e->u.suffix->len + e->len); - } -} diff --git a/contrib/binutils-2.22/bfd/elf-vxworks.c b/contrib/binutils-2.22/bfd/elf-vxworks.c deleted file mode 100644 index 06edf8dce6..0000000000 --- a/contrib/binutils-2.22/bfd/elf-vxworks.c +++ /dev/null @@ -1,299 +0,0 @@ -/* VxWorks support for ELF - Copyright 2005, 2006, 2007, 2009 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. */ - -/* This file provides routines used by all VxWorks targets. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf-vxworks.h" -#include "elf/vxworks.h" - -/* Return true if symbol NAME, as defined by ABFD, is one of the special - __GOTT_BASE__ or __GOTT_INDEX__ symbols. */ - -static bfd_boolean -elf_vxworks_gott_symbol_p (bfd *abfd, const char *name) -{ - char leading; - - leading = bfd_get_symbol_leading_char (abfd); - if (leading) - { - if (*name != leading) - return FALSE; - name++; - } - return (strcmp (name, "__GOTT_BASE__") == 0 - || strcmp (name, "__GOTT_INDEX__") == 0); -} - -/* Tweak magic VxWorks symbols as they are loaded. */ -bfd_boolean -elf_vxworks_add_symbol_hook (bfd *abfd, - struct bfd_link_info *info, - Elf_Internal_Sym *sym, - const char **namep, - flagword *flagsp, - asection **secp ATTRIBUTE_UNUSED, - bfd_vma *valp ATTRIBUTE_UNUSED) -{ - /* Ideally these "magic" symbols would be exported by libc.so.1 - which would be found via a DT_NEEDED tag, and then handled - specially by the linker at runtime. Except shared libraries - don't even link to libc.so.1 by default... - If the symbol is imported from, or will be put in a shared library, - give the symbol weak binding to get the desired samantics. - This transformation will be undone in - elf_i386_vxworks_link_output_symbol_hook. */ - if ((info->shared || abfd->flags & DYNAMIC) - && elf_vxworks_gott_symbol_p (abfd, *namep)) - { - sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info)); - *flagsp |= BSF_WEAK; - } - - return TRUE; -} - -/* Perform VxWorks-specific handling of the create_dynamic_sections hook. - When creating an executable, set *SRELPLT2_OUT to the .rel(a).plt.unloaded - section. */ - -bfd_boolean -elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info, - asection **srelplt2_out) -{ - struct elf_link_hash_table *htab; - const struct elf_backend_data *bed; - asection *s; - - htab = elf_hash_table (info); - bed = get_elf_backend_data (dynobj); - - if (!info->shared) - { - s = bfd_make_section_with_flags (dynobj, - bed->default_use_rela_p - ? ".rela.plt.unloaded" - : ".rel.plt.unloaded", - SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY | SEC_LINKER_CREATED); - if (s == NULL - || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align)) - return FALSE; - - *srelplt2_out = s; - } - - /* Mark the GOT and PLT symbols as having relocations; they might - not, but we won't know for sure until we build the GOT in - finish_dynamic_symbol. Also make sure that the GOT symbol - is entered into the dynamic symbol table; the loader uses it - to initialize __GOTT_BASE__[__GOTT_INDEX__]. */ - if (htab->hgot) - { - htab->hgot->indx = -2; - htab->hgot->other &= ~ELF_ST_VISIBILITY (-1); - htab->hgot->forced_local = 0; - if (!bfd_elf_link_record_dynamic_symbol (info, htab->hgot)) - return FALSE; - } - if (htab->hplt) - { - htab->hplt->indx = -2; - htab->hplt->type = STT_FUNC; - } - - return TRUE; -} - -/* Tweak magic VxWorks symbols as they are written to the output file. */ -int -elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info - ATTRIBUTE_UNUSED, - const char *name, - Elf_Internal_Sym *sym, - asection *input_sec ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h) -{ - /* Reverse the effects of the hack in elf_vxworks_add_symbol_hook. */ - if (h - && h->root.type == bfd_link_hash_undefweak - && elf_vxworks_gott_symbol_p (h->root.u.undef.abfd, name)) - sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info)); - - return 1; -} - -/* Copy relocations into the output file. Fixes up relocations against PLT - entries, then calls the generic routine. */ - -bfd_boolean -elf_vxworks_emit_relocs (bfd *output_bfd, - asection *input_section, - Elf_Internal_Shdr *input_rel_hdr, - Elf_Internal_Rela *internal_relocs, - struct elf_link_hash_entry **rel_hash) -{ - const struct elf_backend_data *bed; - int j; - - bed = get_elf_backend_data (output_bfd); - - if (output_bfd->flags & (DYNAMIC|EXEC_P)) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - struct elf_link_hash_entry **hash_ptr; - - for (irela = internal_relocs, - irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) - * bed->s->int_rels_per_ext_rel), - hash_ptr = rel_hash; - irela < irelaend; - irela += bed->s->int_rels_per_ext_rel, - hash_ptr++) - { - if (*hash_ptr - && (*hash_ptr)->def_dynamic - && !(*hash_ptr)->def_regular - && ((*hash_ptr)->root.type == bfd_link_hash_defined - || (*hash_ptr)->root.type == bfd_link_hash_defweak) - && (*hash_ptr)->root.u.def.section->output_section != NULL) - { - /* This is a relocation from an executable or shared - library against a symbol in a different shared - library. We are creating a definition in the output - file but it does not come from any of our normal (.o) - files. ie. a PLT stub. Normally this would be a - relocation against against SHN_UNDEF with the VMA of - the PLT stub. This upsets the VxWorks loader. - Convert it to a section-relative relocation. This - gets some other symbols (for instance .dynbss), but - is conservatively correct. */ - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) - { - asection *sec = (*hash_ptr)->root.u.def.section; - int this_idx = sec->output_section->target_index; - - irela[j].r_info - = ELF32_R_INFO (this_idx, ELF32_R_TYPE (irela[j].r_info)); - irela[j].r_addend += (*hash_ptr)->root.u.def.value; - irela[j].r_addend += sec->output_offset; - } - /* Stop the generic routine adjusting this entry. */ - *hash_ptr = NULL; - } - } - } - return _bfd_elf_link_output_relocs (output_bfd, input_section, - input_rel_hdr, internal_relocs, - rel_hash); -} - - -/* Set the sh_link and sh_info fields on the static plt relocation secton. */ - -void -elf_vxworks_final_write_processing (bfd *abfd, - bfd_boolean linker ATTRIBUTE_UNUSED) -{ - asection * sec; - struct bfd_elf_section_data *d; - - sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded"); - if (!sec) - sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded"); - if (!sec) - return; - d = elf_section_data (sec); - d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section; - sec = bfd_get_section_by_name (abfd, ".plt"); - if (sec) - d->this_hdr.sh_info = elf_section_data (sec)->this_idx; -} - -/* Add the dynamic entries required by VxWorks. These point to the - tls sections. */ - -bfd_boolean -elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info) -{ - if (bfd_get_section_by_name (output_bfd, ".tls_data")) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0)) - return FALSE; - } - if (bfd_get_section_by_name (output_bfd, ".tls_vars")) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0)) - return FALSE; - } - return TRUE; -} - -/* If *DYN is one of the VxWorks-specific dynamic entries, then fill - in the value now and return TRUE. Otherwise return FALSE. */ - -bfd_boolean -elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn) -{ - asection *sec; - - switch (dyn->d_tag) - { - default: - return FALSE; - - case DT_VX_WRS_TLS_DATA_START: - sec = bfd_get_section_by_name (output_bfd, ".tls_data"); - dyn->d_un.d_ptr = sec->vma; - break; - - case DT_VX_WRS_TLS_DATA_SIZE: - sec = bfd_get_section_by_name (output_bfd, ".tls_data"); - dyn->d_un.d_val = sec->size; - break; - - case DT_VX_WRS_TLS_DATA_ALIGN: - sec = bfd_get_section_by_name (output_bfd, ".tls_data"); - dyn->d_un.d_val - = (bfd_size_type)1 << bfd_get_section_alignment (abfd, sec); - break; - - case DT_VX_WRS_TLS_VARS_START: - sec = bfd_get_section_by_name (output_bfd, ".tls_vars"); - dyn->d_un.d_ptr = sec->vma; - break; - - case DT_VX_WRS_TLS_VARS_SIZE: - sec = bfd_get_section_by_name (output_bfd, ".tls_vars"); - dyn->d_un.d_val = sec->size; - break; - } - return TRUE; -} - - diff --git a/contrib/binutils-2.22/bfd/elf-vxworks.h b/contrib/binutils-2.22/bfd/elf-vxworks.h deleted file mode 100644 index 4a9ed1d8e9..0000000000 --- a/contrib/binutils-2.22/bfd/elf-vxworks.h +++ /dev/null @@ -1,38 +0,0 @@ -/* VxWorks support for ELF - Copyright 2005, 2006, 2007 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. */ - -#include "elf/common.h" -#include "elf/internal.h" - -bfd_boolean elf_vxworks_add_symbol_hook - (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **, - flagword *, asection **, bfd_vma *); -bfd_boolean elf_vxworks_link_output_symbol_hook - (struct bfd_link_info *, const char *name, Elf_Internal_Sym *, - asection *, struct elf_link_hash_entry *); -bfd_boolean elf_vxworks_emit_relocs - (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *, - struct elf_link_hash_entry **); -void elf_vxworks_final_write_processing (bfd *, bfd_boolean); -bfd_boolean elf_vxworks_create_dynamic_sections - (bfd *, struct bfd_link_info *, asection **); -bfd_boolean elf_vxworks_add_dynamic_entries (bfd *, struct bfd_link_info *); -bfd_boolean elf_vxworks_finish_dynamic_entry (bfd *, Elf_Internal_Dyn *); - diff --git a/contrib/binutils-2.22/bfd/elf.c b/contrib/binutils-2.22/bfd/elf.c deleted file mode 100644 index aa40c33908..0000000000 --- a/contrib/binutils-2.22/bfd/elf.c +++ /dev/null @@ -1,9630 +0,0 @@ -/* ELF executable support for BFD. - - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* -SECTION - ELF backends - - BFD support for ELF formats is being worked on. - Currently, the best supported back ends are for sparc and i386 - (running svr4 or Solaris 2). - - Documentation of the internals of the support code still needs - to be written. The code is changing quickly enough that we - haven't bothered yet. */ - -/* For sparc64-cross-sparc32. */ -#define _SYSCALL32 -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" -#include "libiberty.h" -#include "safe-ctype.h" - -#ifdef CORE_HEADER -#include CORE_HEADER -#endif - -static int elf_sort_sections (const void *, const void *); -static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *); -static bfd_boolean prep_headers (bfd *); -static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ; -static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ; -static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size, - file_ptr offset); - -/* Swap version information in and out. The version information is - currently size independent. If that ever changes, this code will - need to move into elfcode.h. */ - -/* Swap in a Verdef structure. */ - -void -_bfd_elf_swap_verdef_in (bfd *abfd, - const Elf_External_Verdef *src, - Elf_Internal_Verdef *dst) -{ - dst->vd_version = H_GET_16 (abfd, src->vd_version); - dst->vd_flags = H_GET_16 (abfd, src->vd_flags); - dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx); - dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt); - dst->vd_hash = H_GET_32 (abfd, src->vd_hash); - dst->vd_aux = H_GET_32 (abfd, src->vd_aux); - dst->vd_next = H_GET_32 (abfd, src->vd_next); -} - -/* Swap out a Verdef structure. */ - -void -_bfd_elf_swap_verdef_out (bfd *abfd, - const Elf_Internal_Verdef *src, - Elf_External_Verdef *dst) -{ - H_PUT_16 (abfd, src->vd_version, dst->vd_version); - H_PUT_16 (abfd, src->vd_flags, dst->vd_flags); - H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx); - H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt); - H_PUT_32 (abfd, src->vd_hash, dst->vd_hash); - H_PUT_32 (abfd, src->vd_aux, dst->vd_aux); - H_PUT_32 (abfd, src->vd_next, dst->vd_next); -} - -/* Swap in a Verdaux structure. */ - -void -_bfd_elf_swap_verdaux_in (bfd *abfd, - const Elf_External_Verdaux *src, - Elf_Internal_Verdaux *dst) -{ - dst->vda_name = H_GET_32 (abfd, src->vda_name); - dst->vda_next = H_GET_32 (abfd, src->vda_next); -} - -/* Swap out a Verdaux structure. */ - -void -_bfd_elf_swap_verdaux_out (bfd *abfd, - const Elf_Internal_Verdaux *src, - Elf_External_Verdaux *dst) -{ - H_PUT_32 (abfd, src->vda_name, dst->vda_name); - H_PUT_32 (abfd, src->vda_next, dst->vda_next); -} - -/* Swap in a Verneed structure. */ - -void -_bfd_elf_swap_verneed_in (bfd *abfd, - const Elf_External_Verneed *src, - Elf_Internal_Verneed *dst) -{ - dst->vn_version = H_GET_16 (abfd, src->vn_version); - dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt); - dst->vn_file = H_GET_32 (abfd, src->vn_file); - dst->vn_aux = H_GET_32 (abfd, src->vn_aux); - dst->vn_next = H_GET_32 (abfd, src->vn_next); -} - -/* Swap out a Verneed structure. */ - -void -_bfd_elf_swap_verneed_out (bfd *abfd, - const Elf_Internal_Verneed *src, - Elf_External_Verneed *dst) -{ - H_PUT_16 (abfd, src->vn_version, dst->vn_version); - H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt); - H_PUT_32 (abfd, src->vn_file, dst->vn_file); - H_PUT_32 (abfd, src->vn_aux, dst->vn_aux); - H_PUT_32 (abfd, src->vn_next, dst->vn_next); -} - -/* Swap in a Vernaux structure. */ - -void -_bfd_elf_swap_vernaux_in (bfd *abfd, - const Elf_External_Vernaux *src, - Elf_Internal_Vernaux *dst) -{ - dst->vna_hash = H_GET_32 (abfd, src->vna_hash); - dst->vna_flags = H_GET_16 (abfd, src->vna_flags); - dst->vna_other = H_GET_16 (abfd, src->vna_other); - dst->vna_name = H_GET_32 (abfd, src->vna_name); - dst->vna_next = H_GET_32 (abfd, src->vna_next); -} - -/* Swap out a Vernaux structure. */ - -void -_bfd_elf_swap_vernaux_out (bfd *abfd, - const Elf_Internal_Vernaux *src, - Elf_External_Vernaux *dst) -{ - H_PUT_32 (abfd, src->vna_hash, dst->vna_hash); - H_PUT_16 (abfd, src->vna_flags, dst->vna_flags); - H_PUT_16 (abfd, src->vna_other, dst->vna_other); - H_PUT_32 (abfd, src->vna_name, dst->vna_name); - H_PUT_32 (abfd, src->vna_next, dst->vna_next); -} - -/* Swap in a Versym structure. */ - -void -_bfd_elf_swap_versym_in (bfd *abfd, - const Elf_External_Versym *src, - Elf_Internal_Versym *dst) -{ - dst->vs_vers = H_GET_16 (abfd, src->vs_vers); -} - -/* Swap out a Versym structure. */ - -void -_bfd_elf_swap_versym_out (bfd *abfd, - const Elf_Internal_Versym *src, - Elf_External_Versym *dst) -{ - H_PUT_16 (abfd, src->vs_vers, dst->vs_vers); -} - -/* Standard ELF hash function. Do not change this function; you will - cause invalid hash tables to be generated. */ - -unsigned long -bfd_elf_hash (const char *namearg) -{ - const unsigned char *name = (const unsigned char *) namearg; - unsigned long h = 0; - unsigned long g; - int ch; - - while ((ch = *name++) != '\0') - { - h = (h << 4) + ch; - if ((g = (h & 0xf0000000)) != 0) - { - h ^= g >> 24; - /* The ELF ABI says `h &= ~g', but this is equivalent in - this case and on some machines one insn instead of two. */ - h ^= g; - } - } - return h & 0xffffffff; -} - -/* DT_GNU_HASH hash function. Do not change this function; you will - cause invalid hash tables to be generated. */ - -unsigned long -bfd_elf_gnu_hash (const char *namearg) -{ - const unsigned char *name = (const unsigned char *) namearg; - unsigned long h = 5381; - unsigned char ch; - - while ((ch = *name++) != '\0') - h = (h << 5) + h + ch; - return h & 0xffffffff; -} - -/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with - the object_id field of an elf_obj_tdata field set to OBJECT_ID. */ -bfd_boolean -bfd_elf_allocate_object (bfd *abfd, - size_t object_size, - enum elf_target_id object_id) -{ - BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata)); - abfd->tdata.any = bfd_zalloc (abfd, object_size); - if (abfd->tdata.any == NULL) - return FALSE; - - elf_object_id (abfd) = object_id; - elf_program_header_size (abfd) = (bfd_size_type) -1; - return TRUE; -} - - -bfd_boolean -bfd_elf_make_object (bfd *abfd) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata), - bed->target_id); -} - -bfd_boolean -bfd_elf_mkcorefile (bfd *abfd) -{ - /* I think this can be done just like an object file. */ - return abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd); -} - -static char * -bfd_elf_get_str_section (bfd *abfd, unsigned int shindex) -{ - Elf_Internal_Shdr **i_shdrp; - bfd_byte *shstrtab = NULL; - file_ptr offset; - bfd_size_type shstrtabsize; - - i_shdrp = elf_elfsections (abfd); - if (i_shdrp == 0 - || shindex >= elf_numsections (abfd) - || i_shdrp[shindex] == 0) - return NULL; - - shstrtab = i_shdrp[shindex]->contents; - if (shstrtab == NULL) - { - /* No cached one, attempt to read, and cache what we read. */ - offset = i_shdrp[shindex]->sh_offset; - shstrtabsize = i_shdrp[shindex]->sh_size; - - /* Allocate and clear an extra byte at the end, to prevent crashes - in case the string table is not terminated. */ - if (shstrtabsize + 1 <= 1 - || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL - || bfd_seek (abfd, offset, SEEK_SET) != 0) - shstrtab = NULL; - else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_file_truncated); - shstrtab = NULL; - /* Once we've failed to read it, make sure we don't keep - trying. Otherwise, we'll keep allocating space for - the string table over and over. */ - i_shdrp[shindex]->sh_size = 0; - } - else - shstrtab[shstrtabsize] = '\0'; - i_shdrp[shindex]->contents = shstrtab; - } - return (char *) shstrtab; -} - -char * -bfd_elf_string_from_elf_section (bfd *abfd, - unsigned int shindex, - unsigned int strindex) -{ - Elf_Internal_Shdr *hdr; - - if (strindex == 0) - return ""; - - if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd)) - return NULL; - - hdr = elf_elfsections (abfd)[shindex]; - - if (hdr->contents == NULL - && bfd_elf_get_str_section (abfd, shindex) == NULL) - return NULL; - - if (strindex >= hdr->sh_size) - { - unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx; - (*_bfd_error_handler) - (_("%B: invalid string offset %u >= %lu for section `%s'"), - abfd, strindex, (unsigned long) hdr->sh_size, - (shindex == shstrndx && strindex == hdr->sh_name - ? ".shstrtab" - : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name))); - return NULL; - } - - return ((char *) hdr->contents) + strindex; -} - -/* Read and convert symbols to internal format. - SYMCOUNT specifies the number of symbols to read, starting from - symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF - are non-NULL, they are used to store the internal symbols, external - symbols, and symbol section index extensions, respectively. - Returns a pointer to the internal symbol buffer (malloced if necessary) - or NULL if there were no symbols or some kind of problem. */ - -Elf_Internal_Sym * -bfd_elf_get_elf_syms (bfd *ibfd, - Elf_Internal_Shdr *symtab_hdr, - size_t symcount, - size_t symoffset, - Elf_Internal_Sym *intsym_buf, - void *extsym_buf, - Elf_External_Sym_Shndx *extshndx_buf) -{ - Elf_Internal_Shdr *shndx_hdr; - void *alloc_ext; - const bfd_byte *esym; - Elf_External_Sym_Shndx *alloc_extshndx; - Elf_External_Sym_Shndx *shndx; - Elf_Internal_Sym *alloc_intsym; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - const struct elf_backend_data *bed; - size_t extsym_size; - bfd_size_type amt; - file_ptr pos; - - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) - abort (); - - if (symcount == 0) - return intsym_buf; - - /* Normal syms might have section extension entries. */ - shndx_hdr = NULL; - if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr) - shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr; - - /* Read the symbols. */ - alloc_ext = NULL; - alloc_extshndx = NULL; - alloc_intsym = NULL; - bed = get_elf_backend_data (ibfd); - extsym_size = bed->s->sizeof_sym; - amt = symcount * extsym_size; - pos = symtab_hdr->sh_offset + symoffset * extsym_size; - if (extsym_buf == NULL) - { - alloc_ext = bfd_malloc2 (symcount, extsym_size); - extsym_buf = alloc_ext; - } - if (extsym_buf == NULL - || bfd_seek (ibfd, pos, SEEK_SET) != 0 - || bfd_bread (extsym_buf, amt, ibfd) != amt) - { - intsym_buf = NULL; - goto out; - } - - if (shndx_hdr == NULL || shndx_hdr->sh_size == 0) - extshndx_buf = NULL; - else - { - amt = symcount * sizeof (Elf_External_Sym_Shndx); - pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx); - if (extshndx_buf == NULL) - { - alloc_extshndx = (Elf_External_Sym_Shndx *) - bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx)); - extshndx_buf = alloc_extshndx; - } - if (extshndx_buf == NULL - || bfd_seek (ibfd, pos, SEEK_SET) != 0 - || bfd_bread (extshndx_buf, amt, ibfd) != amt) - { - intsym_buf = NULL; - goto out; - } - } - - if (intsym_buf == NULL) - { - alloc_intsym = (Elf_Internal_Sym *) - bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); - intsym_buf = alloc_intsym; - if (intsym_buf == NULL) - goto out; - } - - /* Convert the symbols to internal form. */ - isymend = intsym_buf + symcount; - for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf, - shndx = extshndx_buf; - isym < isymend; - esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL) - if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym)) - { - symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size; - (*_bfd_error_handler) (_("%B symbol number %lu references " - "nonexistent SHT_SYMTAB_SHNDX section"), - ibfd, (unsigned long) symoffset); - if (alloc_intsym != NULL) - free (alloc_intsym); - intsym_buf = NULL; - goto out; - } - - out: - if (alloc_ext != NULL) - free (alloc_ext); - if (alloc_extshndx != NULL) - free (alloc_extshndx); - - return intsym_buf; -} - -/* Look up a symbol name. */ -const char * -bfd_elf_sym_name (bfd *abfd, - Elf_Internal_Shdr *symtab_hdr, - Elf_Internal_Sym *isym, - asection *sym_sec) -{ - const char *name; - unsigned int iname = isym->st_name; - unsigned int shindex = symtab_hdr->sh_link; - - if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION - /* Check for a bogus st_shndx to avoid crashing. */ - && isym->st_shndx < elf_numsections (abfd)) - { - iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name; - shindex = elf_elfheader (abfd)->e_shstrndx; - } - - name = bfd_elf_string_from_elf_section (abfd, shindex, iname); - if (name == NULL) - name = "(null)"; - else if (sym_sec && *name == '\0') - name = bfd_section_name (abfd, sym_sec); - - return name; -} - -/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP - sections. The first element is the flags, the rest are section - pointers. */ - -typedef union elf_internal_group { - Elf_Internal_Shdr *shdr; - unsigned int flags; -} Elf_Internal_Group; - -/* Return the name of the group signature symbol. Why isn't the - signature just a string? */ - -static const char * -group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) -{ - Elf_Internal_Shdr *hdr; - unsigned char esym[sizeof (Elf64_External_Sym)]; - Elf_External_Sym_Shndx eshndx; - Elf_Internal_Sym isym; - - /* First we need to ensure the symbol table is available. Make sure - that it is a symbol table section. */ - if (ghdr->sh_link >= elf_numsections (abfd)) - return NULL; - hdr = elf_elfsections (abfd) [ghdr->sh_link]; - if (hdr->sh_type != SHT_SYMTAB - || ! bfd_section_from_shdr (abfd, ghdr->sh_link)) - return NULL; - - /* Go read the symbol. */ - hdr = &elf_tdata (abfd)->symtab_hdr; - if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info, - &isym, esym, &eshndx) == NULL) - return NULL; - - return bfd_elf_sym_name (abfd, hdr, &isym, NULL); -} - -/* Set next_in_group list pointer, and group name for NEWSECT. */ - -static bfd_boolean -setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) -{ - unsigned int num_group = elf_tdata (abfd)->num_group; - - /* If num_group is zero, read in all SHT_GROUP sections. The count - is set to -1 if there are no SHT_GROUP sections. */ - if (num_group == 0) - { - unsigned int i, shnum; - - /* First count the number of groups. If we have a SHT_GROUP - section with just a flag word (ie. sh_size is 4), ignore it. */ - shnum = elf_numsections (abfd); - num_group = 0; - -#define IS_VALID_GROUP_SECTION_HEADER(shdr) \ - ( (shdr)->sh_type == SHT_GROUP \ - && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE) \ - && (shdr)->sh_entsize == GRP_ENTRY_SIZE \ - && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0) - - for (i = 0; i < shnum; i++) - { - Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; - - if (IS_VALID_GROUP_SECTION_HEADER (shdr)) - num_group += 1; - } - - if (num_group == 0) - { - num_group = (unsigned) -1; - elf_tdata (abfd)->num_group = num_group; - } - else - { - /* We keep a list of elf section headers for group sections, - so we can find them quickly. */ - bfd_size_type amt; - - elf_tdata (abfd)->num_group = num_group; - elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **) - bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *)); - if (elf_tdata (abfd)->group_sect_ptr == NULL) - return FALSE; - - num_group = 0; - for (i = 0; i < shnum; i++) - { - Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; - - if (IS_VALID_GROUP_SECTION_HEADER (shdr)) - { - unsigned char *src; - Elf_Internal_Group *dest; - - /* Add to list of sections. */ - elf_tdata (abfd)->group_sect_ptr[num_group] = shdr; - num_group += 1; - - /* Read the raw contents. */ - BFD_ASSERT (sizeof (*dest) >= 4); - amt = shdr->sh_size * sizeof (*dest) / 4; - shdr->contents = (unsigned char *) - bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4); - /* PR binutils/4110: Handle corrupt group headers. */ - if (shdr->contents == NULL) - { - _bfd_error_handler - (_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - memset (shdr->contents, 0, amt); - - if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 - || (bfd_bread (shdr->contents, shdr->sh_size, abfd) - != shdr->sh_size)) - return FALSE; - - /* Translate raw contents, a flag word followed by an - array of elf section indices all in target byte order, - to the flag word followed by an array of elf section - pointers. */ - src = shdr->contents + shdr->sh_size; - dest = (Elf_Internal_Group *) (shdr->contents + amt); - while (1) - { - unsigned int idx; - - src -= 4; - --dest; - idx = H_GET_32 (abfd, src); - if (src == shdr->contents) - { - dest->flags = idx; - if (shdr->bfd_section != NULL && (idx & GRP_COMDAT)) - shdr->bfd_section->flags - |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - break; - } - if (idx >= shnum) - { - ((*_bfd_error_handler) - (_("%B: invalid SHT_GROUP entry"), abfd)); - idx = 0; - } - dest->shdr = elf_elfsections (abfd)[idx]; - } - } - } - } - } - - if (num_group != (unsigned) -1) - { - unsigned int i; - - for (i = 0; i < num_group; i++) - { - Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; - Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents; - unsigned int n_elt = shdr->sh_size / 4; - - /* Look through this group's sections to see if current - section is a member. */ - while (--n_elt != 0) - if ((++idx)->shdr == hdr) - { - asection *s = NULL; - - /* We are a member of this group. Go looking through - other members to see if any others are linked via - next_in_group. */ - idx = (Elf_Internal_Group *) shdr->contents; - n_elt = shdr->sh_size / 4; - while (--n_elt != 0) - if ((s = (++idx)->shdr->bfd_section) != NULL - && elf_next_in_group (s) != NULL) - break; - if (n_elt != 0) - { - /* Snarf the group name from other member, and - insert current section in circular list. */ - elf_group_name (newsect) = elf_group_name (s); - elf_next_in_group (newsect) = elf_next_in_group (s); - elf_next_in_group (s) = newsect; - } - else - { - const char *gname; - - gname = group_signature (abfd, shdr); - if (gname == NULL) - return FALSE; - elf_group_name (newsect) = gname; - - /* Start a circular list with one element. */ - elf_next_in_group (newsect) = newsect; - } - - /* If the group section has been created, point to the - new member. */ - if (shdr->bfd_section != NULL) - elf_next_in_group (shdr->bfd_section) = newsect; - - i = num_group - 1; - break; - } - } - } - - if (elf_group_name (newsect) == NULL) - { - (*_bfd_error_handler) (_("%B: no group info for section %A"), - abfd, newsect); - } - return TRUE; -} - -bfd_boolean -_bfd_elf_setup_sections (bfd *abfd) -{ - unsigned int i; - unsigned int num_group = elf_tdata (abfd)->num_group; - bfd_boolean result = TRUE; - asection *s; - - /* Process SHF_LINK_ORDER. */ - for (s = abfd->sections; s != NULL; s = s->next) - { - Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr; - if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0) - { - unsigned int elfsec = this_hdr->sh_link; - /* FIXME: The old Intel compiler and old strip/objcopy may - not set the sh_link or sh_info fields. Hence we could - get the situation where elfsec is 0. */ - if (elfsec == 0) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (bed->link_order_error_handler) - bed->link_order_error_handler - (_("%B: warning: sh_link not set for section `%A'"), - abfd, s); - } - else - { - asection *linksec = NULL; - - if (elfsec < elf_numsections (abfd)) - { - this_hdr = elf_elfsections (abfd)[elfsec]; - linksec = this_hdr->bfd_section; - } - - /* PR 1991, 2008: - Some strip/objcopy may leave an incorrect value in - sh_link. We don't want to proceed. */ - if (linksec == NULL) - { - (*_bfd_error_handler) - (_("%B: sh_link [%d] in section `%A' is incorrect"), - s->owner, s, elfsec); - result = FALSE; - } - - elf_linked_to_section (s) = linksec; - } - } - } - - /* Process section groups. */ - if (num_group == (unsigned) -1) - return result; - - for (i = 0; i < num_group; i++) - { - Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i]; - Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents; - unsigned int n_elt = shdr->sh_size / 4; - - while (--n_elt != 0) - if ((++idx)->shdr->bfd_section) - elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section; - else if (idx->shdr->sh_type == SHT_RELA - || idx->shdr->sh_type == SHT_REL) - /* We won't include relocation sections in section groups in - output object files. We adjust the group section size here - so that relocatable link will work correctly when - relocation sections are in section group in input object - files. */ - shdr->bfd_section->size -= 4; - else - { - /* There are some unknown sections in the group. */ - (*_bfd_error_handler) - (_("%B: unknown [%d] section `%s' in group [%s]"), - abfd, - (unsigned int) idx->shdr->sh_type, - bfd_elf_string_from_elf_section (abfd, - (elf_elfheader (abfd) - ->e_shstrndx), - idx->shdr->sh_name), - shdr->bfd_section->name); - result = FALSE; - } - } - return result; -} - -bfd_boolean -bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec) -{ - return elf_next_in_group (sec) != NULL; -} - -/* Make a BFD section from an ELF section. We store a pointer to the - BFD section in the bfd_section field of the header. */ - -bfd_boolean -_bfd_elf_make_section_from_shdr (bfd *abfd, - Elf_Internal_Shdr *hdr, - const char *name, - int shindex) -{ - asection *newsect; - flagword flags; - const struct elf_backend_data *bed; - - if (hdr->bfd_section != NULL) - return TRUE; - - newsect = bfd_make_section_anyway (abfd, name); - if (newsect == NULL) - return FALSE; - - hdr->bfd_section = newsect; - elf_section_data (newsect)->this_hdr = *hdr; - elf_section_data (newsect)->this_idx = shindex; - - /* Always use the real type/flags. */ - elf_section_type (newsect) = hdr->sh_type; - elf_section_flags (newsect) = hdr->sh_flags; - - newsect->filepos = hdr->sh_offset; - - if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr) - || ! bfd_set_section_size (abfd, newsect, hdr->sh_size) - || ! bfd_set_section_alignment (abfd, newsect, - bfd_log2 (hdr->sh_addralign))) - return FALSE; - - flags = SEC_NO_FLAGS; - if (hdr->sh_type != SHT_NOBITS) - flags |= SEC_HAS_CONTENTS; - if (hdr->sh_type == SHT_GROUP) - flags |= SEC_GROUP | SEC_EXCLUDE; - if ((hdr->sh_flags & SHF_ALLOC) != 0) - { - flags |= SEC_ALLOC; - if (hdr->sh_type != SHT_NOBITS) - flags |= SEC_LOAD; - } - if ((hdr->sh_flags & SHF_WRITE) == 0) - flags |= SEC_READONLY; - if ((hdr->sh_flags & SHF_EXECINSTR) != 0) - flags |= SEC_CODE; - else if ((flags & SEC_LOAD) != 0) - flags |= SEC_DATA; - if ((hdr->sh_flags & SHF_MERGE) != 0) - { - flags |= SEC_MERGE; - newsect->entsize = hdr->sh_entsize; - if ((hdr->sh_flags & SHF_STRINGS) != 0) - flags |= SEC_STRINGS; - } - if (hdr->sh_flags & SHF_GROUP) - if (!setup_group (abfd, hdr, newsect)) - return FALSE; - if ((hdr->sh_flags & SHF_TLS) != 0) - flags |= SEC_THREAD_LOCAL; - if ((hdr->sh_flags & SHF_EXCLUDE) != 0) - flags |= SEC_EXCLUDE; - - if ((flags & SEC_ALLOC) == 0) - { - /* The debugging sections appear to be recognized only by name, - not any sort of flag. Their SEC_ALLOC bits are cleared. */ - static const struct - { - const char *name; - int len; - } debug_sections [] = - { - { STRING_COMMA_LEN ("debug") }, /* 'd' */ - { NULL, 0 }, /* 'e' */ - { NULL, 0 }, /* 'f' */ - { STRING_COMMA_LEN ("gnu.linkonce.wi.") }, /* 'g' */ - { NULL, 0 }, /* 'h' */ - { NULL, 0 }, /* 'i' */ - { NULL, 0 }, /* 'j' */ - { NULL, 0 }, /* 'k' */ - { STRING_COMMA_LEN ("line") }, /* 'l' */ - { NULL, 0 }, /* 'm' */ - { NULL, 0 }, /* 'n' */ - { NULL, 0 }, /* 'o' */ - { NULL, 0 }, /* 'p' */ - { NULL, 0 }, /* 'q' */ - { NULL, 0 }, /* 'r' */ - { STRING_COMMA_LEN ("stab") }, /* 's' */ - { NULL, 0 }, /* 't' */ - { NULL, 0 }, /* 'u' */ - { NULL, 0 }, /* 'v' */ - { NULL, 0 }, /* 'w' */ - { NULL, 0 }, /* 'x' */ - { NULL, 0 }, /* 'y' */ - { STRING_COMMA_LEN ("zdebug") } /* 'z' */ - }; - - if (name [0] == '.') - { - int i = name [1] - 'd'; - if (i >= 0 - && i < (int) ARRAY_SIZE (debug_sections) - && debug_sections [i].name != NULL - && strncmp (&name [1], debug_sections [i].name, - debug_sections [i].len) == 0) - flags |= SEC_DEBUGGING; - } - } - - /* As a GNU extension, if the name begins with .gnu.linkonce, we - only link a single copy of the section. This is used to support - g++. g++ will emit each template expansion in its own section. - The symbols will be defined as weak, so that multiple definitions - are permitted. The GNU linker extension is to actually discard - all but one of the sections. */ - if (CONST_STRNEQ (name, ".gnu.linkonce") - && elf_next_in_group (newsect) == NULL) - flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - - bed = get_elf_backend_data (abfd); - if (bed->elf_backend_section_flags) - if (! bed->elf_backend_section_flags (&flags, hdr)) - return FALSE; - - if (! bfd_set_section_flags (abfd, newsect, flags)) - return FALSE; - - /* We do not parse the PT_NOTE segments as we are interested even in the - separate debug info files which may have the segments offsets corrupted. - PT_NOTEs from the core files are currently not parsed using BFD. */ - if (hdr->sh_type == SHT_NOTE) - { - bfd_byte *contents; - - if (!bfd_malloc_and_get_section (abfd, newsect, &contents)) - return FALSE; - - elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1); - free (contents); - } - - if ((flags & SEC_ALLOC) != 0) - { - Elf_Internal_Phdr *phdr; - unsigned int i, nload; - - /* Some ELF linkers produce binaries with all the program header - p_paddr fields zero. If we have such a binary with more than - one PT_LOAD header, then leave the section lma equal to vma - so that we don't create sections with overlapping lma. */ - phdr = elf_tdata (abfd)->phdr; - for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) - if (phdr->p_paddr != 0) - break; - else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0) - ++nload; - if (i >= elf_elfheader (abfd)->e_phnum && nload > 1) - return TRUE; - - phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) - { - if (((phdr->p_type == PT_LOAD - && (hdr->sh_flags & SHF_TLS) == 0) - || phdr->p_type == PT_TLS) - && ELF_SECTION_IN_SEGMENT (hdr, phdr)) - { - if ((flags & SEC_LOAD) == 0) - newsect->lma = (phdr->p_paddr - + hdr->sh_addr - phdr->p_vaddr); - else - /* We used to use the same adjustment for SEC_LOAD - sections, but that doesn't work if the segment - is packed with code from multiple VMAs. - Instead we calculate the section LMA based on - the segment LMA. It is assumed that the - segment will contain sections with contiguous - LMAs, even if the VMAs are not. */ - newsect->lma = (phdr->p_paddr - + hdr->sh_offset - phdr->p_offset); - - /* With contiguous segments, we can't tell from file - offsets whether a section with zero size should - be placed at the end of one segment or the - beginning of the next. Decide based on vaddr. */ - if (hdr->sh_addr >= phdr->p_vaddr - && (hdr->sh_addr + hdr->sh_size - <= phdr->p_vaddr + phdr->p_memsz)) - break; - } - } - } - - /* Compress/decompress DWARF debug sections with names: .debug_* and - .zdebug_*, after the section flags is set. */ - if ((flags & SEC_DEBUGGING) - && ((name[1] == 'd' && name[6] == '_') - || (name[1] == 'z' && name[7] == '_'))) - { - enum { nothing, compress, decompress } action = nothing; - char *new_name; - - if (bfd_is_section_compressed (abfd, newsect)) - { - /* Compressed section. Check if we should decompress. */ - if ((abfd->flags & BFD_DECOMPRESS)) - action = decompress; - } - else - { - /* Normal section. Check if we should compress. */ - if ((abfd->flags & BFD_COMPRESS)) - action = compress; - } - - new_name = NULL; - switch (action) - { - case nothing: - break; - case compress: - if (!bfd_init_section_compress_status (abfd, newsect)) - { - (*_bfd_error_handler) - (_("%B: unable to initialize commpress status for section %s"), - abfd, name); - return FALSE; - } - if (name[1] != 'z') - { - unsigned int len = strlen (name); - - new_name = bfd_alloc (abfd, len + 2); - if (new_name == NULL) - return FALSE; - new_name[0] = '.'; - new_name[1] = 'z'; - memcpy (new_name + 2, name + 1, len); - } - break; - case decompress: - if (!bfd_init_section_decompress_status (abfd, newsect)) - { - (*_bfd_error_handler) - (_("%B: unable to initialize decommpress status for section %s"), - abfd, name); - return FALSE; - } - if (name[1] == 'z') - { - unsigned int len = strlen (name); - - new_name = bfd_alloc (abfd, len); - if (new_name == NULL) - return FALSE; - new_name[0] = '.'; - memcpy (new_name + 1, name + 2, len - 1); - } - break; - } - if (new_name != NULL) - bfd_rename_section (abfd, newsect, new_name); - } - - return TRUE; -} - -const char *const bfd_elf_section_type_names[] = { - "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", - "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", - "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", -}; - -/* ELF relocs are against symbols. If we are producing relocatable - output, and the reloc is against an external symbol, and nothing - has given us any additional addend, the resulting reloc will also - be against the same symbol. In such a case, we don't want to - change anything about the way the reloc is handled, since it will - all be done at final link time. Rather than put special case code - into bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocatable output against an external symbol. */ - -bfd_reloc_status_type -bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, - arelent *reloc_entry, - asymbol *symbol, - void *data ATTRIBUTE_UNUSED, - asection *input_section, - bfd *output_bfd, - char **error_message ATTRIBUTE_UNUSED) -{ - if (output_bfd != NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Copy the program header and other data from one object module to - another. */ - -bfd_boolean -_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) -{ - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; - - BFD_ASSERT (!elf_flags_init (obfd) - || (elf_elfheader (obfd)->e_flags - == elf_elfheader (ibfd)->e_flags)); - - elf_gp (obfd) = elf_gp (ibfd); - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = TRUE; - - /* Copy object attributes. */ - _bfd_elf_copy_obj_attributes (ibfd, obfd); - return TRUE; -} - -static const char * -get_segment_type (unsigned int p_type) -{ - const char *pt; - switch (p_type) - { - case PT_NULL: pt = "NULL"; break; - case PT_LOAD: pt = "LOAD"; break; - case PT_DYNAMIC: pt = "DYNAMIC"; break; - case PT_INTERP: pt = "INTERP"; break; - case PT_NOTE: pt = "NOTE"; break; - case PT_SHLIB: pt = "SHLIB"; break; - case PT_PHDR: pt = "PHDR"; break; - case PT_TLS: pt = "TLS"; break; - case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; - case PT_GNU_STACK: pt = "STACK"; break; - case PT_GNU_RELRO: pt = "RELRO"; break; - default: pt = NULL; break; - } - return pt; -} - -/* Print out the program headers. */ - -bfd_boolean -_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) -{ - FILE *f = (FILE *) farg; - Elf_Internal_Phdr *p; - asection *s; - bfd_byte *dynbuf = NULL; - - p = elf_tdata (abfd)->phdr; - if (p != NULL) - { - unsigned int i, c; - - fprintf (f, _("\nProgram Header:\n")); - c = elf_elfheader (abfd)->e_phnum; - for (i = 0; i < c; i++, p++) - { - const char *pt = get_segment_type (p->p_type); - char buf[20]; - - if (pt == NULL) - { - sprintf (buf, "0x%lx", p->p_type); - pt = buf; - } - fprintf (f, "%8s off 0x", pt); - bfd_fprintf_vma (abfd, f, p->p_offset); - fprintf (f, " vaddr 0x"); - bfd_fprintf_vma (abfd, f, p->p_vaddr); - fprintf (f, " paddr 0x"); - bfd_fprintf_vma (abfd, f, p->p_paddr); - fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align)); - fprintf (f, " filesz 0x"); - bfd_fprintf_vma (abfd, f, p->p_filesz); - fprintf (f, " memsz 0x"); - bfd_fprintf_vma (abfd, f, p->p_memsz); - fprintf (f, " flags %c%c%c", - (p->p_flags & PF_R) != 0 ? 'r' : '-', - (p->p_flags & PF_W) != 0 ? 'w' : '-', - (p->p_flags & PF_X) != 0 ? 'x' : '-'); - if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0) - fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)); - fprintf (f, "\n"); - } - } - - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - unsigned int elfsec; - unsigned long shlink; - bfd_byte *extdyn, *extdynend; - size_t extdynsize; - void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); - - fprintf (f, _("\nDynamic Section:\n")); - - if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) - goto error_return; - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == SHN_BAD) - goto error_return; - shlink = elf_elfsections (abfd)[elfsec]->sh_link; - - extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; - swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; - - extdyn = dynbuf; - extdynend = extdyn + s->size; - for (; extdyn < extdynend; extdyn += extdynsize) - { - Elf_Internal_Dyn dyn; - const char *name = ""; - char ab[20]; - bfd_boolean stringp; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - (*swap_dyn_in) (abfd, extdyn, &dyn); - - if (dyn.d_tag == DT_NULL) - break; - - stringp = FALSE; - switch (dyn.d_tag) - { - default: - if (bed->elf_backend_get_target_dtag) - name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag); - - if (!strcmp (name, "")) - { - sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag); - name = ab; - } - break; - - case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break; - case DT_PLTRELSZ: name = "PLTRELSZ"; break; - case DT_PLTGOT: name = "PLTGOT"; break; - case DT_HASH: name = "HASH"; break; - case DT_STRTAB: name = "STRTAB"; break; - case DT_SYMTAB: name = "SYMTAB"; break; - case DT_RELA: name = "RELA"; break; - case DT_RELASZ: name = "RELASZ"; break; - case DT_RELAENT: name = "RELAENT"; break; - case DT_STRSZ: name = "STRSZ"; break; - case DT_SYMENT: name = "SYMENT"; break; - case DT_INIT: name = "INIT"; break; - case DT_FINI: name = "FINI"; break; - case DT_SONAME: name = "SONAME"; stringp = TRUE; break; - case DT_RPATH: name = "RPATH"; stringp = TRUE; break; - case DT_SYMBOLIC: name = "SYMBOLIC"; break; - case DT_REL: name = "REL"; break; - case DT_RELSZ: name = "RELSZ"; break; - case DT_RELENT: name = "RELENT"; break; - case DT_PLTREL: name = "PLTREL"; break; - case DT_DEBUG: name = "DEBUG"; break; - case DT_TEXTREL: name = "TEXTREL"; break; - case DT_JMPREL: name = "JMPREL"; break; - case DT_BIND_NOW: name = "BIND_NOW"; break; - case DT_INIT_ARRAY: name = "INIT_ARRAY"; break; - case DT_FINI_ARRAY: name = "FINI_ARRAY"; break; - case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break; - case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break; - case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break; - case DT_FLAGS: name = "FLAGS"; break; - case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break; - case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break; - case DT_CHECKSUM: name = "CHECKSUM"; break; - case DT_PLTPADSZ: name = "PLTPADSZ"; break; - case DT_MOVEENT: name = "MOVEENT"; break; - case DT_MOVESZ: name = "MOVESZ"; break; - case DT_FEATURE: name = "FEATURE"; break; - case DT_POSFLAG_1: name = "POSFLAG_1"; break; - case DT_SYMINSZ: name = "SYMINSZ"; break; - case DT_SYMINENT: name = "SYMINENT"; break; - case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break; - case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break; - case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break; - case DT_PLTPAD: name = "PLTPAD"; break; - case DT_MOVETAB: name = "MOVETAB"; break; - case DT_SYMINFO: name = "SYMINFO"; break; - case DT_RELACOUNT: name = "RELACOUNT"; break; - case DT_RELCOUNT: name = "RELCOUNT"; break; - case DT_FLAGS_1: name = "FLAGS_1"; break; - case DT_VERSYM: name = "VERSYM"; break; - case DT_VERDEF: name = "VERDEF"; break; - case DT_VERDEFNUM: name = "VERDEFNUM"; break; - case DT_VERNEED: name = "VERNEED"; break; - case DT_VERNEEDNUM: name = "VERNEEDNUM"; break; - case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break; - case DT_USED: name = "USED"; break; - case DT_FILTER: name = "FILTER"; stringp = TRUE; break; - case DT_GNU_HASH: name = "GNU_HASH"; break; - } - - fprintf (f, " %-20s ", name); - if (! stringp) - { - fprintf (f, "0x"); - bfd_fprintf_vma (abfd, f, dyn.d_un.d_val); - } - else - { - const char *string; - unsigned int tagv = dyn.d_un.d_val; - - string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (string == NULL) - goto error_return; - fprintf (f, "%s", string); - } - fprintf (f, "\n"); - } - - free (dynbuf); - dynbuf = NULL; - } - - if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) - || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) - { - if (! _bfd_elf_slurp_version_tables (abfd, FALSE)) - return FALSE; - } - - if (elf_dynverdef (abfd) != 0) - { - Elf_Internal_Verdef *t; - - fprintf (f, _("\nVersion definitions:\n")); - for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef) - { - fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx, - t->vd_flags, t->vd_hash, - t->vd_nodename ? t->vd_nodename : ""); - if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL) - { - Elf_Internal_Verdaux *a; - - fprintf (f, "\t"); - for (a = t->vd_auxptr->vda_nextptr; - a != NULL; - a = a->vda_nextptr) - fprintf (f, "%s ", - a->vda_nodename ? a->vda_nodename : ""); - fprintf (f, "\n"); - } - } - } - - if (elf_dynverref (abfd) != 0) - { - Elf_Internal_Verneed *t; - - fprintf (f, _("\nVersion References:\n")); - for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref) - { - Elf_Internal_Vernaux *a; - - fprintf (f, _(" required from %s:\n"), - t->vn_filename ? t->vn_filename : ""); - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash, - a->vna_flags, a->vna_other, - a->vna_nodename ? a->vna_nodename : ""); - } - } - - return TRUE; - - error_return: - if (dynbuf != NULL) - free (dynbuf); - return FALSE; -} - -/* Display ELF-specific fields of a symbol. */ - -void -bfd_elf_print_symbol (bfd *abfd, - void *filep, - asymbol *symbol, - bfd_print_symbol_type how) -{ - FILE *file = (FILE *) filep; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf (file, "elf "); - bfd_fprintf_vma (abfd, file, symbol->value); - fprintf (file, " %lx", (unsigned long) symbol->flags); - break; - case bfd_print_symbol_all: - { - const char *section_name; - const char *name = NULL; - const struct elf_backend_data *bed; - unsigned char st_other; - bfd_vma val; - - section_name = symbol->section ? symbol->section->name : "(*none*)"; - - bed = get_elf_backend_data (abfd); - if (bed->elf_backend_print_symbol_all) - name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol); - - if (name == NULL) - { - name = symbol->name; - bfd_print_symbol_vandf (abfd, file, symbol); - } - - fprintf (file, " %s\t", section_name); - /* Print the "other" value for a symbol. For common symbols, - we've already printed the size; now print the alignment. - For other symbols, we have no specified alignment, and - we've printed the address; now print the size. */ - if (symbol->section && bfd_is_com_section (symbol->section)) - val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value; - else - val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size; - bfd_fprintf_vma (abfd, file, val); - - /* If we have version information, print it. */ - if (elf_tdata (abfd)->dynversym_section != 0 - && (elf_tdata (abfd)->dynverdef_section != 0 - || elf_tdata (abfd)->dynverref_section != 0)) - { - unsigned int vernum; - const char *version_string; - - vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION; - - if (vernum == 0) - version_string = ""; - else if (vernum == 1) - version_string = "Base"; - else if (vernum <= elf_tdata (abfd)->cverdefs) - version_string = - elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; - else - { - Elf_Internal_Verneed *t; - - version_string = ""; - for (t = elf_tdata (abfd)->verref; - t != NULL; - t = t->vn_nextref) - { - Elf_Internal_Vernaux *a; - - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - { - if (a->vna_other == vernum) - { - version_string = a->vna_nodename; - break; - } - } - } - } - - if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0) - fprintf (file, " %-11s", version_string); - else - { - int i; - - fprintf (file, " (%s)", version_string); - for (i = 10 - strlen (version_string); i > 0; --i) - putc (' ', file); - } - } - - /* If the st_other field is not zero, print it. */ - st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other; - - switch (st_other) - { - case 0: break; - case STV_INTERNAL: fprintf (file, " .internal"); break; - case STV_HIDDEN: fprintf (file, " .hidden"); break; - case STV_PROTECTED: fprintf (file, " .protected"); break; - default: - /* Some other non-defined flags are also present, so print - everything hex. */ - fprintf (file, " 0x%02x", (unsigned int) st_other); - } - - fprintf (file, " %s", name); - } - break; - } -} - -/* Allocate an ELF string table--force the first byte to be zero. */ - -struct bfd_strtab_hash * -_bfd_elf_stringtab_init (void) -{ - struct bfd_strtab_hash *ret; - - ret = _bfd_stringtab_init (); - if (ret != NULL) - { - bfd_size_type loc; - - loc = _bfd_stringtab_add (ret, "", TRUE, FALSE); - BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1); - if (loc == (bfd_size_type) -1) - { - _bfd_stringtab_free (ret); - ret = NULL; - } - } - return ret; -} - -/* ELF .o/exec file reading */ - -/* Create a new bfd section from an ELF section header. */ - -bfd_boolean -bfd_section_from_shdr (bfd *abfd, unsigned int shindex) -{ - Elf_Internal_Shdr *hdr; - Elf_Internal_Ehdr *ehdr; - const struct elf_backend_data *bed; - const char *name; - - if (shindex >= elf_numsections (abfd)) - return FALSE; - - hdr = elf_elfsections (abfd)[shindex]; - ehdr = elf_elfheader (abfd); - name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx, - hdr->sh_name); - if (name == NULL) - return FALSE; - - bed = get_elf_backend_data (abfd); - switch (hdr->sh_type) - { - case SHT_NULL: - /* Inactive section. Throw it away. */ - return TRUE; - - case SHT_PROGBITS: /* Normal section with contents. */ - case SHT_NOBITS: /* .bss section. */ - case SHT_HASH: /* .hash section. */ - case SHT_NOTE: /* .note section. */ - case SHT_INIT_ARRAY: /* .init_array section. */ - case SHT_FINI_ARRAY: /* .fini_array section. */ - case SHT_PREINIT_ARRAY: /* .preinit_array section. */ - case SHT_GNU_LIBLIST: /* .gnu.liblist section. */ - case SHT_GNU_HASH: /* .gnu.hash section. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_DYNAMIC: /* Dynamic linking information. */ - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) - return FALSE; - if (hdr->sh_link > elf_numsections (abfd)) - { - /* PR 10478: Accept Solaris binaries with a sh_link - field set to SHN_BEFORE or SHN_AFTER. */ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_i386: - case bfd_arch_sparc: - if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */ - || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */) - break; - /* Otherwise fall through. */ - default: - return FALSE; - } - } - else if (elf_elfsections (abfd)[hdr->sh_link] == NULL) - return FALSE; - else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB) - { - Elf_Internal_Shdr *dynsymhdr; - - /* The shared libraries distributed with hpux11 have a bogus - sh_link field for the ".dynamic" section. Find the - string table for the ".dynsym" section instead. */ - if (elf_dynsymtab (abfd) != 0) - { - dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)]; - hdr->sh_link = dynsymhdr->sh_link; - } - else - { - unsigned int i, num_sec; - - num_sec = elf_numsections (abfd); - for (i = 1; i < num_sec; i++) - { - dynsymhdr = elf_elfsections (abfd)[i]; - if (dynsymhdr->sh_type == SHT_DYNSYM) - { - hdr->sh_link = dynsymhdr->sh_link; - break; - } - } - } - } - break; - - case SHT_SYMTAB: /* A symbol table */ - if (elf_onesymtab (abfd) == shindex) - return TRUE; - - if (hdr->sh_entsize != bed->s->sizeof_sym) - return FALSE; - if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size) - return FALSE; - BFD_ASSERT (elf_onesymtab (abfd) == 0); - elf_onesymtab (abfd) = shindex; - elf_tdata (abfd)->symtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr; - abfd->flags |= HAS_SYMS; - - /* Sometimes a shared object will map in the symbol table. If - SHF_ALLOC is set, and this is a shared object, then we also - treat this section as a BFD section. We can not base the - decision purely on SHF_ALLOC, because that flag is sometimes - set in a relocatable object file, which would confuse the - linker. */ - if ((hdr->sh_flags & SHF_ALLOC) != 0 - && (abfd->flags & DYNAMIC) != 0 - && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name, - shindex)) - return FALSE; - - /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we - can't read symbols without that section loaded as well. It - is most likely specified by the next section header. */ - if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex) - { - unsigned int i, num_sec; - - num_sec = elf_numsections (abfd); - for (i = shindex + 1; i < num_sec; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_type == SHT_SYMTAB_SHNDX - && hdr2->sh_link == shindex) - break; - } - if (i == num_sec) - for (i = 1; i < shindex; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_type == SHT_SYMTAB_SHNDX - && hdr2->sh_link == shindex) - break; - } - if (i != shindex) - return bfd_section_from_shdr (abfd, i); - } - return TRUE; - - case SHT_DYNSYM: /* A dynamic symbol table */ - if (elf_dynsymtab (abfd) == shindex) - return TRUE; - - if (hdr->sh_entsize != bed->s->sizeof_sym) - return FALSE; - BFD_ASSERT (elf_dynsymtab (abfd) == 0); - elf_dynsymtab (abfd) = shindex; - elf_tdata (abfd)->dynsymtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr; - abfd->flags |= HAS_SYMS; - - /* Besides being a symbol table, we also treat this as a regular - section, so that objcopy can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */ - if (elf_symtab_shndx (abfd) == shindex) - return TRUE; - - BFD_ASSERT (elf_symtab_shndx (abfd) == 0); - elf_symtab_shndx (abfd) = shindex; - elf_tdata (abfd)->symtab_shndx_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr; - return TRUE; - - case SHT_STRTAB: /* A string table */ - if (hdr->bfd_section != NULL) - return TRUE; - if (ehdr->e_shstrndx == shindex) - { - elf_tdata (abfd)->shstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; - return TRUE; - } - if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex) - { - symtab_strtab: - elf_tdata (abfd)->strtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; - return TRUE; - } - if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex) - { - dynsymtab_strtab: - elf_tdata (abfd)->dynstrtab_hdr = *hdr; - hdr = &elf_tdata (abfd)->dynstrtab_hdr; - elf_elfsections (abfd)[shindex] = hdr; - /* We also treat this as a regular section, so that objcopy - can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, - shindex); - } - - /* If the string table isn't one of the above, then treat it as a - regular section. We need to scan all the headers to be sure, - just in case this strtab section appeared before the above. */ - if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0) - { - unsigned int i, num_sec; - - num_sec = elf_numsections (abfd); - for (i = 1; i < num_sec; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_link == shindex) - { - /* Prevent endless recursion on broken objects. */ - if (i == shindex) - return FALSE; - if (! bfd_section_from_shdr (abfd, i)) - return FALSE; - if (elf_onesymtab (abfd) == i) - goto symtab_strtab; - if (elf_dynsymtab (abfd) == i) - goto dynsymtab_strtab; - } - } - } - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_REL: - case SHT_RELA: - /* *These* do a lot of work -- but build no sections! */ - { - asection *target_sect; - Elf_Internal_Shdr *hdr2, **p_hdr; - unsigned int num_sec = elf_numsections (abfd); - struct bfd_elf_section_data *esdt; - bfd_size_type amt; - - if (hdr->sh_entsize - != (bfd_size_type) (hdr->sh_type == SHT_REL - ? bed->s->sizeof_rel : bed->s->sizeof_rela)) - return FALSE; - - /* Check for a bogus link to avoid crashing. */ - if (hdr->sh_link >= num_sec) - { - ((*_bfd_error_handler) - (_("%B: invalid link %lu for reloc section %s (index %u)"), - abfd, hdr->sh_link, name, shindex)); - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, - shindex); - } - - /* For some incomprehensible reason Oracle distributes - libraries for Solaris in which some of the objects have - bogus sh_link fields. It would be nice if we could just - reject them, but, unfortunately, some people need to use - them. We scan through the section headers; if we find only - one suitable symbol table, we clobber the sh_link to point - to it. I hope this doesn't break anything. - - Don't do it on executable nor shared library. */ - if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0 - && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB - && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM) - { - unsigned int scan; - int found; - - found = 0; - for (scan = 1; scan < num_sec; scan++) - { - if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB - || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM) - { - if (found != 0) - { - found = 0; - break; - } - found = scan; - } - } - if (found != 0) - hdr->sh_link = found; - } - - /* Get the symbol table. */ - if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB - || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM) - && ! bfd_section_from_shdr (abfd, hdr->sh_link)) - return FALSE; - - /* If this reloc section does not use the main symbol table we - don't treat it as a reloc section. BFD can't adequately - represent such a section, so at least for now, we don't - try. We just present it as a normal section. We also - can't use it as a reloc section if it points to the null - section, an invalid section, another reloc section, or its - sh_link points to the null section. */ - if (hdr->sh_link != elf_onesymtab (abfd) - || hdr->sh_link == SHN_UNDEF - || hdr->sh_info == SHN_UNDEF - || hdr->sh_info >= num_sec - || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL - || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA) - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, - shindex); - - if (! bfd_section_from_shdr (abfd, hdr->sh_info)) - return FALSE; - target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info); - if (target_sect == NULL) - return FALSE; - - esdt = elf_section_data (target_sect); - if (hdr->sh_type == SHT_RELA) - p_hdr = &esdt->rela.hdr; - else - p_hdr = &esdt->rel.hdr; - - BFD_ASSERT (*p_hdr == NULL); - amt = sizeof (*hdr2); - hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); - if (hdr2 == NULL) - return FALSE; - *hdr2 = *hdr; - *p_hdr = hdr2; - elf_elfsections (abfd)[shindex] = hdr2; - target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr); - target_sect->flags |= SEC_RELOC; - target_sect->relocation = NULL; - target_sect->rel_filepos = hdr->sh_offset; - /* In the section to which the relocations apply, mark whether - its relocations are of the REL or RELA variety. */ - if (hdr->sh_size != 0) - { - if (hdr->sh_type == SHT_RELA) - target_sect->use_rela_p = 1; - } - abfd->flags |= HAS_RELOC; - return TRUE; - } - - case SHT_GNU_verdef: - elf_dynverdef (abfd) = shindex; - elf_tdata (abfd)->dynverdef_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_GNU_versym: - if (hdr->sh_entsize != sizeof (Elf_External_Versym)) - return FALSE; - elf_dynversym (abfd) = shindex; - elf_tdata (abfd)->dynversym_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_GNU_verneed: - elf_dynverref (abfd) = shindex; - elf_tdata (abfd)->dynverref_hdr = *hdr; - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_SHLIB: - return TRUE; - - case SHT_GROUP: - if (! IS_VALID_GROUP_SECTION_HEADER (hdr)) - return FALSE; - if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) - return FALSE; - if (hdr->contents != NULL) - { - Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents; - unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE; - asection *s; - - if (idx->flags & GRP_COMDAT) - hdr->bfd_section->flags - |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - - /* We try to keep the same section order as it comes in. */ - idx += n_elt; - while (--n_elt != 0) - { - --idx; - - if (idx->shdr != NULL - && (s = idx->shdr->bfd_section) != NULL - && elf_next_in_group (s) != NULL) - { - elf_next_in_group (hdr->bfd_section) = s; - break; - } - } - } - break; - - default: - /* Possibly an attributes section. */ - if (hdr->sh_type == SHT_GNU_ATTRIBUTES - || hdr->sh_type == bed->obj_attrs_section_type) - { - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) - return FALSE; - _bfd_elf_parse_attributes (abfd, hdr); - return TRUE; - } - - /* Check for any processor-specific section types. */ - if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex)) - return TRUE; - - if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER) - { - if ((hdr->sh_flags & SHF_ALLOC) != 0) - /* FIXME: How to properly handle allocated section reserved - for applications? */ - (*_bfd_error_handler) - (_("%B: don't know how to handle allocated, application " - "specific section `%s' [0x%8x]"), - abfd, name, hdr->sh_type); - else - /* Allow sections reserved for applications. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, - shindex); - } - else if (hdr->sh_type >= SHT_LOPROC - && hdr->sh_type <= SHT_HIPROC) - /* FIXME: We should handle this section. */ - (*_bfd_error_handler) - (_("%B: don't know how to handle processor specific section " - "`%s' [0x%8x]"), - abfd, name, hdr->sh_type); - else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS) - { - /* Unrecognised OS-specific sections. */ - if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0) - /* SHF_OS_NONCONFORMING indicates that special knowledge is - required to correctly process the section and the file should - be rejected with an error message. */ - (*_bfd_error_handler) - (_("%B: don't know how to handle OS specific section " - "`%s' [0x%8x]"), - abfd, name, hdr->sh_type); - else - /* Otherwise it should be processed. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - } - else - /* FIXME: We should handle this section. */ - (*_bfd_error_handler) - (_("%B: don't know how to handle section `%s' [0x%8x]"), - abfd, name, hdr->sh_type); - - return FALSE; - } - - return TRUE; -} - -/* Return the local symbol specified by ABFD, R_SYMNDX. */ - -Elf_Internal_Sym * -bfd_sym_from_r_symndx (struct sym_cache *cache, - bfd *abfd, - unsigned long r_symndx) -{ - unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE; - - if (cache->abfd != abfd || cache->indx[ent] != r_symndx) - { - Elf_Internal_Shdr *symtab_hdr; - unsigned char esym[sizeof (Elf64_External_Sym)]; - Elf_External_Sym_Shndx eshndx; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx, - &cache->sym[ent], esym, &eshndx) == NULL) - return NULL; - - if (cache->abfd != abfd) - { - memset (cache->indx, -1, sizeof (cache->indx)); - cache->abfd = abfd; - } - cache->indx[ent] = r_symndx; - } - - return &cache->sym[ent]; -} - -/* Given an ELF section number, retrieve the corresponding BFD - section. */ - -asection * -bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index) -{ - if (sec_index >= elf_numsections (abfd)) - return NULL; - return elf_elfsections (abfd)[sec_index]->bfd_section; -} - -static const struct bfd_elf_special_section special_sections_b[] = -{ - { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_c[] = -{ - { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_d[] = -{ - { STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".debug_abbrev"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, SHF_ALLOC }, - { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, SHF_ALLOC }, - { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, SHF_ALLOC }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_f[] = -{ - { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, - { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_g[] = -{ - { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".gnu.lto_"), -1, SHT_PROGBITS, SHF_EXCLUDE }, - { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 }, - { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 }, - { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 }, - { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC }, - { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC }, - { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_h[] = -{ - { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, SHF_ALLOC }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_i[] = -{ - { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, - { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_l[] = -{ - { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_n[] = -{ - { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".note"), -1, SHT_NOTE, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_p[] = -{ - { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE }, - { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_r[] = -{ - { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC }, - { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC }, - { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 }, - { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_s[] = -{ - { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 }, - { STRING_COMMA_LEN (".strtab"), 0, SHT_STRTAB, 0 }, - { STRING_COMMA_LEN (".symtab"), 0, SHT_SYMTAB, 0 }, - /* See struct bfd_elf_special_section declaration for the semantics of - this special case where .prefix_length != strlen (.prefix). */ - { ".stabstr", 5, 3, SHT_STRTAB, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_t[] = -{ - { STRING_COMMA_LEN (".text"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, - { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, - { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section special_sections_z[] = -{ - { STRING_COMMA_LEN (".zdebug_line"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".zdebug_info"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".zdebug_abbrev"), 0, SHT_PROGBITS, 0 }, - { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 }, - { NULL, 0, 0, 0, 0 } -}; - -static const struct bfd_elf_special_section * const special_sections[] = -{ - special_sections_b, /* 'b' */ - special_sections_c, /* 'c' */ - special_sections_d, /* 'd' */ - NULL, /* 'e' */ - special_sections_f, /* 'f' */ - special_sections_g, /* 'g' */ - special_sections_h, /* 'h' */ - special_sections_i, /* 'i' */ - NULL, /* 'j' */ - NULL, /* 'k' */ - special_sections_l, /* 'l' */ - NULL, /* 'm' */ - special_sections_n, /* 'n' */ - NULL, /* 'o' */ - special_sections_p, /* 'p' */ - NULL, /* 'q' */ - special_sections_r, /* 'r' */ - special_sections_s, /* 's' */ - special_sections_t, /* 't' */ - NULL, /* 'u' */ - NULL, /* 'v' */ - NULL, /* 'w' */ - NULL, /* 'x' */ - NULL, /* 'y' */ - special_sections_z /* 'z' */ -}; - -const struct bfd_elf_special_section * -_bfd_elf_get_special_section (const char *name, - const struct bfd_elf_special_section *spec, - unsigned int rela) -{ - int i; - int len; - - len = strlen (name); - - for (i = 0; spec[i].prefix != NULL; i++) - { - int suffix_len; - int prefix_len = spec[i].prefix_length; - - if (len < prefix_len) - continue; - if (memcmp (name, spec[i].prefix, prefix_len) != 0) - continue; - - suffix_len = spec[i].suffix_length; - if (suffix_len <= 0) - { - if (name[prefix_len] != 0) - { - if (suffix_len == 0) - continue; - if (name[prefix_len] != '.' - && (suffix_len == -2 - || (rela && spec[i].type == SHT_REL))) - continue; - } - } - else - { - if (len < prefix_len + suffix_len) - continue; - if (memcmp (name + len - suffix_len, - spec[i].prefix + prefix_len, - suffix_len) != 0) - continue; - } - return &spec[i]; - } - - return NULL; -} - -const struct bfd_elf_special_section * -_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) -{ - int i; - const struct bfd_elf_special_section *spec; - const struct elf_backend_data *bed; - - /* See if this is one of the special sections. */ - if (sec->name == NULL) - return NULL; - - bed = get_elf_backend_data (abfd); - spec = bed->special_sections; - if (spec) - { - spec = _bfd_elf_get_special_section (sec->name, - bed->special_sections, - sec->use_rela_p); - if (spec != NULL) - return spec; - } - - if (sec->name[0] != '.') - return NULL; - - i = sec->name[1] - 'b'; - if (i < 0 || i > 'z' - 'b') - return NULL; - - spec = special_sections[i]; - - if (spec == NULL) - return NULL; - - return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p); -} - -bfd_boolean -_bfd_elf_new_section_hook (bfd *abfd, asection *sec) -{ - struct bfd_elf_section_data *sdata; - const struct elf_backend_data *bed; - const struct bfd_elf_special_section *ssect; - - sdata = (struct bfd_elf_section_data *) sec->used_by_bfd; - if (sdata == NULL) - { - sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, - sizeof (*sdata)); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = sdata; - } - - /* Indicate whether or not this section should use RELA relocations. */ - bed = get_elf_backend_data (abfd); - sec->use_rela_p = bed->default_use_rela_p; - - /* When we read a file, we don't need to set ELF section type and - flags. They will be overridden in _bfd_elf_make_section_from_shdr - anyway. We will set ELF section type and flags for all linker - created sections. If user specifies BFD section flags, we will - set ELF section type and flags based on BFD section flags in - elf_fake_sections. Special handling for .init_array/.fini_array - output sections since they may contain .ctors/.dtors input - sections. We don't want _bfd_elf_init_private_section_data to - copy ELF section type from .ctors/.dtors input sections. */ - if (abfd->direction != read_direction - || (sec->flags & SEC_LINKER_CREATED) != 0) - { - ssect = (*bed->get_sec_type_attr) (abfd, sec); - if (ssect != NULL - && (!sec->flags - || (sec->flags & SEC_LINKER_CREATED) != 0 - || ssect->type == SHT_INIT_ARRAY - || ssect->type == SHT_FINI_ARRAY)) - { - elf_section_type (sec) = ssect->type; - elf_section_flags (sec) = ssect->attr; - } - } - - return _bfd_generic_new_section_hook (abfd, sec); -} - -/* Create a new bfd section from an ELF program header. - - Since program segments have no names, we generate a synthetic name - of the form segment, where NUM is generally the index in the - program header table. For segments that are split (see below) we - generate the names segmenta and segmentb. - - Note that some program segments may have a file size that is different than - (less than) the memory size. All this means is that at execution the - system must allocate the amount of memory specified by the memory size, - but only initialize it with the first "file size" bytes read from the - file. This would occur for example, with program segments consisting - of combined data+bss. - - To handle the above situation, this routine generates TWO bfd sections - for the single program segment. The first has the length specified by - the file size of the segment, and the second has the length specified - by the difference between the two sizes. In effect, the segment is split - into its initialized and uninitialized parts. - - */ - -bfd_boolean -_bfd_elf_make_section_from_phdr (bfd *abfd, - Elf_Internal_Phdr *hdr, - int hdr_index, - const char *type_name) -{ - asection *newsect; - char *name; - char namebuf[64]; - size_t len; - int split; - - split = ((hdr->p_memsz > 0) - && (hdr->p_filesz > 0) - && (hdr->p_memsz > hdr->p_filesz)); - - if (hdr->p_filesz > 0) - { - sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : ""); - len = strlen (namebuf) + 1; - name = (char *) bfd_alloc (abfd, len); - if (!name) - return FALSE; - memcpy (name, namebuf, len); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return FALSE; - newsect->vma = hdr->p_vaddr; - newsect->lma = hdr->p_paddr; - newsect->size = hdr->p_filesz; - newsect->filepos = hdr->p_offset; - newsect->flags |= SEC_HAS_CONTENTS; - newsect->alignment_power = bfd_log2 (hdr->p_align); - if (hdr->p_type == PT_LOAD) - { - newsect->flags |= SEC_ALLOC; - newsect->flags |= SEC_LOAD; - if (hdr->p_flags & PF_X) - { - /* FIXME: all we known is that it has execute PERMISSION, - may be data. */ - newsect->flags |= SEC_CODE; - } - } - if (!(hdr->p_flags & PF_W)) - { - newsect->flags |= SEC_READONLY; - } - } - - if (hdr->p_memsz > hdr->p_filesz) - { - bfd_vma align; - - sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : ""); - len = strlen (namebuf) + 1; - name = (char *) bfd_alloc (abfd, len); - if (!name) - return FALSE; - memcpy (name, namebuf, len); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return FALSE; - newsect->vma = hdr->p_vaddr + hdr->p_filesz; - newsect->lma = hdr->p_paddr + hdr->p_filesz; - newsect->size = hdr->p_memsz - hdr->p_filesz; - newsect->filepos = hdr->p_offset + hdr->p_filesz; - align = newsect->vma & -newsect->vma; - if (align == 0 || align > hdr->p_align) - align = hdr->p_align; - newsect->alignment_power = bfd_log2 (align); - if (hdr->p_type == PT_LOAD) - { - /* Hack for gdb. Segments that have not been modified do - not have their contents written to a core file, on the - assumption that a debugger can find the contents in the - executable. We flag this case by setting the fake - section size to zero. Note that "real" bss sections will - always have their contents dumped to the core file. */ - if (bfd_get_format (abfd) == bfd_core) - newsect->size = 0; - newsect->flags |= SEC_ALLOC; - if (hdr->p_flags & PF_X) - newsect->flags |= SEC_CODE; - } - if (!(hdr->p_flags & PF_W)) - newsect->flags |= SEC_READONLY; - } - - return TRUE; -} - -bfd_boolean -bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index) -{ - const struct elf_backend_data *bed; - - switch (hdr->p_type) - { - case PT_NULL: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null"); - - case PT_LOAD: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load"); - - case PT_DYNAMIC: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic"); - - case PT_INTERP: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp"); - - case PT_NOTE: - if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note")) - return FALSE; - if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz)) - return FALSE; - return TRUE; - - case PT_SHLIB: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib"); - - case PT_PHDR: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr"); - - case PT_GNU_EH_FRAME: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, - "eh_frame_hdr"); - - case PT_GNU_STACK: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack"); - - case PT_GNU_RELRO: - return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro"); - - default: - /* Check for any processor-specific program segment types. */ - bed = get_elf_backend_data (abfd); - return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc"); - } -} - -/* Return the REL_HDR for SEC, assuming there is only a single one, either - REL or RELA. */ - -Elf_Internal_Shdr * -_bfd_elf_single_rel_hdr (asection *sec) -{ - if (elf_section_data (sec)->rel.hdr) - { - BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL); - return elf_section_data (sec)->rel.hdr; - } - else - return elf_section_data (sec)->rela.hdr; -} - -/* Allocate and initialize a section-header for a new reloc section, - containing relocations against ASECT. It is stored in RELDATA. If - USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL - relocations. */ - -bfd_boolean -_bfd_elf_init_reloc_shdr (bfd *abfd, - struct bfd_elf_section_reloc_data *reldata, - asection *asect, - bfd_boolean use_rela_p) -{ - Elf_Internal_Shdr *rel_hdr; - char *name; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_size_type amt; - - amt = sizeof (Elf_Internal_Shdr); - BFD_ASSERT (reldata->hdr == NULL); - rel_hdr = bfd_zalloc (abfd, amt); - reldata->hdr = rel_hdr; - - amt = sizeof ".rela" + strlen (asect->name); - name = (char *) bfd_alloc (abfd, amt); - if (name == NULL) - return FALSE; - sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name); - rel_hdr->sh_name = - (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name, - FALSE); - if (rel_hdr->sh_name == (unsigned int) -1) - return FALSE; - rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; - rel_hdr->sh_entsize = (use_rela_p - ? bed->s->sizeof_rela - : bed->s->sizeof_rel); - rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; - rel_hdr->sh_flags = 0; - rel_hdr->sh_addr = 0; - rel_hdr->sh_size = 0; - rel_hdr->sh_offset = 0; - - return TRUE; -} - -/* Return the default section type based on the passed in section flags. */ - -int -bfd_elf_get_default_section_type (flagword flags) -{ - if ((flags & SEC_ALLOC) != 0 - && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - return SHT_NOBITS; - return SHT_PROGBITS; -} - -struct fake_section_arg -{ - struct bfd_link_info *link_info; - bfd_boolean failed; -}; - -/* Set up an ELF internal section header for a section. */ - -static void -elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) -{ - struct fake_section_arg *arg = (struct fake_section_arg *)fsarg; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct bfd_elf_section_data *esd = elf_section_data (asect); - Elf_Internal_Shdr *this_hdr; - unsigned int sh_type; - - if (arg->failed) - { - /* We already failed; just get out of the bfd_map_over_sections - loop. */ - return; - } - - this_hdr = &esd->this_hdr; - - this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), - asect->name, FALSE); - if (this_hdr->sh_name == (unsigned int) -1) - { - arg->failed = TRUE; - return; - } - - /* Don't clear sh_flags. Assembler may set additional bits. */ - - if ((asect->flags & SEC_ALLOC) != 0 - || asect->user_set_vma) - this_hdr->sh_addr = asect->vma; - else - this_hdr->sh_addr = 0; - - this_hdr->sh_offset = 0; - this_hdr->sh_size = asect->size; - this_hdr->sh_link = 0; - this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power; - /* The sh_entsize and sh_info fields may have been set already by - copy_private_section_data. */ - - this_hdr->bfd_section = asect; - this_hdr->contents = NULL; - - /* If the section type is unspecified, we set it based on - asect->flags. */ - if ((asect->flags & SEC_GROUP) != 0) - sh_type = SHT_GROUP; - else - sh_type = bfd_elf_get_default_section_type (asect->flags); - - if (this_hdr->sh_type == SHT_NULL) - this_hdr->sh_type = sh_type; - else if (this_hdr->sh_type == SHT_NOBITS - && sh_type == SHT_PROGBITS - && (asect->flags & SEC_ALLOC) != 0) - { - /* Warn if we are changing a NOBITS section to PROGBITS, but - allow the link to proceed. This can happen when users link - non-bss input sections to bss output sections, or emit data - to a bss output section via a linker script. */ - (*_bfd_error_handler) - (_("warning: section `%A' type changed to PROGBITS"), asect); - this_hdr->sh_type = sh_type; - } - - switch (this_hdr->sh_type) - { - default: - break; - - case SHT_STRTAB: - case SHT_INIT_ARRAY: - case SHT_FINI_ARRAY: - case SHT_PREINIT_ARRAY: - case SHT_NOTE: - case SHT_NOBITS: - case SHT_PROGBITS: - break; - - case SHT_HASH: - this_hdr->sh_entsize = bed->s->sizeof_hash_entry; - break; - - case SHT_DYNSYM: - this_hdr->sh_entsize = bed->s->sizeof_sym; - break; - - case SHT_DYNAMIC: - this_hdr->sh_entsize = bed->s->sizeof_dyn; - break; - - case SHT_RELA: - if (get_elf_backend_data (abfd)->may_use_rela_p) - this_hdr->sh_entsize = bed->s->sizeof_rela; - break; - - case SHT_REL: - if (get_elf_backend_data (abfd)->may_use_rel_p) - this_hdr->sh_entsize = bed->s->sizeof_rel; - break; - - case SHT_GNU_versym: - this_hdr->sh_entsize = sizeof (Elf_External_Versym); - break; - - case SHT_GNU_verdef: - this_hdr->sh_entsize = 0; - /* objcopy or strip will copy over sh_info, but may not set - cverdefs. The linker will set cverdefs, but sh_info will be - zero. */ - if (this_hdr->sh_info == 0) - this_hdr->sh_info = elf_tdata (abfd)->cverdefs; - else - BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0 - || this_hdr->sh_info == elf_tdata (abfd)->cverdefs); - break; - - case SHT_GNU_verneed: - this_hdr->sh_entsize = 0; - /* objcopy or strip will copy over sh_info, but may not set - cverrefs. The linker will set cverrefs, but sh_info will be - zero. */ - if (this_hdr->sh_info == 0) - this_hdr->sh_info = elf_tdata (abfd)->cverrefs; - else - BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0 - || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); - break; - - case SHT_GROUP: - this_hdr->sh_entsize = GRP_ENTRY_SIZE; - break; - - case SHT_GNU_HASH: - this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4; - break; - } - - if ((asect->flags & SEC_ALLOC) != 0) - this_hdr->sh_flags |= SHF_ALLOC; - if ((asect->flags & SEC_READONLY) == 0) - this_hdr->sh_flags |= SHF_WRITE; - if ((asect->flags & SEC_CODE) != 0) - this_hdr->sh_flags |= SHF_EXECINSTR; - if ((asect->flags & SEC_MERGE) != 0) - { - this_hdr->sh_flags |= SHF_MERGE; - this_hdr->sh_entsize = asect->entsize; - if ((asect->flags & SEC_STRINGS) != 0) - this_hdr->sh_flags |= SHF_STRINGS; - } - if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL) - this_hdr->sh_flags |= SHF_GROUP; - if ((asect->flags & SEC_THREAD_LOCAL) != 0) - { - this_hdr->sh_flags |= SHF_TLS; - if (asect->size == 0 - && (asect->flags & SEC_HAS_CONTENTS) == 0) - { - struct bfd_link_order *o = asect->map_tail.link_order; - - this_hdr->sh_size = 0; - if (o != NULL) - { - this_hdr->sh_size = o->offset + o->size; - if (this_hdr->sh_size != 0) - this_hdr->sh_type = SHT_NOBITS; - } - } - } - if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE) - this_hdr->sh_flags |= SHF_EXCLUDE; - - /* If the section has relocs, set up a section header for the - SHT_REL[A] section. If two relocation sections are required for - this section, it is up to the processor-specific back-end to - create the other. */ - if ((asect->flags & SEC_RELOC) != 0) - { - /* When doing a relocatable link, create both REL and RELA sections if - needed. */ - if (arg->link_info - /* Do the normal setup if we wouldn't create any sections here. */ - && esd->rel.count + esd->rela.count > 0 - && (arg->link_info->relocatable || arg->link_info->emitrelocations)) - { - if (esd->rel.count && esd->rel.hdr == NULL - && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE)) - { - arg->failed = TRUE; - return; - } - if (esd->rela.count && esd->rela.hdr == NULL - && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE)) - { - arg->failed = TRUE; - return; - } - } - else if (!_bfd_elf_init_reloc_shdr (abfd, - (asect->use_rela_p - ? &esd->rela : &esd->rel), - asect, - asect->use_rela_p)) - arg->failed = TRUE; - } - - /* Check for processor-specific section types. */ - sh_type = this_hdr->sh_type; - if (bed->elf_backend_fake_sections - && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect)) - arg->failed = TRUE; - - if (sh_type == SHT_NOBITS && asect->size != 0) - { - /* Don't change the header type from NOBITS if we are being - called for objcopy --only-keep-debug. */ - this_hdr->sh_type = sh_type; - } -} - -/* Fill in the contents of a SHT_GROUP section. Called from - _bfd_elf_compute_section_file_positions for gas, objcopy, and - when ELF targets use the generic linker, ld. Called for ld -r - from bfd_elf_final_link. */ - -void -bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) -{ - bfd_boolean *failedptr = (bfd_boolean *) failedptrarg; - asection *elt, *first; - unsigned char *loc; - bfd_boolean gas; - - /* Ignore linker created group section. See elfNN_ia64_object_p in - elfxx-ia64.c. */ - if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP) - || *failedptr) - return; - - if (elf_section_data (sec)->this_hdr.sh_info == 0) - { - unsigned long symindx = 0; - - /* elf_group_id will have been set up by objcopy and the - generic linker. */ - if (elf_group_id (sec) != NULL) - symindx = elf_group_id (sec)->udata.i; - - if (symindx == 0) - { - /* If called from the assembler, swap_out_syms will have set up - elf_section_syms. */ - BFD_ASSERT (elf_section_syms (abfd) != NULL); - symindx = elf_section_syms (abfd)[sec->index]->udata.i; - } - elf_section_data (sec)->this_hdr.sh_info = symindx; - } - else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2) - { - /* The ELF backend linker sets sh_info to -2 when the group - signature symbol is global, and thus the index can't be - set until all local symbols are output. */ - asection *igroup = elf_sec_group (elf_next_in_group (sec)); - struct bfd_elf_section_data *sec_data = elf_section_data (igroup); - unsigned long symndx = sec_data->this_hdr.sh_info; - unsigned long extsymoff = 0; - struct elf_link_hash_entry *h; - - if (!elf_bad_symtab (igroup->owner)) - { - Elf_Internal_Shdr *symtab_hdr; - - symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr; - extsymoff = symtab_hdr->sh_info; - } - h = elf_sym_hashes (igroup->owner)[symndx - extsymoff]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - elf_section_data (sec)->this_hdr.sh_info = h->indx; - } - - /* The contents won't be allocated for "ld -r" or objcopy. */ - gas = TRUE; - if (sec->contents == NULL) - { - gas = FALSE; - sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size); - - /* Arrange for the section to be written out. */ - elf_section_data (sec)->this_hdr.contents = sec->contents; - if (sec->contents == NULL) - { - *failedptr = TRUE; - return; - } - } - - loc = sec->contents + sec->size; - - /* Get the pointer to the first section in the group that gas - squirreled away here. objcopy arranges for this to be set to the - start of the input section group. */ - first = elt = elf_next_in_group (sec); - - /* First element is a flag word. Rest of section is elf section - indices for all the sections of the group. Write them backwards - just to keep the group in the same order as given in .section - directives, not that it matters. */ - while (elt != NULL) - { - asection *s; - - s = elt; - if (!gas) - s = s->output_section; - if (s != NULL - && !bfd_is_abs_section (s)) - { - unsigned int idx = elf_section_data (s)->this_idx; - - loc -= 4; - H_PUT_32 (abfd, idx, loc); - } - elt = elf_next_in_group (elt); - if (elt == first) - break; - } - - if ((loc -= 4) != sec->contents) - abort (); - - H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc); -} - -/* Assign all ELF section numbers. The dummy first section is handled here - too. The link/info pointers for the standard section types are filled - in here too, while we're at it. */ - -static bfd_boolean -assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) -{ - struct elf_obj_tdata *t = elf_tdata (abfd); - asection *sec; - unsigned int section_number, secn; - Elf_Internal_Shdr **i_shdrp; - struct bfd_elf_section_data *d; - bfd_boolean need_symtab; - - section_number = 1; - - _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd)); - - /* SHT_GROUP sections are in relocatable files only. */ - if (link_info == NULL || link_info->relocatable) - { - /* Put SHT_GROUP sections first. */ - for (sec = abfd->sections; sec != NULL; sec = sec->next) - { - d = elf_section_data (sec); - - if (d->this_hdr.sh_type == SHT_GROUP) - { - if (sec->flags & SEC_LINKER_CREATED) - { - /* Remove the linker created SHT_GROUP sections. */ - bfd_section_list_remove (abfd, sec); - abfd->section_count--; - } - else - d->this_idx = section_number++; - } - } - } - - for (sec = abfd->sections; sec; sec = sec->next) - { - d = elf_section_data (sec); - - if (d->this_hdr.sh_type != SHT_GROUP) - d->this_idx = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name); - if (d->rel.hdr) - { - d->rel.idx = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name); - } - else - d->rel.idx = 0; - - if (d->rela.hdr) - { - d->rela.idx = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name); - } - else - d->rela.idx = 0; - } - - t->shstrtab_section = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name); - elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; - - need_symtab = (bfd_get_symcount (abfd) > 0 - || (link_info == NULL - && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC)) - == HAS_RELOC))); - if (need_symtab) - { - t->symtab_section = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); - if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF)) - { - t->symtab_shndx_section = section_number++; - t->symtab_shndx_hdr.sh_name - = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), - ".symtab_shndx", FALSE); - if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1) - return FALSE; - } - t->strtab_section = section_number++; - _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name); - } - - _bfd_elf_strtab_finalize (elf_shstrtab (abfd)); - t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); - - elf_numsections (abfd) = section_number; - elf_elfheader (abfd)->e_shnum = section_number; - - /* Set up the list of section header pointers, in agreement with the - indices. */ - i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc2 (abfd, section_number, - sizeof (Elf_Internal_Shdr *)); - if (i_shdrp == NULL) - return FALSE; - - i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd, - sizeof (Elf_Internal_Shdr)); - if (i_shdrp[0] == NULL) - { - bfd_release (abfd, i_shdrp); - return FALSE; - } - - elf_elfsections (abfd) = i_shdrp; - - i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr; - if (need_symtab) - { - i_shdrp[t->symtab_section] = &t->symtab_hdr; - if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) - { - i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr; - t->symtab_shndx_hdr.sh_link = t->symtab_section; - } - i_shdrp[t->strtab_section] = &t->strtab_hdr; - t->symtab_hdr.sh_link = t->strtab_section; - } - - for (sec = abfd->sections; sec; sec = sec->next) - { - asection *s; - const char *name; - - d = elf_section_data (sec); - - i_shdrp[d->this_idx] = &d->this_hdr; - if (d->rel.idx != 0) - i_shdrp[d->rel.idx] = d->rel.hdr; - if (d->rela.idx != 0) - i_shdrp[d->rela.idx] = d->rela.hdr; - - /* Fill in the sh_link and sh_info fields while we're at it. */ - - /* sh_link of a reloc section is the section index of the symbol - table. sh_info is the section index of the section to which - the relocation entries apply. */ - if (d->rel.idx != 0) - { - d->rel.hdr->sh_link = t->symtab_section; - d->rel.hdr->sh_info = d->this_idx; - } - if (d->rela.idx != 0) - { - d->rela.hdr->sh_link = t->symtab_section; - d->rela.hdr->sh_info = d->this_idx; - } - - /* We need to set up sh_link for SHF_LINK_ORDER. */ - if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0) - { - s = elf_linked_to_section (sec); - if (s) - { - /* elf_linked_to_section points to the input section. */ - if (link_info != NULL) - { - /* Check discarded linkonce section. */ - if (elf_discarded_section (s)) - { - asection *kept; - (*_bfd_error_handler) - (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"), - abfd, d->this_hdr.bfd_section, - s, s->owner); - /* Point to the kept section if it has the same - size as the discarded one. */ - kept = _bfd_elf_check_kept_section (s, link_info); - if (kept == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - s = kept; - } - - s = s->output_section; - BFD_ASSERT (s != NULL); - } - else - { - /* Handle objcopy. */ - if (s->output_section == NULL) - { - (*_bfd_error_handler) - (_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"), - abfd, d->this_hdr.bfd_section, s, s->owner); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - s = s->output_section; - } - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - } - else - { - /* PR 290: - The Intel C compiler generates SHT_IA_64_UNWIND with - SHF_LINK_ORDER. But it doesn't set the sh_link or - sh_info fields. Hence we could get the situation - where s is NULL. */ - const struct elf_backend_data *bed - = get_elf_backend_data (abfd); - if (bed->link_order_error_handler) - bed->link_order_error_handler - (_("%B: warning: sh_link not set for section `%A'"), - abfd, sec); - } - } - - switch (d->this_hdr.sh_type) - { - case SHT_REL: - case SHT_RELA: - /* A reloc section which we are treating as a normal BFD - section. sh_link is the section index of the symbol - table. sh_info is the section index of the section to - which the relocation entries apply. We assume that an - allocated reloc section uses the dynamic symbol table. - FIXME: How can we be sure? */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - - /* We look up the section the relocs apply to by name. */ - name = sec->name; - if (d->this_hdr.sh_type == SHT_REL) - name += 4; - else - name += 5; - s = bfd_get_section_by_name (abfd, name); - if (s != NULL) - d->this_hdr.sh_info = elf_section_data (s)->this_idx; - break; - - case SHT_STRTAB: - /* We assume that a section named .stab*str is a stabs - string section. We look for a section with the same name - but without the trailing ``str'', and set its sh_link - field to point to this section. */ - if (CONST_STRNEQ (sec->name, ".stab") - && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0) - { - size_t len; - char *alc; - - len = strlen (sec->name); - alc = (char *) bfd_malloc (len - 2); - if (alc == NULL) - return FALSE; - memcpy (alc, sec->name, len - 3); - alc[len - 3] = '\0'; - s = bfd_get_section_by_name (abfd, alc); - free (alc); - if (s != NULL) - { - elf_section_data (s)->this_hdr.sh_link = d->this_idx; - - /* This is a .stab section. */ - if (elf_section_data (s)->this_hdr.sh_entsize == 0) - elf_section_data (s)->this_hdr.sh_entsize - = 4 + 2 * bfd_get_arch_size (abfd) / 8; - } - } - break; - - case SHT_DYNAMIC: - case SHT_DYNSYM: - case SHT_GNU_verneed: - case SHT_GNU_verdef: - /* sh_link is the section header index of the string table - used for the dynamic entries, or the symbol table, or the - version strings. */ - s = bfd_get_section_by_name (abfd, ".dynstr"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - - case SHT_GNU_LIBLIST: - /* sh_link is the section header index of the prelink library - list used for the dynamic entries, or the symbol table, or - the version strings. */ - s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC) - ? ".dynstr" : ".gnu.libstr"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - - case SHT_HASH: - case SHT_GNU_HASH: - case SHT_GNU_versym: - /* sh_link is the section header index of the symbol table - this hash table or version table is for. */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - - case SHT_GROUP: - d->this_hdr.sh_link = t->symtab_section; - } - } - - for (secn = 1; secn < section_number; ++secn) - if (i_shdrp[secn] == NULL) - i_shdrp[secn] = i_shdrp[0]; - else - i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd), - i_shdrp[secn]->sh_name); - return TRUE; -} - -/* Map symbol from it's internal number to the external number, moving - all local symbols to be at the head of the list. */ - -static bfd_boolean -sym_is_global (bfd *abfd, asymbol *sym) -{ - /* If the backend has a special mapping, use it. */ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - if (bed->elf_backend_sym_is_global) - return (*bed->elf_backend_sym_is_global) (abfd, sym); - - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym))); -} - -/* Don't output section symbols for sections that are not going to be - output. */ - -static bfd_boolean -ignore_section_sym (bfd *abfd, asymbol *sym) -{ - return ((sym->flags & BSF_SECTION_SYM) != 0 - && !(sym->section->owner == abfd - || (sym->section->output_section->owner == abfd - && sym->section->output_offset == 0))); -} - -static bfd_boolean -elf_map_symbols (bfd *abfd) -{ - unsigned int symcount = bfd_get_symcount (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - asymbol **sect_syms; - unsigned int num_locals = 0; - unsigned int num_globals = 0; - unsigned int num_locals2 = 0; - unsigned int num_globals2 = 0; - int max_index = 0; - unsigned int idx; - asection *asect; - asymbol **new_syms; - -#ifdef DEBUG - fprintf (stderr, "elf_map_symbols\n"); - fflush (stderr); -#endif - - for (asect = abfd->sections; asect; asect = asect->next) - { - if (max_index < asect->index) - max_index = asect->index; - } - - max_index++; - sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *)); - if (sect_syms == NULL) - return FALSE; - elf_section_syms (abfd) = sect_syms; - elf_num_section_syms (abfd) = max_index; - - /* Init sect_syms entries for any section symbols we have already - decided to output. */ - for (idx = 0; idx < symcount; idx++) - { - asymbol *sym = syms[idx]; - - if ((sym->flags & BSF_SECTION_SYM) != 0 - && sym->value == 0 - && !ignore_section_sym (abfd, sym)) - { - asection *sec = sym->section; - - if (sec->owner != abfd) - sec = sec->output_section; - - sect_syms[sec->index] = syms[idx]; - } - } - - /* Classify all of the symbols. */ - for (idx = 0; idx < symcount; idx++) - { - if (ignore_section_sym (abfd, syms[idx])) - continue; - if (!sym_is_global (abfd, syms[idx])) - num_locals++; - else - num_globals++; - } - - /* We will be adding a section symbol for each normal BFD section. Most - sections will already have a section symbol in outsymbols, but - eg. SHT_GROUP sections will not, and we need the section symbol mapped - at least in that case. */ - for (asect = abfd->sections; asect; asect = asect->next) - { - if (sect_syms[asect->index] == NULL) - { - if (!sym_is_global (abfd, asect->symbol)) - num_locals++; - else - num_globals++; - } - } - - /* Now sort the symbols so the local symbols are first. */ - new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals, - sizeof (asymbol *)); - - if (new_syms == NULL) - return FALSE; - - for (idx = 0; idx < symcount; idx++) - { - asymbol *sym = syms[idx]; - unsigned int i; - - if (ignore_section_sym (abfd, sym)) - continue; - if (!sym_is_global (abfd, sym)) - i = num_locals2++; - else - i = num_locals + num_globals2++; - new_syms[i] = sym; - sym->udata.i = i + 1; - } - for (asect = abfd->sections; asect; asect = asect->next) - { - if (sect_syms[asect->index] == NULL) - { - asymbol *sym = asect->symbol; - unsigned int i; - - sect_syms[asect->index] = sym; - if (!sym_is_global (abfd, sym)) - i = num_locals2++; - else - i = num_locals + num_globals2++; - new_syms[i] = sym; - sym->udata.i = i + 1; - } - } - - bfd_set_symtab (abfd, new_syms, num_locals + num_globals); - - elf_num_locals (abfd) = num_locals; - elf_num_globals (abfd) = num_globals; - return TRUE; -} - -/* Align to the maximum file alignment that could be required for any - ELF data structure. */ - -static inline file_ptr -align_file_position (file_ptr off, int align) -{ - return (off + align - 1) & ~(align - 1); -} - -/* Assign a file position to a section, optionally aligning to the - required section alignment. */ - -file_ptr -_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp, - file_ptr offset, - bfd_boolean align) -{ - if (align && i_shdrp->sh_addralign > 1) - offset = BFD_ALIGN (offset, i_shdrp->sh_addralign); - i_shdrp->sh_offset = offset; - if (i_shdrp->bfd_section != NULL) - i_shdrp->bfd_section->filepos = offset; - if (i_shdrp->sh_type != SHT_NOBITS) - offset += i_shdrp->sh_size; - return offset; -} - -/* Compute the file positions we are going to put the sections at, and - otherwise prepare to begin writing out the ELF file. If LINK_INFO - is not NULL, this is being called by the ELF backend linker. */ - -bfd_boolean -_bfd_elf_compute_section_file_positions (bfd *abfd, - struct bfd_link_info *link_info) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct fake_section_arg fsargs; - bfd_boolean failed; - struct bfd_strtab_hash *strtab = NULL; - Elf_Internal_Shdr *shstrtab_hdr; - bfd_boolean need_symtab; - - if (abfd->output_has_begun) - return TRUE; - - /* Do any elf backend specific processing first. */ - if (bed->elf_backend_begin_write_processing) - (*bed->elf_backend_begin_write_processing) (abfd, link_info); - - if (! prep_headers (abfd)) - return FALSE; - - /* Post process the headers if necessary. */ - if (bed->elf_backend_post_process_headers) - (*bed->elf_backend_post_process_headers) (abfd, link_info); - - fsargs.failed = FALSE; - fsargs.link_info = link_info; - bfd_map_over_sections (abfd, elf_fake_sections, &fsargs); - if (fsargs.failed) - return FALSE; - - if (!assign_section_numbers (abfd, link_info)) - return FALSE; - - /* The backend linker builds symbol table information itself. */ - need_symtab = (link_info == NULL - && (bfd_get_symcount (abfd) > 0 - || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC)) - == HAS_RELOC))); - if (need_symtab) - { - /* Non-zero if doing a relocatable link. */ - int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC)); - - if (! swap_out_syms (abfd, &strtab, relocatable_p)) - return FALSE; - } - - failed = FALSE; - if (link_info == NULL) - { - bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); - if (failed) - return FALSE; - } - - shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; - /* sh_name was set in prep_headers. */ - shstrtab_hdr->sh_type = SHT_STRTAB; - shstrtab_hdr->sh_flags = 0; - shstrtab_hdr->sh_addr = 0; - shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd)); - shstrtab_hdr->sh_entsize = 0; - shstrtab_hdr->sh_link = 0; - shstrtab_hdr->sh_info = 0; - /* sh_offset is set in assign_file_positions_except_relocs. */ - shstrtab_hdr->sh_addralign = 1; - - if (!assign_file_positions_except_relocs (abfd, link_info)) - return FALSE; - - if (need_symtab) - { - file_ptr off; - Elf_Internal_Shdr *hdr; - - off = elf_tdata (abfd)->next_file_pos; - - hdr = &elf_tdata (abfd)->symtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - hdr = &elf_tdata (abfd)->symtab_shndx_hdr; - if (hdr->sh_size != 0) - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - hdr = &elf_tdata (abfd)->strtab_hdr; - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - - elf_tdata (abfd)->next_file_pos = off; - - /* Now that we know where the .strtab section goes, write it - out. */ - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, strtab)) - return FALSE; - _bfd_stringtab_free (strtab); - } - - abfd->output_has_begun = TRUE; - - return TRUE; -} - -/* Make an initial estimate of the size of the program header. If we - get the number wrong here, we'll redo section placement. */ - -static bfd_size_type -get_program_header_size (bfd *abfd, struct bfd_link_info *info) -{ - size_t segs; - asection *s; - const struct elf_backend_data *bed; - - /* Assume we will need exactly two PT_LOAD segments: one for text - and one for data. */ - segs = 2; - - s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - /* If we have a loadable interpreter section, we need a - PT_INTERP segment. In this case, assume we also need a - PT_PHDR segment, although that may not be true for all - targets. */ - segs += 2; - } - - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) - { - /* We need a PT_DYNAMIC segment. */ - ++segs; - } - - if (info != NULL && info->relro) - { - /* We need a PT_GNU_RELRO segment. */ - ++segs; - } - - if (elf_tdata (abfd)->eh_frame_hdr) - { - /* We need a PT_GNU_EH_FRAME segment. */ - ++segs; - } - - if (elf_tdata (abfd)->stack_flags) - { - /* We need a PT_GNU_STACK segment. */ - ++segs; - } - - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_LOAD) != 0 - && CONST_STRNEQ (s->name, ".note")) - { - /* We need a PT_NOTE segment. */ - ++segs; - /* Try to create just one PT_NOTE segment - for all adjacent loadable .note* sections. - gABI requires that within a PT_NOTE segment - (and also inside of each SHT_NOTE section) - each note is padded to a multiple of 4 size, - so we check whether the sections are correctly - aligned. */ - if (s->alignment_power == 2) - while (s->next != NULL - && s->next->alignment_power == 2 - && (s->next->flags & SEC_LOAD) != 0 - && CONST_STRNEQ (s->next->name, ".note")) - s = s->next; - } - } - - for (s = abfd->sections; s != NULL; s = s->next) - { - if (s->flags & SEC_THREAD_LOCAL) - { - /* We need a PT_TLS segment. */ - ++segs; - break; - } - } - - /* Let the backend count up any program headers it might need. */ - bed = get_elf_backend_data (abfd); - if (bed->elf_backend_additional_program_headers) - { - int a; - - a = (*bed->elf_backend_additional_program_headers) (abfd, info); - if (a == -1) - abort (); - segs += a; - } - - return segs * bed->s->sizeof_phdr; -} - -/* Find the segment that contains the output_section of section. */ - -Elf_Internal_Phdr * -_bfd_elf_find_segment_containing_section (bfd * abfd, asection * section) -{ - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - for (m = elf_tdata (abfd)->segment_map, - p = elf_tdata (abfd)->phdr; - m != NULL; - m = m->next, p++) - { - int i; - - for (i = m->count - 1; i >= 0; i--) - if (m->sections[i] == section) - return p; - } - - return NULL; -} - -/* Create a mapping from a set of sections to a program segment. */ - -static struct elf_segment_map * -make_mapping (bfd *abfd, - asection **sections, - unsigned int from, - unsigned int to, - bfd_boolean phdr) -{ - struct elf_segment_map *m; - unsigned int i; - asection **hdrpp; - bfd_size_type amt; - - amt = sizeof (struct elf_segment_map); - amt += (to - from - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - return NULL; - m->next = NULL; - m->p_type = PT_LOAD; - for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++) - m->sections[i - from] = *hdrpp; - m->count = to - from; - - if (from == 0 && phdr) - { - /* Include the headers in the first PT_LOAD segment. */ - m->includes_filehdr = 1; - m->includes_phdrs = 1; - } - - return m; -} - -/* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL - on failure. */ - -struct elf_segment_map * -_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec) -{ - struct elf_segment_map *m; - - m = (struct elf_segment_map *) bfd_zalloc (abfd, - sizeof (struct elf_segment_map)); - if (m == NULL) - return NULL; - m->next = NULL; - m->p_type = PT_DYNAMIC; - m->count = 1; - m->sections[0] = dynsec; - - return m; -} - -/* Possibly add or remove segments from the segment map. */ - -static bfd_boolean -elf_modify_segment_map (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean remove_empty_load) -{ - struct elf_segment_map **m; - const struct elf_backend_data *bed; - - /* The placement algorithm assumes that non allocated sections are - not in PT_LOAD segments. We ensure this here by removing such - sections from the segment map. We also remove excluded - sections. Finally, any PT_LOAD segment without sections is - removed. */ - m = &elf_tdata (abfd)->segment_map; - while (*m) - { - unsigned int i, new_count; - - for (new_count = 0, i = 0; i < (*m)->count; i++) - { - if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0 - && (((*m)->sections[i]->flags & SEC_ALLOC) != 0 - || (*m)->p_type != PT_LOAD)) - { - (*m)->sections[new_count] = (*m)->sections[i]; - new_count++; - } - } - (*m)->count = new_count; - - if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0) - *m = (*m)->next; - else - m = &(*m)->next; - } - - bed = get_elf_backend_data (abfd); - if (bed->elf_backend_modify_segment_map != NULL) - { - if (!(*bed->elf_backend_modify_segment_map) (abfd, info)) - return FALSE; - } - - return TRUE; -} - -/* Set up a mapping from BFD sections to program segments. */ - -bfd_boolean -_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) -{ - unsigned int count; - struct elf_segment_map *m; - asection **sections = NULL; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_boolean no_user_phdrs; - - no_user_phdrs = elf_tdata (abfd)->segment_map == NULL; - if (no_user_phdrs && bfd_count_sections (abfd) != 0) - { - asection *s; - unsigned int i; - struct elf_segment_map *mfirst; - struct elf_segment_map **pm; - asection *last_hdr; - bfd_vma last_size; - unsigned int phdr_index; - bfd_vma maxpagesize; - asection **hdrpp; - bfd_boolean phdr_in_segment = TRUE; - bfd_boolean writable; - int tls_count = 0; - asection *first_tls = NULL; - asection *dynsec, *eh_frame_hdr; - bfd_size_type amt; - bfd_vma addr_mask, wrap_to = 0; - - /* Select the allocated sections, and sort them. */ - - sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd), - sizeof (asection *)); - if (sections == NULL) - goto error_return; - - /* Calculate top address, avoiding undefined behaviour of shift - left operator when shift count is equal to size of type - being shifted. */ - addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1; - addr_mask = (addr_mask << 1) + 1; - - i = 0; - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_ALLOC) != 0) - { - sections[i] = s; - ++i; - /* A wrapping section potentially clashes with header. */ - if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask)) - wrap_to = (s->lma + s->size) & addr_mask; - } - } - BFD_ASSERT (i <= bfd_count_sections (abfd)); - count = i; - - qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections); - - /* Build the mapping. */ - - mfirst = NULL; - pm = &mfirst; - - /* If we have a .interp section, then create a PT_PHDR segment for - the program headers and a PT_INTERP segment for the .interp - section. */ - s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_PHDR; - /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */ - m->p_flags = PF_R | PF_X; - m->p_flags_valid = 1; - m->includes_phdrs = 1; - - *pm = m; - pm = &m->next; - - amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_INTERP; - m->count = 1; - m->sections[0] = s; - - *pm = m; - pm = &m->next; - } - - /* Look through the sections. We put sections in the same program - segment when the start of the second section can be placed within - a few bytes of the end of the first section. */ - last_hdr = NULL; - last_size = 0; - phdr_index = 0; - maxpagesize = bed->maxpagesize; - writable = FALSE; - dynsec = bfd_get_section_by_name (abfd, ".dynamic"); - if (dynsec != NULL - && (dynsec->flags & SEC_LOAD) == 0) - dynsec = NULL; - - /* Deal with -Ttext or something similar such that the first section - is not adjacent to the program headers. This is an - approximation, since at this point we don't know exactly how many - program headers we will need. */ - if (count > 0) - { - bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; - - if (phdr_size == (bfd_size_type) -1) - phdr_size = get_program_header_size (abfd, info); - if ((abfd->flags & D_PAGED) == 0 - || (sections[0]->lma & addr_mask) < phdr_size - || ((sections[0]->lma & addr_mask) % maxpagesize - < phdr_size % maxpagesize) - || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to) - phdr_in_segment = FALSE; - } - - for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) - { - asection *hdr; - bfd_boolean new_segment; - - hdr = *hdrpp; - - /* See if this section and the last one will fit in the same - segment. */ - - if (last_hdr == NULL) - { - /* If we don't have a segment yet, then we don't need a new - one (we build the last one after this loop). */ - new_segment = FALSE; - } - else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma) - { - /* If this section has a different relation between the - virtual address and the load address, then we need a new - segment. */ - new_segment = TRUE; - } - else if (hdr->lma < last_hdr->lma + last_size - || last_hdr->lma + last_size < last_hdr->lma) - { - /* If this section has a load address that makes it overlap - the previous section, then we need a new segment. */ - new_segment = TRUE; - } - /* In the next test we have to be careful when last_hdr->lma is close - to the end of the address space. If the aligned address wraps - around to the start of the address space, then there are no more - pages left in memory and it is OK to assume that the current - section can be included in the current segment. */ - else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize - > last_hdr->lma) - && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize - <= hdr->lma)) - { - /* If putting this section in this segment would force us to - skip a page in the segment, then we need a new segment. */ - new_segment = TRUE; - } - else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 - && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0) - { - /* We don't want to put a loadable section after a - nonloadable section in the same segment. - Consider .tbss sections as loadable for this purpose. */ - new_segment = TRUE; - } - else if ((abfd->flags & D_PAGED) == 0) - { - /* If the file is not demand paged, which means that we - don't require the sections to be correctly aligned in the - file, then there is no other reason for a new segment. */ - new_segment = FALSE; - } - else if (! writable - && (hdr->flags & SEC_READONLY) == 0 - && (((last_hdr->lma + last_size - 1) & -maxpagesize) - != (hdr->lma & -maxpagesize))) - { - /* We don't want to put a writable section in a read only - segment, unless they are on the same page in memory - anyhow. We already know that the last section does not - bring us past the current section on the page, so the - only case in which the new section is not on the same - page as the previous section is when the previous section - ends precisely on a page boundary. */ - new_segment = TRUE; - } - else - { - /* Otherwise, we can use the same segment. */ - new_segment = FALSE; - } - - /* Allow interested parties a chance to override our decision. */ - if (last_hdr != NULL - && info != NULL - && info->callbacks->override_segment_assignment != NULL) - new_segment - = info->callbacks->override_segment_assignment (info, abfd, hdr, - last_hdr, - new_segment); - - if (! new_segment) - { - if ((hdr->flags & SEC_READONLY) == 0) - writable = TRUE; - last_hdr = hdr; - /* .tbss sections effectively have zero size. */ - if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) - != SEC_THREAD_LOCAL) - last_size = hdr->size; - else - last_size = 0; - continue; - } - - /* We need a new program segment. We must create a new program - header holding all the sections from phdr_index until hdr. */ - - m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); - if (m == NULL) - goto error_return; - - *pm = m; - pm = &m->next; - - if ((hdr->flags & SEC_READONLY) == 0) - writable = TRUE; - else - writable = FALSE; - - last_hdr = hdr; - /* .tbss sections effectively have zero size. */ - if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) - last_size = hdr->size; - else - last_size = 0; - phdr_index = i; - phdr_in_segment = FALSE; - } - - /* Create a final PT_LOAD program segment, but not if it's just - for .tbss. */ - if (last_hdr != NULL - && (i - phdr_index != 1 - || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) - != SEC_THREAD_LOCAL))) - { - m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); - if (m == NULL) - goto error_return; - - *pm = m; - pm = &m->next; - } - - /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */ - if (dynsec != NULL) - { - m = _bfd_elf_make_dynamic_segment (abfd, dynsec); - if (m == NULL) - goto error_return; - *pm = m; - pm = &m->next; - } - - /* For each batch of consecutive loadable .note sections, - add a PT_NOTE segment. We don't use bfd_get_section_by_name, - because if we link together nonloadable .note sections and - loadable .note sections, we will generate two .note sections - in the output file. FIXME: Using names for section types is - bogus anyhow. */ - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_LOAD) != 0 - && CONST_STRNEQ (s->name, ".note")) - { - asection *s2; - - count = 1; - amt = sizeof (struct elf_segment_map); - if (s->alignment_power == 2) - for (s2 = s; s2->next != NULL; s2 = s2->next) - { - if (s2->next->alignment_power == 2 - && (s2->next->flags & SEC_LOAD) != 0 - && CONST_STRNEQ (s2->next->name, ".note") - && align_power (s2->lma + s2->size, 2) - == s2->next->lma) - count++; - else - break; - } - amt += (count - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_NOTE; - m->count = count; - while (count > 1) - { - m->sections[m->count - count--] = s; - BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0); - s = s->next; - } - m->sections[m->count - 1] = s; - BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0); - *pm = m; - pm = &m->next; - } - if (s->flags & SEC_THREAD_LOCAL) - { - if (! tls_count) - first_tls = s; - tls_count++; - } - } - - /* If there are any SHF_TLS output sections, add PT_TLS segment. */ - if (tls_count > 0) - { - amt = sizeof (struct elf_segment_map); - amt += (tls_count - 1) * sizeof (asection *); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_TLS; - m->count = tls_count; - /* Mandated PF_R. */ - m->p_flags = PF_R; - m->p_flags_valid = 1; - for (i = 0; i < (unsigned int) tls_count; ++i) - { - BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL); - m->sections[i] = first_tls; - first_tls = first_tls->next; - } - - *pm = m; - pm = &m->next; - } - - /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME - segment. */ - eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr; - if (eh_frame_hdr != NULL - && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0) - { - amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_GNU_EH_FRAME; - m->count = 1; - m->sections[0] = eh_frame_hdr->output_section; - - *pm = m; - pm = &m->next; - } - - if (elf_tdata (abfd)->stack_flags) - { - amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_GNU_STACK; - m->p_flags = elf_tdata (abfd)->stack_flags; - m->p_flags_valid = 1; - - *pm = m; - pm = &m->next; - } - - if (info != NULL && info->relro) - { - for (m = mfirst; m != NULL; m = m->next) - { - if (m->p_type == PT_LOAD) - { - asection *last = m->sections[m->count - 1]; - bfd_vma vaddr = m->sections[0]->vma; - bfd_vma filesz = last->vma - vaddr + last->size; - - if (vaddr < info->relro_end - && vaddr >= info->relro_start - && (vaddr + filesz) >= info->relro_end) - break; - } - } - - /* Make a PT_GNU_RELRO segment only when it isn't empty. */ - if (m != NULL) - { - amt = sizeof (struct elf_segment_map); - m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); - if (m == NULL) - goto error_return; - m->next = NULL; - m->p_type = PT_GNU_RELRO; - m->p_flags = PF_R; - m->p_flags_valid = 1; - - *pm = m; - pm = &m->next; - } - } - - free (sections); - elf_tdata (abfd)->segment_map = mfirst; - } - - if (!elf_modify_segment_map (abfd, info, no_user_phdrs)) - return FALSE; - - for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - ++count; - elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr; - - return TRUE; - - error_return: - if (sections != NULL) - free (sections); - return FALSE; -} - -/* Sort sections by address. */ - -static int -elf_sort_sections (const void *arg1, const void *arg2) -{ - const asection *sec1 = *(const asection **) arg1; - const asection *sec2 = *(const asection **) arg2; - bfd_size_type size1, size2; - - /* Sort by LMA first, since this is the address used to - place the section into a segment. */ - if (sec1->lma < sec2->lma) - return -1; - else if (sec1->lma > sec2->lma) - return 1; - - /* Then sort by VMA. Normally the LMA and the VMA will be - the same, and this will do nothing. */ - if (sec1->vma < sec2->vma) - return -1; - else if (sec1->vma > sec2->vma) - return 1; - - /* Put !SEC_LOAD sections after SEC_LOAD ones. */ - -#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0) - - if (TOEND (sec1)) - { - if (TOEND (sec2)) - { - /* If the indicies are the same, do not return 0 - here, but continue to try the next comparison. */ - if (sec1->target_index - sec2->target_index != 0) - return sec1->target_index - sec2->target_index; - } - else - return 1; - } - else if (TOEND (sec2)) - return -1; - -#undef TOEND - - /* Sort by size, to put zero sized sections - before others at the same address. */ - - size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0; - size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0; - - if (size1 < size2) - return -1; - if (size1 > size2) - return 1; - - return sec1->target_index - sec2->target_index; -} - -/* Ian Lance Taylor writes: - - We shouldn't be using % with a negative signed number. That's just - not good. We have to make sure either that the number is not - negative, or that the number has an unsigned type. When the types - are all the same size they wind up as unsigned. When file_ptr is a - larger signed type, the arithmetic winds up as signed long long, - which is wrong. - - What we're trying to say here is something like ``increase OFF by - the least amount that will cause it to be equal to the VMA modulo - the page size.'' */ -/* In other words, something like: - - vma_offset = m->sections[0]->vma % bed->maxpagesize; - off_offset = off % bed->maxpagesize; - if (vma_offset < off_offset) - adjustment = vma_offset + bed->maxpagesize - off_offset; - else - adjustment = vma_offset - off_offset; - - which can can be collapsed into the expression below. */ - -static file_ptr -vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize) -{ - return ((vma - off) % maxpagesize); -} - -static void -print_segment_map (const struct elf_segment_map *m) -{ - unsigned int j; - const char *pt = get_segment_type (m->p_type); - char buf[32]; - - if (pt == NULL) - { - if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC) - sprintf (buf, "LOPROC+%7.7x", - (unsigned int) (m->p_type - PT_LOPROC)); - else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS) - sprintf (buf, "LOOS+%7.7x", - (unsigned int) (m->p_type - PT_LOOS)); - else - snprintf (buf, sizeof (buf), "%8.8x", - (unsigned int) m->p_type); - pt = buf; - } - fflush (stdout); - fprintf (stderr, "%s:", pt); - for (j = 0; j < m->count; j++) - fprintf (stderr, " %s", m->sections [j]->name); - putc ('\n',stderr); - fflush (stderr); -} - -static bfd_boolean -write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len) -{ - void *buf; - bfd_boolean ret; - - if (bfd_seek (abfd, pos, SEEK_SET) != 0) - return FALSE; - buf = bfd_zmalloc (len); - if (buf == NULL) - return FALSE; - ret = bfd_bwrite (buf, len, abfd) == len; - free (buf); - return ret; -} - -/* Assign file positions to the sections based on the mapping from - sections to segments. This function also sets up some fields in - the file header. */ - -static bfd_boolean -assign_file_positions_for_load_sections (bfd *abfd, - struct bfd_link_info *link_info) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *phdrs; - Elf_Internal_Phdr *p; - file_ptr off; - bfd_size_type maxpagesize; - unsigned int alloc; - unsigned int i, j; - bfd_vma header_pad = 0; - - if (link_info == NULL - && !_bfd_elf_map_sections_to_segments (abfd, link_info)) - return FALSE; - - alloc = 0; - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - { - ++alloc; - if (m->header_size) - header_pad = m->header_size; - } - - if (alloc) - { - elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr; - elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr; - } - else - { - /* PR binutils/12467. */ - elf_elfheader (abfd)->e_phoff = 0; - elf_elfheader (abfd)->e_phentsize = 0; - } - - elf_elfheader (abfd)->e_phnum = alloc; - - if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1) - elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr; - else - BFD_ASSERT (elf_tdata (abfd)->program_header_size - >= alloc * bed->s->sizeof_phdr); - - if (alloc == 0) - { - elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr; - return TRUE; - } - - /* We're writing the size in elf_tdata (abfd)->program_header_size, - see assign_file_positions_except_relocs, so make sure we have - that amount allocated, with trailing space cleared. - The variable alloc contains the computed need, while elf_tdata - (abfd)->program_header_size contains the size used for the - layout. - See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments - where the layout is forced to according to a larger size in the - last iterations for the testcase ld-elf/header. */ - BFD_ASSERT (elf_tdata (abfd)->program_header_size % bed->s->sizeof_phdr - == 0); - phdrs = (Elf_Internal_Phdr *) - bfd_zalloc2 (abfd, - (elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr), - sizeof (Elf_Internal_Phdr)); - elf_tdata (abfd)->phdr = phdrs; - if (phdrs == NULL) - return FALSE; - - maxpagesize = 1; - if ((abfd->flags & D_PAGED) != 0) - maxpagesize = bed->maxpagesize; - - off = bed->s->sizeof_ehdr; - off += alloc * bed->s->sizeof_phdr; - if (header_pad < (bfd_vma) off) - header_pad = 0; - else - header_pad -= off; - off += header_pad; - - for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0; - m != NULL; - m = m->next, p++, j++) - { - asection **secpp; - bfd_vma off_adjust; - bfd_boolean no_contents; - - /* If elf_segment_map is not from map_sections_to_segments, the - sections may not be correctly ordered. NOTE: sorting should - not be done to the PT_NOTE section of a corefile, which may - contain several pseudo-sections artificially created by bfd. - Sorting these pseudo-sections breaks things badly. */ - if (m->count > 1 - && !(elf_elfheader (abfd)->e_type == ET_CORE - && m->p_type == PT_NOTE)) - qsort (m->sections, (size_t) m->count, sizeof (asection *), - elf_sort_sections); - - /* An ELF segment (described by Elf_Internal_Phdr) may contain a - number of sections with contents contributing to both p_filesz - and p_memsz, followed by a number of sections with no contents - that just contribute to p_memsz. In this loop, OFF tracks next - available file offset for PT_LOAD and PT_NOTE segments. */ - p->p_type = m->p_type; - p->p_flags = m->p_flags; - - if (m->count == 0) - p->p_vaddr = 0; - else - p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset; - - if (m->p_paddr_valid) - p->p_paddr = m->p_paddr; - else if (m->count == 0) - p->p_paddr = 0; - else - p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset; - - if (p->p_type == PT_LOAD - && (abfd->flags & D_PAGED) != 0) - { - /* p_align in demand paged PT_LOAD segments effectively stores - the maximum page size. When copying an executable with - objcopy, we set m->p_align from the input file. Use this - value for maxpagesize rather than bed->maxpagesize, which - may be different. Note that we use maxpagesize for PT_TLS - segment alignment later in this function, so we are relying - on at least one PT_LOAD segment appearing before a PT_TLS - segment. */ - if (m->p_align_valid) - maxpagesize = m->p_align; - - p->p_align = maxpagesize; - } - else if (m->p_align_valid) - p->p_align = m->p_align; - else if (m->count == 0) - p->p_align = 1 << bed->s->log_file_align; - else - p->p_align = 0; - - no_contents = FALSE; - off_adjust = 0; - if (p->p_type == PT_LOAD - && m->count > 0) - { - bfd_size_type align; - unsigned int align_power = 0; - - if (m->p_align_valid) - align = p->p_align; - else - { - for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) - { - unsigned int secalign; - - secalign = bfd_get_section_alignment (abfd, *secpp); - if (secalign > align_power) - align_power = secalign; - } - align = (bfd_size_type) 1 << align_power; - if (align < maxpagesize) - align = maxpagesize; - } - - for (i = 0; i < m->count; i++) - if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - /* If we aren't making room for this section, then - it must be SHT_NOBITS regardless of what we've - set via struct bfd_elf_special_section. */ - elf_section_type (m->sections[i]) = SHT_NOBITS; - - /* Find out whether this segment contains any loadable - sections. */ - no_contents = TRUE; - for (i = 0; i < m->count; i++) - if (elf_section_type (m->sections[i]) != SHT_NOBITS) - { - no_contents = FALSE; - break; - } - - off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align); - off += off_adjust; - if (no_contents) - { - /* We shouldn't need to align the segment on disk since - the segment doesn't need file space, but the gABI - arguably requires the alignment and glibc ld.so - checks it. So to comply with the alignment - requirement but not waste file space, we adjust - p_offset for just this segment. (OFF_ADJUST is - subtracted from OFF later.) This may put p_offset - past the end of file, but that shouldn't matter. */ - } - else - off_adjust = 0; - } - /* Make sure the .dynamic section is the first section in the - PT_DYNAMIC segment. */ - else if (p->p_type == PT_DYNAMIC - && m->count > 1 - && strcmp (m->sections[0]->name, ".dynamic") != 0) - { - _bfd_error_handler - (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"), - abfd); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - /* Set the note section type to SHT_NOTE. */ - else if (p->p_type == PT_NOTE) - for (i = 0; i < m->count; i++) - elf_section_type (m->sections[i]) = SHT_NOTE; - - p->p_offset = 0; - p->p_filesz = 0; - p->p_memsz = 0; - - if (m->includes_filehdr) - { - if (!m->p_flags_valid) - p->p_flags |= PF_R; - p->p_filesz = bed->s->sizeof_ehdr; - p->p_memsz = bed->s->sizeof_ehdr; - if (m->count > 0) - { - BFD_ASSERT (p->p_type == PT_LOAD); - - if (p->p_vaddr < (bfd_vma) off) - { - (*_bfd_error_handler) - (_("%B: Not enough room for program headers, try linking with -N"), - abfd); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - p->p_vaddr -= off; - if (!m->p_paddr_valid) - p->p_paddr -= off; - } - } - - if (m->includes_phdrs) - { - if (!m->p_flags_valid) - p->p_flags |= PF_R; - - if (!m->includes_filehdr) - { - p->p_offset = bed->s->sizeof_ehdr; - - if (m->count > 0) - { - BFD_ASSERT (p->p_type == PT_LOAD); - p->p_vaddr -= off - p->p_offset; - if (!m->p_paddr_valid) - p->p_paddr -= off - p->p_offset; - } - } - - p->p_filesz += alloc * bed->s->sizeof_phdr; - p->p_memsz += alloc * bed->s->sizeof_phdr; - if (m->count) - { - p->p_filesz += header_pad; - p->p_memsz += header_pad; - } - } - - if (p->p_type == PT_LOAD - || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)) - { - if (!m->includes_filehdr && !m->includes_phdrs) - p->p_offset = off; - else - { - file_ptr adjust; - - adjust = off - (p->p_offset + p->p_filesz); - if (!no_contents) - p->p_filesz += adjust; - p->p_memsz += adjust; - } - } - - /* Set up p_filesz, p_memsz, p_align and p_flags from the section - maps. Set filepos for sections in PT_LOAD segments, and in - core files, for sections in PT_NOTE segments. - assign_file_positions_for_non_load_sections will set filepos - for other sections and update p_filesz for other segments. */ - for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) - { - asection *sec; - bfd_size_type align; - Elf_Internal_Shdr *this_hdr; - - sec = *secpp; - this_hdr = &elf_section_data (sec)->this_hdr; - align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec); - - if ((p->p_type == PT_LOAD - || p->p_type == PT_TLS) - && (this_hdr->sh_type != SHT_NOBITS - || ((this_hdr->sh_flags & SHF_ALLOC) != 0 - && ((this_hdr->sh_flags & SHF_TLS) == 0 - || p->p_type == PT_TLS)))) - { - bfd_vma p_start = p->p_paddr; - bfd_vma p_end = p_start + p->p_memsz; - bfd_vma s_start = sec->lma; - bfd_vma adjust = s_start - p_end; - - if (adjust != 0 - && (s_start < p_end - || p_end < p_start)) - { - (*_bfd_error_handler) - (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec, - (unsigned long) s_start, (unsigned long) p_end); - adjust = 0; - sec->lma = p_end; - } - p->p_memsz += adjust; - - if (this_hdr->sh_type != SHT_NOBITS) - { - if (p->p_filesz + adjust < p->p_memsz) - { - /* We have a PROGBITS section following NOBITS ones. - Allocate file space for the NOBITS section(s) and - zero it. */ - adjust = p->p_memsz - p->p_filesz; - if (!write_zeros (abfd, off, adjust)) - return FALSE; - } - off += adjust; - p->p_filesz += adjust; - } - } - - if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core) - { - /* The section at i == 0 is the one that actually contains - everything. */ - if (i == 0) - { - this_hdr->sh_offset = sec->filepos = off; - off += this_hdr->sh_size; - p->p_filesz = this_hdr->sh_size; - p->p_memsz = 0; - p->p_align = 1; - } - else - { - /* The rest are fake sections that shouldn't be written. */ - sec->filepos = 0; - sec->size = 0; - sec->flags = 0; - continue; - } - } - else - { - if (p->p_type == PT_LOAD) - { - this_hdr->sh_offset = sec->filepos = off; - if (this_hdr->sh_type != SHT_NOBITS) - off += this_hdr->sh_size; - } - else if (this_hdr->sh_type == SHT_NOBITS - && (this_hdr->sh_flags & SHF_TLS) != 0 - && this_hdr->sh_offset == 0) - { - /* This is a .tbss section that didn't get a PT_LOAD. - (See _bfd_elf_map_sections_to_segments "Create a - final PT_LOAD".) Set sh_offset to the value it - would have if we had created a zero p_filesz and - p_memsz PT_LOAD header for the section. This - also makes the PT_TLS header have the same - p_offset value. */ - bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr, - off, align); - this_hdr->sh_offset = sec->filepos = off + adjust; - } - - if (this_hdr->sh_type != SHT_NOBITS) - { - p->p_filesz += this_hdr->sh_size; - /* A load section without SHF_ALLOC is something like - a note section in a PT_NOTE segment. These take - file space but are not loaded into memory. */ - if ((this_hdr->sh_flags & SHF_ALLOC) != 0) - p->p_memsz += this_hdr->sh_size; - } - else if ((this_hdr->sh_flags & SHF_ALLOC) != 0) - { - if (p->p_type == PT_TLS) - p->p_memsz += this_hdr->sh_size; - - /* .tbss is special. It doesn't contribute to p_memsz of - normal segments. */ - else if ((this_hdr->sh_flags & SHF_TLS) == 0) - p->p_memsz += this_hdr->sh_size; - } - - if (align > p->p_align - && !m->p_align_valid - && (p->p_type != PT_LOAD - || (abfd->flags & D_PAGED) == 0)) - p->p_align = align; - } - - if (!m->p_flags_valid) - { - p->p_flags |= PF_R; - if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0) - p->p_flags |= PF_X; - if ((this_hdr->sh_flags & SHF_WRITE) != 0) - p->p_flags |= PF_W; - } - } - off -= off_adjust; - - /* Check that all sections are in a PT_LOAD segment. - Don't check funky gdb generated core files. */ - if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core) - { - bfd_boolean check_vma = TRUE; - - for (i = 1; i < m->count; i++) - if (m->sections[i]->vma == m->sections[i - 1]->vma - && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i]) - ->this_hdr), p) != 0 - && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1]) - ->this_hdr), p) != 0) - { - /* Looks like we have overlays packed into the segment. */ - check_vma = FALSE; - break; - } - - for (i = 0; i < m->count; i++) - { - Elf_Internal_Shdr *this_hdr; - asection *sec; - - sec = m->sections[i]; - this_hdr = &(elf_section_data(sec)->this_hdr); - if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0) - && !ELF_TBSS_SPECIAL (this_hdr, p)) - { - (*_bfd_error_handler) - (_("%B: section `%A' can't be allocated in segment %d"), - abfd, sec, j); - print_segment_map (m); - } - } - } - } - - elf_tdata (abfd)->next_file_pos = off; - return TRUE; -} - -/* Assign file positions for the other sections. */ - -static bfd_boolean -assign_file_positions_for_non_load_sections (bfd *abfd, - struct bfd_link_info *link_info) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Shdr **i_shdrpp; - Elf_Internal_Shdr **hdrpp; - Elf_Internal_Phdr *phdrs; - Elf_Internal_Phdr *p; - struct elf_segment_map *m; - bfd_vma filehdr_vaddr, filehdr_paddr; - bfd_vma phdrs_vaddr, phdrs_paddr; - file_ptr off; - unsigned int num_sec; - unsigned int i; - unsigned int count; - - i_shdrpp = elf_elfsections (abfd); - num_sec = elf_numsections (abfd); - off = elf_tdata (abfd)->next_file_pos; - for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) - { - struct elf_obj_tdata *tdata = elf_tdata (abfd); - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (hdr->bfd_section != NULL - && (hdr->bfd_section->filepos != 0 - || (hdr->sh_type == SHT_NOBITS - && hdr->contents == NULL))) - BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); - else if ((hdr->sh_flags & SHF_ALLOC) != 0) - { - (*_bfd_error_handler) - (_("%B: warning: allocated section `%s' not in segment"), - abfd, - (hdr->bfd_section == NULL - ? "*unknown*" - : hdr->bfd_section->name)); - /* We don't need to page align empty sections. */ - if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0) - off += vma_page_aligned_bias (hdr->sh_addr, off, - bed->maxpagesize); - else - off += vma_page_aligned_bias (hdr->sh_addr, off, - hdr->sh_addralign); - off = _bfd_elf_assign_file_position_for_section (hdr, off, - FALSE); - } - else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - && hdr->bfd_section == NULL) - || hdr == i_shdrpp[tdata->symtab_section] - || hdr == i_shdrpp[tdata->symtab_shndx_section] - || hdr == i_shdrpp[tdata->strtab_section]) - hdr->sh_offset = -1; - else - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - } - - /* Now that we have set the section file positions, we can set up - the file positions for the non PT_LOAD segments. */ - count = 0; - filehdr_vaddr = 0; - filehdr_paddr = 0; - phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr; - phdrs_paddr = 0; - phdrs = elf_tdata (abfd)->phdr; - for (m = elf_tdata (abfd)->segment_map, p = phdrs; - m != NULL; - m = m->next, p++) - { - ++count; - if (p->p_type != PT_LOAD) - continue; - - if (m->includes_filehdr) - { - filehdr_vaddr = p->p_vaddr; - filehdr_paddr = p->p_paddr; - } - if (m->includes_phdrs) - { - phdrs_vaddr = p->p_vaddr; - phdrs_paddr = p->p_paddr; - if (m->includes_filehdr) - { - phdrs_vaddr += bed->s->sizeof_ehdr; - phdrs_paddr += bed->s->sizeof_ehdr; - } - } - } - - for (m = elf_tdata (abfd)->segment_map, p = phdrs; - m != NULL; - m = m->next, p++) - { - if (p->p_type == PT_GNU_RELRO) - { - const Elf_Internal_Phdr *lp; - - BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); - - if (link_info != NULL) - { - /* During linking the range of the RELRO segment is passed - in link_info. */ - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_vaddr >= link_info->relro_start - && lp->p_vaddr < link_info->relro_end - && lp->p_vaddr + lp->p_filesz >= link_info->relro_end) - break; - } - } - else - { - /* Otherwise we are copying an executable or shared - library, but we need to use the same linker logic. */ - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_paddr == p->p_paddr) - break; - } - } - - if (lp < phdrs + count) - { - p->p_vaddr = lp->p_vaddr; - p->p_paddr = lp->p_paddr; - p->p_offset = lp->p_offset; - if (link_info != NULL) - p->p_filesz = link_info->relro_end - lp->p_vaddr; - else if (m->p_size_valid) - p->p_filesz = m->p_size; - else - abort (); - p->p_memsz = p->p_filesz; - p->p_align = 1; - p->p_flags = (lp->p_flags & ~PF_W); - } - else - { - memset (p, 0, sizeof *p); - p->p_type = PT_NULL; - } - } - else if (m->count != 0) - { - if (p->p_type != PT_LOAD - && (p->p_type != PT_NOTE - || bfd_get_format (abfd) != bfd_core)) - { - BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); - - p->p_filesz = 0; - p->p_offset = m->sections[0]->filepos; - for (i = m->count; i-- != 0;) - { - asection *sect = m->sections[i]; - Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr; - if (hdr->sh_type != SHT_NOBITS) - { - p->p_filesz = (sect->filepos - m->sections[0]->filepos - + hdr->sh_size); - break; - } - } - } - } - else if (m->includes_filehdr) - { - p->p_vaddr = filehdr_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = filehdr_paddr; - } - else if (m->includes_phdrs) - { - p->p_vaddr = phdrs_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = phdrs_paddr; - } - } - - elf_tdata (abfd)->next_file_pos = off; - - return TRUE; -} - -/* Work out the file positions of all the sections. This is called by - _bfd_elf_compute_section_file_positions. All the section sizes and - VMAs must be known before this is called. - - Reloc sections come in two flavours: Those processed specially as - "side-channel" data attached to a section to which they apply, and - those that bfd doesn't process as relocations. The latter sort are - stored in a normal bfd section by bfd_section_from_shdr. We don't - consider the former sort here, unless they form part of the loadable - image. Reloc sections not assigned here will be handled later by - assign_file_positions_for_relocs. - - We also don't set the positions of the .symtab and .strtab here. */ - -static bfd_boolean -assign_file_positions_except_relocs (bfd *abfd, - struct bfd_link_info *link_info) -{ - struct elf_obj_tdata *tdata = elf_tdata (abfd); - Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); - file_ptr off; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 - && bfd_get_format (abfd) != bfd_core) - { - Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); - unsigned int num_sec = elf_numsections (abfd); - Elf_Internal_Shdr **hdrpp; - unsigned int i; - - /* Start after the ELF header. */ - off = i_ehdrp->e_ehsize; - - /* We are not creating an executable, which means that we are - not creating a program header, and that the actual order of - the sections in the file is unimportant. */ - for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - && hdr->bfd_section == NULL) - || i == tdata->symtab_section - || i == tdata->symtab_shndx_section - || i == tdata->strtab_section) - { - hdr->sh_offset = -1; - } - else - off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); - } - } - else - { - unsigned int alloc; - - /* Assign file positions for the loaded sections based on the - assignment of sections to segments. */ - if (!assign_file_positions_for_load_sections (abfd, link_info)) - return FALSE; - - /* And for non-load sections. */ - if (!assign_file_positions_for_non_load_sections (abfd, link_info)) - return FALSE; - - if (bed->elf_backend_modify_program_headers != NULL) - { - if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info)) - return FALSE; - } - - /* Write out the program headers. */ - alloc = tdata->program_header_size / bed->s->sizeof_phdr; - if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 - || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0) - return FALSE; - - off = tdata->next_file_pos; - } - - /* Place the section headers. */ - off = align_file_position (off, 1 << bed->s->log_file_align); - i_ehdrp->e_shoff = off; - off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; - - tdata->next_file_pos = off; - - return TRUE; -} - -static bfd_boolean -prep_headers (bfd *abfd) -{ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */ - struct elf_strtab_hash *shstrtab; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - i_ehdrp = elf_elfheader (abfd); - - shstrtab = _bfd_elf_strtab_init (); - if (shstrtab == NULL) - return FALSE; - - elf_shstrtab (abfd) = shstrtab; - - i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; - i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; - i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; - i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; - - i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass; - i_ehdrp->e_ident[EI_DATA] = - bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB; - i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current; - - if ((abfd->flags & DYNAMIC) != 0) - i_ehdrp->e_type = ET_DYN; - else if ((abfd->flags & EXEC_P) != 0) - i_ehdrp->e_type = ET_EXEC; - else if (bfd_get_format (abfd) == bfd_core) - i_ehdrp->e_type = ET_CORE; - else - i_ehdrp->e_type = ET_REL; - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_unknown: - i_ehdrp->e_machine = EM_NONE; - break; - - /* There used to be a long list of cases here, each one setting - e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE - in the corresponding bfd definition. To avoid duplication, - the switch was removed. Machines that need special handling - can generally do it in elf_backend_final_write_processing(), - unless they need the information earlier than the final write. - Such need can generally be supplied by replacing the tests for - e_machine with the conditions used to determine it. */ - default: - i_ehdrp->e_machine = bed->elf_machine_code; - } - - i_ehdrp->e_version = bed->s->ev_current; - i_ehdrp->e_ehsize = bed->s->sizeof_ehdr; - - /* No program header, for now. */ - i_ehdrp->e_phoff = 0; - i_ehdrp->e_phentsize = 0; - i_ehdrp->e_phnum = 0; - - /* Each bfd section is section header entry. */ - i_ehdrp->e_entry = bfd_get_start_address (abfd); - i_ehdrp->e_shentsize = bed->s->sizeof_shdr; - - /* If we're building an executable, we'll need a program header table. */ - if (abfd->flags & EXEC_P) - /* It all happens later. */ - ; - else - { - i_ehdrp->e_phentsize = 0; - i_ehdrp->e_phoff = 0; - } - - elf_tdata (abfd)->symtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE); - elf_tdata (abfd)->strtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE); - elf_tdata (abfd)->shstrtab_hdr.sh_name = - (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE); - if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) - return FALSE; - - return TRUE; -} - -/* Assign file positions for all the reloc sections which are not part - of the loadable file image. */ - -void -_bfd_elf_assign_file_positions_for_relocs (bfd *abfd) -{ - file_ptr off; - unsigned int i, num_sec; - Elf_Internal_Shdr **shdrpp; - - off = elf_tdata (abfd)->next_file_pos; - - num_sec = elf_numsections (abfd); - for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++) - { - Elf_Internal_Shdr *shdrp; - - shdrp = *shdrpp; - if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA) - && shdrp->sh_offset == -1) - off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE); - } - - elf_tdata (abfd)->next_file_pos = off; -} - -bfd_boolean -_bfd_elf_write_object_contents (bfd *abfd) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Shdr **i_shdrp; - bfd_boolean failed; - unsigned int count, num_sec; - - if (! abfd->output_has_begun - && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) - return FALSE; - - i_shdrp = elf_elfsections (abfd); - - failed = FALSE; - bfd_map_over_sections (abfd, bed->s->write_relocs, &failed); - if (failed) - return FALSE; - - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* After writing the headers, we need to write the sections too... */ - num_sec = elf_numsections (abfd); - for (count = 1; count < num_sec; count++) - { - if (bed->elf_backend_section_processing) - (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]); - if (i_shdrp[count]->contents) - { - bfd_size_type amt = i_shdrp[count]->sh_size; - - if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 - || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt) - return FALSE; - } - } - - /* Write out the section header names. */ - if (elf_shstrtab (abfd) != NULL - && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0 - || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))) - return FALSE; - - if (bed->elf_backend_final_write_processing) - (*bed->elf_backend_final_write_processing) (abfd, - elf_tdata (abfd)->linker); - - if (!bed->s->write_shdrs_and_ehdr (abfd)) - return FALSE; - - /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */ - if (elf_tdata (abfd)->after_write_object_contents) - return (*elf_tdata (abfd)->after_write_object_contents) (abfd); - - return TRUE; -} - -bfd_boolean -_bfd_elf_write_corefile_contents (bfd *abfd) -{ - /* Hopefully this can be done just like an object file. */ - return _bfd_elf_write_object_contents (abfd); -} - -/* Given a section, search the header to find them. */ - -unsigned int -_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect) -{ - const struct elf_backend_data *bed; - unsigned int sec_index; - - if (elf_section_data (asect) != NULL - && elf_section_data (asect)->this_idx != 0) - return elf_section_data (asect)->this_idx; - - if (bfd_is_abs_section (asect)) - sec_index = SHN_ABS; - else if (bfd_is_com_section (asect)) - sec_index = SHN_COMMON; - else if (bfd_is_und_section (asect)) - sec_index = SHN_UNDEF; - else - sec_index = SHN_BAD; - - bed = get_elf_backend_data (abfd); - if (bed->elf_backend_section_from_bfd_section) - { - int retval = sec_index; - - if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval)) - return retval; - } - - if (sec_index == SHN_BAD) - bfd_set_error (bfd_error_nonrepresentable_section); - - return sec_index; -} - -/* Given a BFD symbol, return the index in the ELF symbol table, or -1 - on error. */ - -int -_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr) -{ - asymbol *asym_ptr = *asym_ptr_ptr; - int idx; - flagword flags = asym_ptr->flags; - - /* When gas creates relocations against local labels, it creates its - own symbol for the section, but does put the symbol into the - symbol chain, so udata is 0. When the linker is generating - relocatable output, this section symbol may be for one of the - input sections rather than the output section. */ - if (asym_ptr->udata.i == 0 - && (flags & BSF_SECTION_SYM) - && asym_ptr->section) - { - asection *sec; - int indx; - - sec = asym_ptr->section; - if (sec->owner != abfd && sec->output_section != NULL) - sec = sec->output_section; - if (sec->owner == abfd - && (indx = sec->index) < elf_num_section_syms (abfd) - && elf_section_syms (abfd)[indx] != NULL) - asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i; - } - - idx = asym_ptr->udata.i; - - if (idx == 0) - { - /* This case can occur when using --strip-symbol on a symbol - which is used in a relocation entry. */ - (*_bfd_error_handler) - (_("%B: symbol `%s' required but not present"), - abfd, bfd_asymbol_name (asym_ptr)); - bfd_set_error (bfd_error_no_symbols); - return -1; - } - -#if DEBUG & 4 - { - fprintf (stderr, - "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx\n", - (long) asym_ptr, asym_ptr->name, idx, (long) flags); - fflush (stderr); - } -#endif - - return idx; -} - -/* Rewrite program header information. */ - -static bfd_boolean -rewrite_elf_program_header (bfd *ibfd, bfd *obfd) -{ - Elf_Internal_Ehdr *iehdr; - struct elf_segment_map *map; - struct elf_segment_map *map_first; - struct elf_segment_map **pointer_to_map; - Elf_Internal_Phdr *segment; - asection *section; - unsigned int i; - unsigned int num_segments; - bfd_boolean phdr_included = FALSE; - bfd_boolean p_paddr_valid; - bfd_vma maxpagesize; - struct elf_segment_map *phdr_adjust_seg = NULL; - unsigned int phdr_adjust_num = 0; - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (ibfd); - iehdr = elf_elfheader (ibfd); - - map_first = NULL; - pointer_to_map = &map_first; - - num_segments = elf_elfheader (ibfd)->e_phnum; - maxpagesize = get_elf_backend_data (obfd)->maxpagesize; - - /* Returns the end address of the segment + 1. */ -#define SEGMENT_END(segment, start) \ - (start + (segment->p_memsz > segment->p_filesz \ - ? segment->p_memsz : segment->p_filesz)) - -#define SECTION_SIZE(section, segment) \ - (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \ - != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \ - ? section->size : 0) - - /* Returns TRUE if the given section is contained within - the given segment. VMA addresses are compared. */ -#define IS_CONTAINED_BY_VMA(section, segment) \ - (section->vma >= segment->p_vaddr \ - && (section->vma + SECTION_SIZE (section, segment) \ - <= (SEGMENT_END (segment, segment->p_vaddr)))) - - /* Returns TRUE if the given section is contained within - the given segment. LMA addresses are compared. */ -#define IS_CONTAINED_BY_LMA(section, segment, base) \ - (section->lma >= base \ - && (section->lma + SECTION_SIZE (section, segment) \ - <= SEGMENT_END (segment, base))) - - /* Handle PT_NOTE segment. */ -#define IS_NOTE(p, s) \ - (p->p_type == PT_NOTE \ - && elf_section_type (s) == SHT_NOTE \ - && (bfd_vma) s->filepos >= p->p_offset \ - && ((bfd_vma) s->filepos + s->size \ - <= p->p_offset + p->p_filesz)) - - /* Special case: corefile "NOTE" section containing regs, prpsinfo - etc. */ -#define IS_COREFILE_NOTE(p, s) \ - (IS_NOTE (p, s) \ - && bfd_get_format (ibfd) == bfd_core \ - && s->vma == 0 \ - && s->lma == 0) - - /* The complicated case when p_vaddr is 0 is to handle the Solaris - linker, which generates a PT_INTERP section with p_vaddr and - p_memsz set to 0. */ -#define IS_SOLARIS_PT_INTERP(p, s) \ - (p->p_vaddr == 0 \ - && p->p_paddr == 0 \ - && p->p_memsz == 0 \ - && p->p_filesz > 0 \ - && (s->flags & SEC_HAS_CONTENTS) != 0 \ - && s->size > 0 \ - && (bfd_vma) s->filepos >= p->p_offset \ - && ((bfd_vma) s->filepos + s->size \ - <= p->p_offset + p->p_filesz)) - - /* Decide if the given section should be included in the given segment. - A section will be included if: - 1. It is within the address space of the segment -- we use the LMA - if that is set for the segment and the VMA otherwise, - 2. It is an allocated section or a NOTE section in a PT_NOTE - segment. - 3. There is an output section associated with it, - 4. The section has not already been allocated to a previous segment. - 5. PT_GNU_STACK segments do not include any sections. - 6. PT_TLS segment includes only SHF_TLS sections. - 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. - 8. PT_DYNAMIC should not contain empty sections at the beginning - (with the possible exception of .dynamic). */ -#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \ - ((((segment->p_paddr \ - ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ - : IS_CONTAINED_BY_VMA (section, segment)) \ - && (section->flags & SEC_ALLOC) != 0) \ - || IS_NOTE (segment, section)) \ - && segment->p_type != PT_GNU_STACK \ - && (segment->p_type != PT_TLS \ - || (section->flags & SEC_THREAD_LOCAL)) \ - && (segment->p_type == PT_LOAD \ - || segment->p_type == PT_TLS \ - || (section->flags & SEC_THREAD_LOCAL) == 0) \ - && (segment->p_type != PT_DYNAMIC \ - || SECTION_SIZE (section, segment) > 0 \ - || (segment->p_paddr \ - ? segment->p_paddr != section->lma \ - : segment->p_vaddr != section->vma) \ - || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \ - == 0)) \ - && !section->segment_mark) - -/* If the output section of a section in the input segment is NULL, - it is removed from the corresponding output segment. */ -#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \ - (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \ - && section->output_section != NULL) - - /* Returns TRUE iff seg1 starts after the end of seg2. */ -#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \ - (seg1->field >= SEGMENT_END (seg2, seg2->field)) - - /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both - their VMA address ranges and their LMA address ranges overlap. - It is possible to have overlapping VMA ranges without overlapping LMA - ranges. RedBoot images for example can have both .data and .bss mapped - to the same VMA range, but with the .data section mapped to a different - LMA. */ -#define SEGMENT_OVERLAPS(seg1, seg2) \ - ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \ - || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \ - && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \ - || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr))) - - /* Initialise the segment mark field. */ - for (section = ibfd->sections; section != NULL; section = section->next) - section->segment_mark = FALSE; - - /* The Solaris linker creates program headers in which all the - p_paddr fields are zero. When we try to objcopy or strip such a - file, we get confused. Check for this case, and if we find it - don't set the p_paddr_valid fields. */ - p_paddr_valid = FALSE; - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - if (segment->p_paddr != 0) - { - p_paddr_valid = TRUE; - break; - } - - /* Scan through the segments specified in the program header - of the input BFD. For this first scan we look for overlaps - in the loadable segments. These can be created by weird - parameters to objcopy. Also, fix some solaris weirdness. */ - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - { - unsigned int j; - Elf_Internal_Phdr *segment2; - - if (segment->p_type == PT_INTERP) - for (section = ibfd->sections; section; section = section->next) - if (IS_SOLARIS_PT_INTERP (segment, section)) - { - /* Mininal change so that the normal section to segment - assignment code will work. */ - segment->p_vaddr = section->vma; - break; - } - - if (segment->p_type != PT_LOAD) - { - /* Remove PT_GNU_RELRO segment. */ - if (segment->p_type == PT_GNU_RELRO) - segment->p_type = PT_NULL; - continue; - } - - /* Determine if this segment overlaps any previous segments. */ - for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++) - { - bfd_signed_vma extra_length; - - if (segment2->p_type != PT_LOAD - || !SEGMENT_OVERLAPS (segment, segment2)) - continue; - - /* Merge the two segments together. */ - if (segment2->p_vaddr < segment->p_vaddr) - { - /* Extend SEGMENT2 to include SEGMENT and then delete - SEGMENT. */ - extra_length = (SEGMENT_END (segment, segment->p_vaddr) - - SEGMENT_END (segment2, segment2->p_vaddr)); - - if (extra_length > 0) - { - segment2->p_memsz += extra_length; - segment2->p_filesz += extra_length; - } - - segment->p_type = PT_NULL; - - /* Since we have deleted P we must restart the outer loop. */ - i = 0; - segment = elf_tdata (ibfd)->phdr; - break; - } - else - { - /* Extend SEGMENT to include SEGMENT2 and then delete - SEGMENT2. */ - extra_length = (SEGMENT_END (segment2, segment2->p_vaddr) - - SEGMENT_END (segment, segment->p_vaddr)); - - if (extra_length > 0) - { - segment->p_memsz += extra_length; - segment->p_filesz += extra_length; - } - - segment2->p_type = PT_NULL; - } - } - } - - /* The second scan attempts to assign sections to segments. */ - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - { - unsigned int section_count; - asection **sections; - asection *output_section; - unsigned int isec; - bfd_vma matching_lma; - bfd_vma suggested_lma; - unsigned int j; - bfd_size_type amt; - asection *first_section; - bfd_boolean first_matching_lma; - bfd_boolean first_suggested_lma; - - if (segment->p_type == PT_NULL) - continue; - - first_section = NULL; - /* Compute how many sections might be placed into this segment. */ - for (section = ibfd->sections, section_count = 0; - section != NULL; - section = section->next) - { - /* Find the first section in the input segment, which may be - removed from the corresponding output segment. */ - if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)) - { - if (first_section == NULL) - first_section = section; - if (section->output_section != NULL) - ++section_count; - } - } - - /* Allocate a segment map big enough to contain - all of the sections we have selected. */ - amt = sizeof (struct elf_segment_map); - amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); - map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); - if (map == NULL) - return FALSE; - - /* Initialise the fields of the segment map. Default to - using the physical address of the segment in the input BFD. */ - map->next = NULL; - map->p_type = segment->p_type; - map->p_flags = segment->p_flags; - map->p_flags_valid = 1; - - /* If the first section in the input segment is removed, there is - no need to preserve segment physical address in the corresponding - output segment. */ - if (!first_section || first_section->output_section != NULL) - { - map->p_paddr = segment->p_paddr; - map->p_paddr_valid = p_paddr_valid; - } - - /* Determine if this segment contains the ELF file header - and if it contains the program headers themselves. */ - map->includes_filehdr = (segment->p_offset == 0 - && segment->p_filesz >= iehdr->e_ehsize); - map->includes_phdrs = 0; - - if (!phdr_included || segment->p_type != PT_LOAD) - { - map->includes_phdrs = - (segment->p_offset <= (bfd_vma) iehdr->e_phoff - && (segment->p_offset + segment->p_filesz - >= ((bfd_vma) iehdr->e_phoff - + iehdr->e_phnum * iehdr->e_phentsize))); - - if (segment->p_type == PT_LOAD && map->includes_phdrs) - phdr_included = TRUE; - } - - if (section_count == 0) - { - /* Special segments, such as the PT_PHDR segment, may contain - no sections, but ordinary, loadable segments should contain - something. They are allowed by the ELF spec however, so only - a warning is produced. */ - if (segment->p_type == PT_LOAD) - (*_bfd_error_handler) (_("%B: warning: Empty loadable segment" - " detected, is this intentional ?\n"), - ibfd); - - map->count = 0; - *pointer_to_map = map; - pointer_to_map = &map->next; - - continue; - } - - /* Now scan the sections in the input BFD again and attempt - to add their corresponding output sections to the segment map. - The problem here is how to handle an output section which has - been moved (ie had its LMA changed). There are four possibilities: - - 1. None of the sections have been moved. - In this case we can continue to use the segment LMA from the - input BFD. - - 2. All of the sections have been moved by the same amount. - In this case we can change the segment's LMA to match the LMA - of the first section. - - 3. Some of the sections have been moved, others have not. - In this case those sections which have not been moved can be - placed in the current segment which will have to have its size, - and possibly its LMA changed, and a new segment or segments will - have to be created to contain the other sections. - - 4. The sections have been moved, but not by the same amount. - In this case we can change the segment's LMA to match the LMA - of the first section and we will have to create a new segment - or segments to contain the other sections. - - In order to save time, we allocate an array to hold the section - pointers that we are interested in. As these sections get assigned - to a segment, they are removed from this array. */ - - sections = (asection **) bfd_malloc2 (section_count, sizeof (asection *)); - if (sections == NULL) - return FALSE; - - /* Step One: Scan for segment vs section LMA conflicts. - Also add the sections to the section array allocated above. - Also add the sections to the current segment. In the common - case, where the sections have not been moved, this means that - we have completely filled the segment, and there is nothing - more to do. */ - isec = 0; - matching_lma = 0; - suggested_lma = 0; - first_matching_lma = TRUE; - first_suggested_lma = TRUE; - - for (section = ibfd->sections; - section != NULL; - section = section->next) - if (section == first_section) - break; - - for (j = 0; section != NULL; section = section->next) - { - if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed)) - { - output_section = section->output_section; - - sections[j++] = section; - - /* The Solaris native linker always sets p_paddr to 0. - We try to catch that case here, and set it to the - correct value. Note - some backends require that - p_paddr be left as zero. */ - if (!p_paddr_valid - && segment->p_vaddr != 0 - && !bed->want_p_paddr_set_to_zero - && isec == 0 - && output_section->lma != 0 - && output_section->vma == (segment->p_vaddr - + (map->includes_filehdr - ? iehdr->e_ehsize - : 0) - + (map->includes_phdrs - ? (iehdr->e_phnum - * iehdr->e_phentsize) - : 0))) - map->p_paddr = segment->p_vaddr; - - /* Match up the physical address of the segment with the - LMA address of the output section. */ - if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) - || IS_COREFILE_NOTE (segment, section) - || (bed->want_p_paddr_set_to_zero - && IS_CONTAINED_BY_VMA (output_section, segment))) - { - if (first_matching_lma || output_section->lma < matching_lma) - { - matching_lma = output_section->lma; - first_matching_lma = FALSE; - } - - /* We assume that if the section fits within the segment - then it does not overlap any other section within that - segment. */ - map->sections[isec++] = output_section; - } - else if (first_suggested_lma) - { - suggested_lma = output_section->lma; - first_suggested_lma = FALSE; - } - - if (j == section_count) - break; - } - } - - BFD_ASSERT (j == section_count); - - /* Step Two: Adjust the physical address of the current segment, - if necessary. */ - if (isec == section_count) - { - /* All of the sections fitted within the segment as currently - specified. This is the default case. Add the segment to - the list of built segments and carry on to process the next - program header in the input BFD. */ - map->count = section_count; - *pointer_to_map = map; - pointer_to_map = &map->next; - - if (p_paddr_valid - && !bed->want_p_paddr_set_to_zero - && matching_lma != map->p_paddr - && !map->includes_filehdr - && !map->includes_phdrs) - /* There is some padding before the first section in the - segment. So, we must account for that in the output - segment's vma. */ - map->p_vaddr_offset = matching_lma - map->p_paddr; - - free (sections); - continue; - } - else - { - if (!first_matching_lma) - { - /* At least one section fits inside the current segment. - Keep it, but modify its physical address to match the - LMA of the first section that fitted. */ - map->p_paddr = matching_lma; - } - else - { - /* None of the sections fitted inside the current segment. - Change the current segment's physical address to match - the LMA of the first section. */ - map->p_paddr = suggested_lma; - } - - /* Offset the segment physical address from the lma - to allow for space taken up by elf headers. */ - if (map->includes_filehdr) - { - if (map->p_paddr >= iehdr->e_ehsize) - map->p_paddr -= iehdr->e_ehsize; - else - { - map->includes_filehdr = FALSE; - map->includes_phdrs = FALSE; - } - } - - if (map->includes_phdrs) - { - if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize) - { - map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize; - - /* iehdr->e_phnum is just an estimate of the number - of program headers that we will need. Make a note - here of the number we used and the segment we chose - to hold these headers, so that we can adjust the - offset when we know the correct value. */ - phdr_adjust_num = iehdr->e_phnum; - phdr_adjust_seg = map; - } - else - map->includes_phdrs = FALSE; - } - } - - /* Step Three: Loop over the sections again, this time assigning - those that fit to the current segment and removing them from the - sections array; but making sure not to leave large gaps. Once all - possible sections have been assigned to the current segment it is - added to the list of built segments and if sections still remain - to be assigned, a new segment is constructed before repeating - the loop. */ - isec = 0; - do - { - map->count = 0; - suggested_lma = 0; - first_suggested_lma = TRUE; - - /* Fill the current segment with sections that fit. */ - for (j = 0; j < section_count; j++) - { - section = sections[j]; - - if (section == NULL) - continue; - - output_section = section->output_section; - - BFD_ASSERT (output_section != NULL); - - if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) - || IS_COREFILE_NOTE (segment, section)) - { - if (map->count == 0) - { - /* If the first section in a segment does not start at - the beginning of the segment, then something is - wrong. */ - if (output_section->lma - != (map->p_paddr - + (map->includes_filehdr ? iehdr->e_ehsize : 0) - + (map->includes_phdrs - ? iehdr->e_phnum * iehdr->e_phentsize - : 0))) - abort (); - } - else - { - asection *prev_sec; - - prev_sec = map->sections[map->count - 1]; - - /* If the gap between the end of the previous section - and the start of this section is more than - maxpagesize then we need to start a new segment. */ - if ((BFD_ALIGN (prev_sec->lma + prev_sec->size, - maxpagesize) - < BFD_ALIGN (output_section->lma, maxpagesize)) - || (prev_sec->lma + prev_sec->size - > output_section->lma)) - { - if (first_suggested_lma) - { - suggested_lma = output_section->lma; - first_suggested_lma = FALSE; - } - - continue; - } - } - - map->sections[map->count++] = output_section; - ++isec; - sections[j] = NULL; - section->segment_mark = TRUE; - } - else if (first_suggested_lma) - { - suggested_lma = output_section->lma; - first_suggested_lma = FALSE; - } - } - - BFD_ASSERT (map->count > 0); - - /* Add the current segment to the list of built segments. */ - *pointer_to_map = map; - pointer_to_map = &map->next; - - if (isec < section_count) - { - /* We still have not allocated all of the sections to - segments. Create a new segment here, initialise it - and carry on looping. */ - amt = sizeof (struct elf_segment_map); - amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); - map = (struct elf_segment_map *) bfd_alloc (obfd, amt); - if (map == NULL) - { - free (sections); - return FALSE; - } - - /* Initialise the fields of the segment map. Set the physical - physical address to the LMA of the first section that has - not yet been assigned. */ - map->next = NULL; - map->p_type = segment->p_type; - map->p_flags = segment->p_flags; - map->p_flags_valid = 1; - map->p_paddr = suggested_lma; - map->p_paddr_valid = p_paddr_valid; - map->includes_filehdr = 0; - map->includes_phdrs = 0; - } - } - while (isec < section_count); - - free (sections); - } - - elf_tdata (obfd)->segment_map = map_first; - - /* If we had to estimate the number of program headers that were - going to be needed, then check our estimate now and adjust - the offset if necessary. */ - if (phdr_adjust_seg != NULL) - { - unsigned int count; - - for (count = 0, map = map_first; map != NULL; map = map->next) - count++; - - if (count > phdr_adjust_num) - phdr_adjust_seg->p_paddr - -= (count - phdr_adjust_num) * iehdr->e_phentsize; - } - -#undef SEGMENT_END -#undef SECTION_SIZE -#undef IS_CONTAINED_BY_VMA -#undef IS_CONTAINED_BY_LMA -#undef IS_NOTE -#undef IS_COREFILE_NOTE -#undef IS_SOLARIS_PT_INTERP -#undef IS_SECTION_IN_INPUT_SEGMENT -#undef INCLUDE_SECTION_IN_SEGMENT -#undef SEGMENT_AFTER_SEGMENT -#undef SEGMENT_OVERLAPS - return TRUE; -} - -/* Copy ELF program header information. */ - -static bfd_boolean -copy_elf_program_header (bfd *ibfd, bfd *obfd) -{ - Elf_Internal_Ehdr *iehdr; - struct elf_segment_map *map; - struct elf_segment_map *map_first; - struct elf_segment_map **pointer_to_map; - Elf_Internal_Phdr *segment; - unsigned int i; - unsigned int num_segments; - bfd_boolean phdr_included = FALSE; - bfd_boolean p_paddr_valid; - - iehdr = elf_elfheader (ibfd); - - map_first = NULL; - pointer_to_map = &map_first; - - /* If all the segment p_paddr fields are zero, don't set - map->p_paddr_valid. */ - p_paddr_valid = FALSE; - num_segments = elf_elfheader (ibfd)->e_phnum; - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - if (segment->p_paddr != 0) - { - p_paddr_valid = TRUE; - break; - } - - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - { - asection *section; - unsigned int section_count; - bfd_size_type amt; - Elf_Internal_Shdr *this_hdr; - asection *first_section = NULL; - asection *lowest_section; - - /* Compute how many sections are in this segment. */ - for (section = ibfd->sections, section_count = 0; - section != NULL; - section = section->next) - { - this_hdr = &(elf_section_data(section)->this_hdr); - if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) - { - if (first_section == NULL) - first_section = section; - section_count++; - } - } - - /* Allocate a segment map big enough to contain - all of the sections we have selected. */ - amt = sizeof (struct elf_segment_map); - if (section_count != 0) - amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); - map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); - if (map == NULL) - return FALSE; - - /* Initialize the fields of the output segment map with the - input segment. */ - map->next = NULL; - map->p_type = segment->p_type; - map->p_flags = segment->p_flags; - map->p_flags_valid = 1; - map->p_paddr = segment->p_paddr; - map->p_paddr_valid = p_paddr_valid; - map->p_align = segment->p_align; - map->p_align_valid = 1; - map->p_vaddr_offset = 0; - - if (map->p_type == PT_GNU_RELRO) - { - /* The PT_GNU_RELRO segment may contain the first a few - bytes in the .got.plt section even if the whole .got.plt - section isn't in the PT_GNU_RELRO segment. We won't - change the size of the PT_GNU_RELRO segment. */ - map->p_size = segment->p_memsz; - map->p_size_valid = 1; - } - - /* Determine if this segment contains the ELF file header - and if it contains the program headers themselves. */ - map->includes_filehdr = (segment->p_offset == 0 - && segment->p_filesz >= iehdr->e_ehsize); - - map->includes_phdrs = 0; - if (! phdr_included || segment->p_type != PT_LOAD) - { - map->includes_phdrs = - (segment->p_offset <= (bfd_vma) iehdr->e_phoff - && (segment->p_offset + segment->p_filesz - >= ((bfd_vma) iehdr->e_phoff - + iehdr->e_phnum * iehdr->e_phentsize))); - - if (segment->p_type == PT_LOAD && map->includes_phdrs) - phdr_included = TRUE; - } - - lowest_section = first_section; - if (section_count != 0) - { - unsigned int isec = 0; - - for (section = first_section; - section != NULL; - section = section->next) - { - this_hdr = &(elf_section_data(section)->this_hdr); - if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) - { - map->sections[isec++] = section->output_section; - if (section->lma < lowest_section->lma) - lowest_section = section; - if ((section->flags & SEC_ALLOC) != 0) - { - bfd_vma seg_off; - - /* Section lmas are set up from PT_LOAD header - p_paddr in _bfd_elf_make_section_from_shdr. - If this header has a p_paddr that disagrees - with the section lma, flag the p_paddr as - invalid. */ - if ((section->flags & SEC_LOAD) != 0) - seg_off = this_hdr->sh_offset - segment->p_offset; - else - seg_off = this_hdr->sh_addr - segment->p_vaddr; - if (section->lma - segment->p_paddr != seg_off) - map->p_paddr_valid = FALSE; - } - if (isec == section_count) - break; - } - } - } - - if (map->includes_filehdr && lowest_section != NULL) - /* We need to keep the space used by the headers fixed. */ - map->header_size = lowest_section->vma - segment->p_vaddr; - - if (!map->includes_phdrs - && !map->includes_filehdr - && map->p_paddr_valid) - /* There is some other padding before the first section. */ - map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0) - - segment->p_paddr); - - map->count = section_count; - *pointer_to_map = map; - pointer_to_map = &map->next; - } - - elf_tdata (obfd)->segment_map = map_first; - return TRUE; -} - -/* Copy private BFD data. This copies or rewrites ELF program header - information. */ - -static bfd_boolean -copy_private_bfd_data (bfd *ibfd, bfd *obfd) -{ - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; - - if (elf_tdata (ibfd)->phdr == NULL) - return TRUE; - - if (ibfd->xvec == obfd->xvec) - { - /* Check to see if any sections in the input BFD - covered by ELF program header have changed. */ - Elf_Internal_Phdr *segment; - asection *section, *osec; - unsigned int i, num_segments; - Elf_Internal_Shdr *this_hdr; - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (ibfd); - - /* Regenerate the segment map if p_paddr is set to 0. */ - if (bed->want_p_paddr_set_to_zero) - goto rewrite; - - /* Initialize the segment mark field. */ - for (section = obfd->sections; section != NULL; - section = section->next) - section->segment_mark = FALSE; - - num_segments = elf_elfheader (ibfd)->e_phnum; - for (i = 0, segment = elf_tdata (ibfd)->phdr; - i < num_segments; - i++, segment++) - { - /* PR binutils/3535. The Solaris linker always sets the p_paddr - and p_memsz fields of special segments (DYNAMIC, INTERP) to 0 - which severly confuses things, so always regenerate the segment - map in this case. */ - if (segment->p_paddr == 0 - && segment->p_memsz == 0 - && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC)) - goto rewrite; - - for (section = ibfd->sections; - section != NULL; section = section->next) - { - /* We mark the output section so that we know it comes - from the input BFD. */ - osec = section->output_section; - if (osec) - osec->segment_mark = TRUE; - - /* Check if this section is covered by the segment. */ - this_hdr = &(elf_section_data(section)->this_hdr); - if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) - { - /* FIXME: Check if its output section is changed or - removed. What else do we need to check? */ - if (osec == NULL - || section->flags != osec->flags - || section->lma != osec->lma - || section->vma != osec->vma - || section->size != osec->size - || section->rawsize != osec->rawsize - || section->alignment_power != osec->alignment_power) - goto rewrite; - } - } - } - - /* Check to see if any output section do not come from the - input BFD. */ - for (section = obfd->sections; section != NULL; - section = section->next) - { - if (section->segment_mark == FALSE) - goto rewrite; - else - section->segment_mark = FALSE; - } - - return copy_elf_program_header (ibfd, obfd); - } - -rewrite: - return rewrite_elf_program_header (ibfd, obfd); -} - -/* Initialize private output section information from input section. */ - -bfd_boolean -_bfd_elf_init_private_section_data (bfd *ibfd, - asection *isec, - bfd *obfd, - asection *osec, - struct bfd_link_info *link_info) - -{ - Elf_Internal_Shdr *ihdr, *ohdr; - bfd_boolean final_link = link_info != NULL && !link_info->relocatable; - - if (ibfd->xvec->flavour != bfd_target_elf_flavour - || obfd->xvec->flavour != bfd_target_elf_flavour) - return TRUE; - - BFD_ASSERT (elf_section_data (osec) != NULL); - - /* For objcopy and relocatable link, don't copy the output ELF - section type from input if the output BFD section flags have been - set to something different. For a final link allow some flags - that the linker clears to differ. */ - if (elf_section_type (osec) == SHT_NULL - && (osec->flags == isec->flags - || (final_link - && ((osec->flags ^ isec->flags) - & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0))) - elf_section_type (osec) = elf_section_type (isec); - - /* FIXME: Is this correct for all OS/PROC specific flags? */ - elf_section_flags (osec) |= (elf_section_flags (isec) - & (SHF_MASKOS | SHF_MASKPROC)); - - /* Set things up for objcopy and relocatable link. The output - SHT_GROUP section will have its elf_next_in_group pointing back - to the input group members. Ignore linker created group section. - See elfNN_ia64_object_p in elfxx-ia64.c. */ - if (!final_link) - { - if (elf_sec_group (isec) == NULL - || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0) - { - if (elf_section_flags (isec) & SHF_GROUP) - elf_section_flags (osec) |= SHF_GROUP; - elf_next_in_group (osec) = elf_next_in_group (isec); - elf_section_data (osec)->group = elf_section_data (isec)->group; - } - } - - ihdr = &elf_section_data (isec)->this_hdr; - - /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We - don't use the output section of the linked-to section since it - may be NULL at this point. */ - if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0) - { - ohdr = &elf_section_data (osec)->this_hdr; - ohdr->sh_flags |= SHF_LINK_ORDER; - elf_linked_to_section (osec) = elf_linked_to_section (isec); - } - - osec->use_rela_p = isec->use_rela_p; - - return TRUE; -} - -/* Copy private section information. This copies over the entsize - field, and sometimes the info field. */ - -bfd_boolean -_bfd_elf_copy_private_section_data (bfd *ibfd, - asection *isec, - bfd *obfd, - asection *osec) -{ - Elf_Internal_Shdr *ihdr, *ohdr; - - if (ibfd->xvec->flavour != bfd_target_elf_flavour - || obfd->xvec->flavour != bfd_target_elf_flavour) - return TRUE; - - ihdr = &elf_section_data (isec)->this_hdr; - ohdr = &elf_section_data (osec)->this_hdr; - - ohdr->sh_entsize = ihdr->sh_entsize; - - if (ihdr->sh_type == SHT_SYMTAB - || ihdr->sh_type == SHT_DYNSYM - || ihdr->sh_type == SHT_GNU_verneed - || ihdr->sh_type == SHT_GNU_verdef) - ohdr->sh_info = ihdr->sh_info; - - return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec, - NULL); -} - -/* Look at all the SHT_GROUP sections in IBFD, making any adjustments - necessary if we are removing either the SHT_GROUP section or any of - the group member sections. DISCARDED is the value that a section's - output_section has if the section will be discarded, NULL when this - function is called from objcopy, bfd_abs_section_ptr when called - from the linker. */ - -bfd_boolean -_bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded) -{ - asection *isec; - - for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if (elf_section_type (isec) == SHT_GROUP) - { - asection *first = elf_next_in_group (isec); - asection *s = first; - bfd_size_type removed = 0; - - while (s != NULL) - { - /* If this member section is being output but the - SHT_GROUP section is not, then clear the group info - set up by _bfd_elf_copy_private_section_data. */ - if (s->output_section != discarded - && isec->output_section == discarded) - { - elf_section_flags (s->output_section) &= ~SHF_GROUP; - elf_group_name (s->output_section) = NULL; - } - /* Conversely, if the member section is not being output - but the SHT_GROUP section is, then adjust its size. */ - else if (s->output_section == discarded - && isec->output_section != discarded) - removed += 4; - s = elf_next_in_group (s); - if (s == first) - break; - } - if (removed != 0) - { - if (discarded != NULL) - { - /* If we've been called for ld -r, then we need to - adjust the input section size. This function may - be called multiple times, so save the original - size. */ - if (isec->rawsize == 0) - isec->rawsize = isec->size; - isec->size = isec->rawsize - removed; - } - else - { - /* Adjust the output section size when called from - objcopy. */ - isec->output_section->size -= removed; - } - } - } - - return TRUE; -} - -/* Copy private header information. */ - -bfd_boolean -_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd) -{ - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; - - /* Copy over private BFD data if it has not already been copied. - This must be done here, rather than in the copy_private_bfd_data - entry point, because the latter is called after the section - contents have been set, which means that the program headers have - already been worked out. */ - if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL) - { - if (! copy_private_bfd_data (ibfd, obfd)) - return FALSE; - } - - return _bfd_elf_fixup_group_sections (ibfd, NULL); -} - -/* Copy private symbol information. If this symbol is in a section - which we did not map into a BFD section, try to map the section - index correctly. We use special macro definitions for the mapped - section indices; these definitions are interpreted by the - swap_out_syms function. */ - -#define MAP_ONESYMTAB (SHN_HIOS + 1) -#define MAP_DYNSYMTAB (SHN_HIOS + 2) -#define MAP_STRTAB (SHN_HIOS + 3) -#define MAP_SHSTRTAB (SHN_HIOS + 4) -#define MAP_SYM_SHNDX (SHN_HIOS + 5) - -bfd_boolean -_bfd_elf_copy_private_symbol_data (bfd *ibfd, - asymbol *isymarg, - bfd *obfd, - asymbol *osymarg) -{ - elf_symbol_type *isym, *osym; - - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; - - isym = elf_symbol_from (ibfd, isymarg); - osym = elf_symbol_from (obfd, osymarg); - - if (isym != NULL - && isym->internal_elf_sym.st_shndx != 0 - && osym != NULL - && bfd_is_abs_section (isym->symbol.section)) - { - unsigned int shndx; - - shndx = isym->internal_elf_sym.st_shndx; - if (shndx == elf_onesymtab (ibfd)) - shndx = MAP_ONESYMTAB; - else if (shndx == elf_dynsymtab (ibfd)) - shndx = MAP_DYNSYMTAB; - else if (shndx == elf_tdata (ibfd)->strtab_section) - shndx = MAP_STRTAB; - else if (shndx == elf_tdata (ibfd)->shstrtab_section) - shndx = MAP_SHSTRTAB; - else if (shndx == elf_tdata (ibfd)->symtab_shndx_section) - shndx = MAP_SYM_SHNDX; - osym->internal_elf_sym.st_shndx = shndx; - } - - return TRUE; -} - -/* Swap out the symbols. */ - -static bfd_boolean -swap_out_syms (bfd *abfd, - struct bfd_strtab_hash **sttp, - int relocatable_p) -{ - const struct elf_backend_data *bed; - int symcount; - asymbol **syms; - struct bfd_strtab_hash *stt; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symtab_shndx_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - bfd_byte *outbound_syms; - bfd_byte *outbound_shndx; - int idx; - bfd_size_type amt; - bfd_boolean name_local_sections; - - if (!elf_map_symbols (abfd)) - return FALSE; - - /* Dump out the symtabs. */ - stt = _bfd_elf_stringtab_init (); - if (stt == NULL) - return FALSE; - - bed = get_elf_backend_data (abfd); - symcount = bfd_get_symcount (abfd); - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_entsize = bed->s->sizeof_sym; - symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); - symtab_hdr->sh_info = elf_num_locals (abfd) + 1; - symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; - - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - symstrtab_hdr->sh_type = SHT_STRTAB; - - outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount, - bed->s->sizeof_sym); - if (outbound_syms == NULL) - { - _bfd_stringtab_free (stt); - return FALSE; - } - symtab_hdr->contents = outbound_syms; - - outbound_shndx = NULL; - symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; - if (symtab_shndx_hdr->sh_name != 0) - { - amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx); - outbound_shndx = (bfd_byte *) - bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx)); - if (outbound_shndx == NULL) - { - _bfd_stringtab_free (stt); - return FALSE; - } - - symtab_shndx_hdr->contents = outbound_shndx; - symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; - symtab_shndx_hdr->sh_size = amt; - symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); - symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); - } - - /* Now generate the data (for "contents"). */ - { - /* Fill in zeroth symbol and swap it out. */ - Elf_Internal_Sym sym; - sym.st_name = 0; - sym.st_value = 0; - sym.st_size = 0; - sym.st_info = 0; - sym.st_other = 0; - sym.st_shndx = SHN_UNDEF; - sym.st_target_internal = 0; - bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); - outbound_syms += bed->s->sizeof_sym; - if (outbound_shndx != NULL) - outbound_shndx += sizeof (Elf_External_Sym_Shndx); - } - - name_local_sections - = (bed->elf_backend_name_local_section_symbols - && bed->elf_backend_name_local_section_symbols (abfd)); - - syms = bfd_get_outsymbols (abfd); - for (idx = 0; idx < symcount; idx++) - { - Elf_Internal_Sym sym; - bfd_vma value = syms[idx]->value; - elf_symbol_type *type_ptr; - flagword flags = syms[idx]->flags; - int type; - - if (!name_local_sections - && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) - { - /* Local section symbols have no name. */ - sym.st_name = 0; - } - else - { - sym.st_name = (unsigned long) _bfd_stringtab_add (stt, - syms[idx]->name, - TRUE, FALSE); - if (sym.st_name == (unsigned long) -1) - { - _bfd_stringtab_free (stt); - return FALSE; - } - } - - type_ptr = elf_symbol_from (abfd, syms[idx]); - - if ((flags & BSF_SECTION_SYM) == 0 - && bfd_is_com_section (syms[idx]->section)) - { - /* ELF common symbols put the alignment into the `value' field, - and the size into the `size' field. This is backwards from - how BFD handles it, so reverse it here. */ - sym.st_size = value; - if (type_ptr == NULL - || type_ptr->internal_elf_sym.st_value == 0) - sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value)); - else - sym.st_value = type_ptr->internal_elf_sym.st_value; - sym.st_shndx = _bfd_elf_section_from_bfd_section - (abfd, syms[idx]->section); - } - else - { - asection *sec = syms[idx]->section; - unsigned int shndx; - - if (sec->output_section) - { - value += sec->output_offset; - sec = sec->output_section; - } - - /* Don't add in the section vma for relocatable output. */ - if (! relocatable_p) - value += sec->vma; - sym.st_value = value; - sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0; - - if (bfd_is_abs_section (sec) - && type_ptr != NULL - && type_ptr->internal_elf_sym.st_shndx != 0) - { - /* This symbol is in a real ELF section which we did - not create as a BFD section. Undo the mapping done - by copy_private_symbol_data. */ - shndx = type_ptr->internal_elf_sym.st_shndx; - switch (shndx) - { - case MAP_ONESYMTAB: - shndx = elf_onesymtab (abfd); - break; - case MAP_DYNSYMTAB: - shndx = elf_dynsymtab (abfd); - break; - case MAP_STRTAB: - shndx = elf_tdata (abfd)->strtab_section; - break; - case MAP_SHSTRTAB: - shndx = elf_tdata (abfd)->shstrtab_section; - break; - case MAP_SYM_SHNDX: - shndx = elf_tdata (abfd)->symtab_shndx_section; - break; - default: - break; - } - } - else - { - shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - - if (shndx == SHN_BAD) - { - asection *sec2; - - /* Writing this would be a hell of a lot easier if - we had some decent documentation on bfd, and - knew what to expect of the library, and what to - demand of applications. For example, it - appears that `objcopy' might not set the - section of a symbol to be a section that is - actually in the output file. */ - sec2 = bfd_get_section_by_name (abfd, sec->name); - if (sec2 == NULL) - { - _bfd_error_handler (_("\ -Unable to find equivalent output section for symbol '%s' from section '%s'"), - syms[idx]->name ? syms[idx]->name : "", - sec->name); - bfd_set_error (bfd_error_invalid_operation); - _bfd_stringtab_free (stt); - return FALSE; - } - - shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); - BFD_ASSERT (shndx != SHN_BAD); - } - } - - sym.st_shndx = shndx; - } - - if ((flags & BSF_THREAD_LOCAL) != 0) - type = STT_TLS; - else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0) - type = STT_GNU_IFUNC; - else if ((flags & BSF_FUNCTION) != 0) - type = STT_FUNC; - else if ((flags & BSF_OBJECT) != 0) - type = STT_OBJECT; - else if ((flags & BSF_RELC) != 0) - type = STT_RELC; - else if ((flags & BSF_SRELC) != 0) - type = STT_SRELC; - else - type = STT_NOTYPE; - - if (syms[idx]->section->flags & SEC_THREAD_LOCAL) - type = STT_TLS; - - /* Processor-specific types. */ - if (type_ptr != NULL - && bed->elf_backend_get_symbol_type) - type = ((*bed->elf_backend_get_symbol_type) - (&type_ptr->internal_elf_sym, type)); - - if (flags & BSF_SECTION_SYM) - { - if (flags & BSF_GLOBAL) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - else - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - } - else if (bfd_is_com_section (syms[idx]->section)) - { -#ifdef USE_STT_COMMON - if (type == STT_OBJECT) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON); - else -#endif - sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); - } - else if (bfd_is_und_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) - ? STB_WEAK - : STB_GLOBAL), - type); - else if (flags & BSF_FILE) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - else - { - int bind = STB_LOCAL; - - if (flags & BSF_LOCAL) - bind = STB_LOCAL; - else if (flags & BSF_GNU_UNIQUE) - bind = STB_GNU_UNIQUE; - else if (flags & BSF_WEAK) - bind = STB_WEAK; - else if (flags & BSF_GLOBAL) - bind = STB_GLOBAL; - - sym.st_info = ELF_ST_INFO (bind, type); - } - - if (type_ptr != NULL) - { - sym.st_other = type_ptr->internal_elf_sym.st_other; - sym.st_target_internal - = type_ptr->internal_elf_sym.st_target_internal; - } - else - { - sym.st_other = 0; - sym.st_target_internal = 0; - } - - bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); - outbound_syms += bed->s->sizeof_sym; - if (outbound_shndx != NULL) - outbound_shndx += sizeof (Elf_External_Sym_Shndx); - } - - *sttp = stt; - symstrtab_hdr->sh_size = _bfd_stringtab_size (stt); - symstrtab_hdr->sh_type = SHT_STRTAB; - - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - symstrtab_hdr->sh_addralign = 1; - - return TRUE; -} - -/* Return the number of bytes required to hold the symtab vector. - - Note that we base it on the count plus 1, since we will null terminate - the vector allocated based on this size. However, the ELF symbol table - always has a dummy entry as symbol #0, so it ends up even. */ - -long -_bfd_elf_get_symtab_upper_bound (bfd *abfd) -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; - - symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - symtab_size = (symcount + 1) * (sizeof (asymbol *)); - if (symcount > 0) - symtab_size -= sizeof (asymbol *); - - return symtab_size; -} - -long -_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; - - if (elf_dynsymtab (abfd) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - symtab_size = (symcount + 1) * (sizeof (asymbol *)); - if (symcount > 0) - symtab_size -= sizeof (asymbol *); - - return symtab_size; -} - -long -_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr asect) -{ - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -/* Canonicalize the relocs. */ - -long -_bfd_elf_canonicalize_reloc (bfd *abfd, - sec_ptr section, - arelent **relptr, - asymbol **symbols) -{ - arelent *tblptr; - unsigned int i; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE)) - return -1; - - tblptr = section->relocation; - for (i = 0; i < section->reloc_count; i++) - *relptr++ = tblptr++; - - *relptr = NULL; - - return section->reloc_count; -} - -long -_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE); - - if (symcount >= 0) - bfd_get_symcount (abfd) = symcount; - return symcount; -} - -long -_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, - asymbol **allocation) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE); - - if (symcount >= 0) - bfd_get_dynamic_symcount (abfd) = symcount; - return symcount; -} - -/* Return the size required for the dynamic reloc entries. Any loadable - section that was actually installed in the BFD, and has type SHT_REL - or SHT_RELA, and uses the dynamic symbol table, is considered to be a - dynamic reloc section. */ - -long -_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) -{ - long ret; - asection *s; - - if (elf_dynsymtab (abfd) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - ret = sizeof (arelent *); - for (s = abfd->sections; s != NULL; s = s->next) - if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) - && (elf_section_data (s)->this_hdr.sh_type == SHT_REL - || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) - ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize) - * sizeof (arelent *)); - - return ret; -} - -/* Canonicalize the dynamic relocation entries. Note that we return the - dynamic relocations as a single block, although they are actually - associated with particular sections; the interface, which was - designed for SunOS style shared libraries, expects that there is only - one set of dynamic relocs. Any loadable section that was actually - installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the - dynamic symbol table, is considered to be a dynamic reloc section. */ - -long -_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd, - arelent **storage, - asymbol **syms) -{ - bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); - asection *s; - long ret; - - if (elf_dynsymtab (abfd) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; - ret = 0; - for (s = abfd->sections; s != NULL; s = s->next) - { - if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) - && (elf_section_data (s)->this_hdr.sh_type == SHT_REL - || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) - { - arelent *p; - long count, i; - - if (! (*slurp_relocs) (abfd, s, syms, TRUE)) - return -1; - count = s->size / elf_section_data (s)->this_hdr.sh_entsize; - p = s->relocation; - for (i = 0; i < count; i++) - *storage++ = p++; - ret += count; - } - } - - *storage = NULL; - - return ret; -} - -/* Read in the version information. */ - -bfd_boolean -_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) -{ - bfd_byte *contents = NULL; - unsigned int freeidx = 0; - - if (elf_dynverref (abfd) != 0) - { - Elf_Internal_Shdr *hdr; - Elf_External_Verneed *everneed; - Elf_Internal_Verneed *iverneed; - unsigned int i; - bfd_byte *contents_end; - - hdr = &elf_tdata (abfd)->dynverref_hdr; - - elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) - bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed)); - if (elf_tdata (abfd)->verref == NULL) - goto error_return; - - elf_tdata (abfd)->cverrefs = hdr->sh_info; - - contents = (bfd_byte *) bfd_malloc (hdr->sh_size); - if (contents == NULL) - { -error_return_verref: - elf_tdata (abfd)->verref = NULL; - elf_tdata (abfd)->cverrefs = 0; - goto error_return; - } - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) - goto error_return_verref; - - if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed)) - goto error_return_verref; - - BFD_ASSERT (sizeof (Elf_External_Verneed) - == sizeof (Elf_External_Vernaux)); - contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed); - everneed = (Elf_External_Verneed *) contents; - iverneed = elf_tdata (abfd)->verref; - for (i = 0; i < hdr->sh_info; i++, iverneed++) - { - Elf_External_Vernaux *evernaux; - Elf_Internal_Vernaux *ivernaux; - unsigned int j; - - _bfd_elf_swap_verneed_in (abfd, everneed, iverneed); - - iverneed->vn_bfd = abfd; - - iverneed->vn_filename = - bfd_elf_string_from_elf_section (abfd, hdr->sh_link, - iverneed->vn_file); - if (iverneed->vn_filename == NULL) - goto error_return_verref; - - if (iverneed->vn_cnt == 0) - iverneed->vn_auxptr = NULL; - else - { - iverneed->vn_auxptr = (struct elf_internal_vernaux *) - bfd_alloc2 (abfd, iverneed->vn_cnt, - sizeof (Elf_Internal_Vernaux)); - if (iverneed->vn_auxptr == NULL) - goto error_return_verref; - } - - if (iverneed->vn_aux - > (size_t) (contents_end - (bfd_byte *) everneed)) - goto error_return_verref; - - evernaux = ((Elf_External_Vernaux *) - ((bfd_byte *) everneed + iverneed->vn_aux)); - ivernaux = iverneed->vn_auxptr; - for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++) - { - _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux); - - ivernaux->vna_nodename = - bfd_elf_string_from_elf_section (abfd, hdr->sh_link, - ivernaux->vna_name); - if (ivernaux->vna_nodename == NULL) - goto error_return_verref; - - if (j + 1 < iverneed->vn_cnt) - ivernaux->vna_nextptr = ivernaux + 1; - else - ivernaux->vna_nextptr = NULL; - - if (ivernaux->vna_next - > (size_t) (contents_end - (bfd_byte *) evernaux)) - goto error_return_verref; - - evernaux = ((Elf_External_Vernaux *) - ((bfd_byte *) evernaux + ivernaux->vna_next)); - - if (ivernaux->vna_other > freeidx) - freeidx = ivernaux->vna_other; - } - - if (i + 1 < hdr->sh_info) - iverneed->vn_nextref = iverneed + 1; - else - iverneed->vn_nextref = NULL; - - if (iverneed->vn_next - > (size_t) (contents_end - (bfd_byte *) everneed)) - goto error_return_verref; - - everneed = ((Elf_External_Verneed *) - ((bfd_byte *) everneed + iverneed->vn_next)); - } - - free (contents); - contents = NULL; - } - - if (elf_dynverdef (abfd) != 0) - { - Elf_Internal_Shdr *hdr; - Elf_External_Verdef *everdef; - Elf_Internal_Verdef *iverdef; - Elf_Internal_Verdef *iverdefarr; - Elf_Internal_Verdef iverdefmem; - unsigned int i; - unsigned int maxidx; - bfd_byte *contents_end_def, *contents_end_aux; - - hdr = &elf_tdata (abfd)->dynverdef_hdr; - - contents = (bfd_byte *) bfd_malloc (hdr->sh_size); - if (contents == NULL) - goto error_return; - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) - goto error_return; - - if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef)) - goto error_return; - - BFD_ASSERT (sizeof (Elf_External_Verdef) - >= sizeof (Elf_External_Verdaux)); - contents_end_def = contents + hdr->sh_size - - sizeof (Elf_External_Verdef); - contents_end_aux = contents + hdr->sh_size - - sizeof (Elf_External_Verdaux); - - /* We know the number of entries in the section but not the maximum - index. Therefore we have to run through all entries and find - the maximum. */ - everdef = (Elf_External_Verdef *) contents; - maxidx = 0; - for (i = 0; i < hdr->sh_info; ++i) - { - _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); - - if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) - maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION); - - if (iverdefmem.vd_next - > (size_t) (contents_end_def - (bfd_byte *) everdef)) - goto error_return; - - everdef = ((Elf_External_Verdef *) - ((bfd_byte *) everdef + iverdefmem.vd_next)); - } - - if (default_imported_symver) - { - if (freeidx > maxidx) - maxidx = ++freeidx; - else - freeidx = ++maxidx; - } - elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) - bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef)); - if (elf_tdata (abfd)->verdef == NULL) - goto error_return; - - elf_tdata (abfd)->cverdefs = maxidx; - - everdef = (Elf_External_Verdef *) contents; - iverdefarr = elf_tdata (abfd)->verdef; - for (i = 0; i < hdr->sh_info; i++) - { - Elf_External_Verdaux *everdaux; - Elf_Internal_Verdaux *iverdaux; - unsigned int j; - - _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); - - if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0) - { -error_return_verdef: - elf_tdata (abfd)->verdef = NULL; - elf_tdata (abfd)->cverdefs = 0; - goto error_return; - } - - iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1]; - memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef)); - - iverdef->vd_bfd = abfd; - - if (iverdef->vd_cnt == 0) - iverdef->vd_auxptr = NULL; - else - { - iverdef->vd_auxptr = (struct elf_internal_verdaux *) - bfd_alloc2 (abfd, iverdef->vd_cnt, - sizeof (Elf_Internal_Verdaux)); - if (iverdef->vd_auxptr == NULL) - goto error_return_verdef; - } - - if (iverdef->vd_aux - > (size_t) (contents_end_aux - (bfd_byte *) everdef)) - goto error_return_verdef; - - everdaux = ((Elf_External_Verdaux *) - ((bfd_byte *) everdef + iverdef->vd_aux)); - iverdaux = iverdef->vd_auxptr; - for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++) - { - _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux); - - iverdaux->vda_nodename = - bfd_elf_string_from_elf_section (abfd, hdr->sh_link, - iverdaux->vda_name); - if (iverdaux->vda_nodename == NULL) - goto error_return_verdef; - - if (j + 1 < iverdef->vd_cnt) - iverdaux->vda_nextptr = iverdaux + 1; - else - iverdaux->vda_nextptr = NULL; - - if (iverdaux->vda_next - > (size_t) (contents_end_aux - (bfd_byte *) everdaux)) - goto error_return_verdef; - - everdaux = ((Elf_External_Verdaux *) - ((bfd_byte *) everdaux + iverdaux->vda_next)); - } - - if (iverdef->vd_cnt) - iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename; - - if ((size_t) (iverdef - iverdefarr) + 1 < maxidx) - iverdef->vd_nextdef = iverdef + 1; - else - iverdef->vd_nextdef = NULL; - - everdef = ((Elf_External_Verdef *) - ((bfd_byte *) everdef + iverdef->vd_next)); - } - - free (contents); - contents = NULL; - } - else if (default_imported_symver) - { - if (freeidx < 3) - freeidx = 3; - else - freeidx++; - - elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) - bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef)); - if (elf_tdata (abfd)->verdef == NULL) - goto error_return; - - elf_tdata (abfd)->cverdefs = freeidx; - } - - /* Create a default version based on the soname. */ - if (default_imported_symver) - { - Elf_Internal_Verdef *iverdef; - Elf_Internal_Verdaux *iverdaux; - - iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];; - - iverdef->vd_version = VER_DEF_CURRENT; - iverdef->vd_flags = 0; - iverdef->vd_ndx = freeidx; - iverdef->vd_cnt = 1; - - iverdef->vd_bfd = abfd; - - iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); - if (iverdef->vd_nodename == NULL) - goto error_return_verdef; - iverdef->vd_nextdef = NULL; - iverdef->vd_auxptr = (struct elf_internal_verdaux *) - bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux)); - if (iverdef->vd_auxptr == NULL) - goto error_return_verdef; - - iverdaux = iverdef->vd_auxptr; - iverdaux->vda_nodename = iverdef->vd_nodename; - iverdaux->vda_nextptr = NULL; - } - - return TRUE; - - error_return: - if (contents != NULL) - free (contents); - return FALSE; -} - -asymbol * -_bfd_elf_make_empty_symbol (bfd *abfd) -{ - elf_symbol_type *newsym; - bfd_size_type amt = sizeof (elf_symbol_type); - - newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt); - if (!newsym) - return NULL; - else - { - newsym->symbol.the_bfd = abfd; - return &newsym->symbol; - } -} - -void -_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, - asymbol *symbol, - symbol_info *ret) -{ - bfd_symbol_info (symbol, ret); -} - -/* Return whether a symbol name implies a local symbol. Most targets - use this function for the is_local_label_name entry point, but some - override it. */ - -bfd_boolean -_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, - const char *name) -{ - /* Normal local symbols start with ``.L''. */ - if (name[0] == '.' && name[1] == 'L') - return TRUE; - - /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate - DWARF debugging symbols starting with ``..''. */ - if (name[0] == '.' && name[1] == '.') - return TRUE; - - /* gcc will sometimes generate symbols beginning with ``_.L_'' when - emitting DWARF debugging output. I suspect this is actually a - small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call - ASM_GENERATE_INTERNAL_LABEL, and this causes the leading - underscore to be emitted on some ELF targets). For ease of use, - we treat such symbols as local. */ - if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_') - return TRUE; - - return FALSE; -} - -alent * -_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED, - asymbol *symbol ATTRIBUTE_UNUSED) -{ - abort (); - return NULL; -} - -bfd_boolean -_bfd_elf_set_arch_mach (bfd *abfd, - enum bfd_architecture arch, - unsigned long machine) -{ - /* If this isn't the right architecture for this backend, and this - isn't the generic backend, fail. */ - if (arch != get_elf_backend_data (abfd)->arch - && arch != bfd_arch_unknown - && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) - return FALSE; - - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -/* Find the function to a particular section and offset, - for error reporting. */ - -static bfd_boolean -elf_find_function (bfd *abfd, - asection *section, - asymbol **symbols, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr) -{ - const char *filename; - asymbol *func, *file; - bfd_vma low_func; - asymbol **p; - /* ??? Given multiple file symbols, it is impossible to reliably - choose the right file name for global symbols. File symbols are - local symbols, and thus all file symbols must sort before any - global symbols. The ELF spec may be interpreted to say that a - file symbol must sort before other local symbols, but currently - ld -r doesn't do this. So, for ld -r output, it is possible to - make a better choice of file name for local symbols by ignoring - file symbols appearing after a given local symbol. */ - enum { nothing_seen, symbol_seen, file_after_symbol_seen } state; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (symbols == NULL) - return FALSE; - - filename = NULL; - func = NULL; - file = NULL; - low_func = 0; - state = nothing_seen; - - for (p = symbols; *p != NULL; p++) - { - elf_symbol_type *q; - unsigned int type; - - q = (elf_symbol_type *) *p; - - type = ELF_ST_TYPE (q->internal_elf_sym.st_info); - switch (type) - { - case STT_FILE: - file = &q->symbol; - if (state == symbol_seen) - state = file_after_symbol_seen; - continue; - default: - if (!bed->is_function_type (type)) - break; - case STT_NOTYPE: - if (bfd_get_section (&q->symbol) == section - && q->symbol.value >= low_func - && q->symbol.value <= offset) - { - func = (asymbol *) q; - low_func = q->symbol.value; - filename = NULL; - if (file != NULL - && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL - || state != file_after_symbol_seen)) - filename = bfd_asymbol_name (file); - } - break; - } - if (state == nothing_seen) - state = symbol_seen; - } - - if (func == NULL) - return FALSE; - - if (filename_ptr) - *filename_ptr = filename; - if (functionname_ptr) - *functionname_ptr = bfd_asymbol_name (func); - - return TRUE; -} - -/* Find the nearest line to a particular section and offset, - for error reporting. */ - -bfd_boolean -_bfd_elf_find_nearest_line (bfd *abfd, - asection *section, - asymbol **symbols, - bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr) -{ - bfd_boolean found; - - if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr)) - { - if (!*functionname_ptr) - elf_find_function (abfd, section, symbols, offset, - *filename_ptr ? NULL : filename_ptr, - functionname_ptr); - - return TRUE; - } - - if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr, 0, - &elf_tdata (abfd)->dwarf2_find_line_info)) - { - if (!*functionname_ptr) - elf_find_function (abfd, section, symbols, offset, - *filename_ptr ? NULL : filename_ptr, - functionname_ptr); - - return TRUE; - } - - if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - &found, filename_ptr, - functionname_ptr, line_ptr, - &elf_tdata (abfd)->line_info)) - return FALSE; - if (found && (*functionname_ptr || *line_ptr)) - return TRUE; - - if (symbols == NULL) - return FALSE; - - if (! elf_find_function (abfd, section, symbols, offset, - filename_ptr, functionname_ptr)) - return FALSE; - - *line_ptr = 0; - return TRUE; -} - -/* Find the line for a symbol. */ - -bfd_boolean -_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, - const char **filename_ptr, unsigned int *line_ptr) -{ - return _bfd_dwarf2_find_line (abfd, symbols, symbol, - filename_ptr, line_ptr, 0, - &elf_tdata (abfd)->dwarf2_find_line_info); -} - -/* After a call to bfd_find_nearest_line, successive calls to - bfd_find_inliner_info can be used to get source information about - each level of function inlining that terminated at the address - passed to bfd_find_nearest_line. Currently this is only supported - for DWARF2 with appropriate DWARF3 extensions. */ - -bfd_boolean -_bfd_elf_find_inliner_info (bfd *abfd, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr) -{ - bfd_boolean found; - found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, - functionname_ptr, line_ptr, - & elf_tdata (abfd)->dwarf2_find_line_info); - return found; -} - -int -_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - int ret = bed->s->sizeof_ehdr; - - if (!info->relocatable) - { - bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; - - if (phdr_size == (bfd_size_type) -1) - { - struct elf_segment_map *m; - - phdr_size = 0; - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - phdr_size += bed->s->sizeof_phdr; - - if (phdr_size == 0) - phdr_size = get_program_header_size (abfd, info); - } - - elf_tdata (abfd)->program_header_size = phdr_size; - ret += phdr_size; - } - - return ret; -} - -bfd_boolean -_bfd_elf_set_section_contents (bfd *abfd, - sec_ptr section, - const void *location, - file_ptr offset, - bfd_size_type count) -{ - Elf_Internal_Shdr *hdr; - bfd_signed_vma pos; - - if (! abfd->output_has_begun - && ! _bfd_elf_compute_section_file_positions (abfd, NULL)) - return FALSE; - - hdr = &elf_section_data (section)->this_hdr; - pos = hdr->sh_offset + offset; - if (bfd_seek (abfd, pos, SEEK_SET) != 0 - || bfd_bwrite (location, count, abfd) != count) - return FALSE; - - return TRUE; -} - -void -_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, - arelent *cache_ptr ATTRIBUTE_UNUSED, - Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) -{ - abort (); -} - -/* Try to convert a non-ELF reloc into an ELF one. */ - -bfd_boolean -_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc) -{ - /* Check whether we really have an ELF howto. */ - - if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec) - { - bfd_reloc_code_real_type code; - reloc_howto_type *howto; - - /* Alien reloc: Try to determine its type to replace it with an - equivalent ELF reloc. */ - - if (areloc->howto->pc_relative) - { - switch (areloc->howto->bitsize) - { - case 8: - code = BFD_RELOC_8_PCREL; - break; - case 12: - code = BFD_RELOC_12_PCREL; - break; - case 16: - code = BFD_RELOC_16_PCREL; - break; - case 24: - code = BFD_RELOC_24_PCREL; - break; - case 32: - code = BFD_RELOC_32_PCREL; - break; - case 64: - code = BFD_RELOC_64_PCREL; - break; - default: - goto fail; - } - - howto = bfd_reloc_type_lookup (abfd, code); - - if (areloc->howto->pcrel_offset != howto->pcrel_offset) - { - if (howto->pcrel_offset) - areloc->addend += areloc->address; - else - areloc->addend -= areloc->address; /* addend is unsigned!! */ - } - } - else - { - switch (areloc->howto->bitsize) - { - case 8: - code = BFD_RELOC_8; - break; - case 14: - code = BFD_RELOC_14; - break; - case 16: - code = BFD_RELOC_16; - break; - case 26: - code = BFD_RELOC_26; - break; - case 32: - code = BFD_RELOC_32; - break; - case 64: - code = BFD_RELOC_64; - break; - default: - goto fail; - } - - howto = bfd_reloc_type_lookup (abfd, code); - } - - if (howto) - areloc->howto = howto; - else - goto fail; - } - - return TRUE; - - fail: - (*_bfd_error_handler) - (_("%B: unsupported relocation type %s"), - abfd, areloc->howto->name); - bfd_set_error (bfd_error_bad_value); - return FALSE; -} - -bfd_boolean -_bfd_elf_close_and_cleanup (bfd *abfd) -{ - if (bfd_get_format (abfd) == bfd_object) - { - if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL) - _bfd_elf_strtab_free (elf_shstrtab (abfd)); - _bfd_dwarf2_cleanup_debug_info (abfd); - } - - return _bfd_generic_close_and_cleanup (abfd); -} - -/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY - in the relocation's offset. Thus we cannot allow any sort of sanity - range-checking to interfere. There is nothing else to do in processing - this reloc. */ - -bfd_reloc_status_type -_bfd_elf_rel_vtable_reloc_fn - (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED, - struct bfd_symbol *symbol ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED) -{ - return bfd_reloc_ok; -} - -/* Elf core file support. Much of this only works on native - toolchains, since we rely on knowing the - machine-dependent procfs structure in order to pick - out details about the corefile. */ - -#ifdef HAVE_SYS_PROCFS_H -/* Needed for new procfs interface on sparc-solaris. */ -# define _STRUCTURED_PROC 1 -# include -#endif - -/* Return a PID that identifies a "thread" for threaded cores, or the - PID of the main process for non-threaded cores. */ - -static int -elfcore_make_pid (bfd *abfd) -{ - int pid; - - pid = elf_tdata (abfd)->core_lwpid; - if (pid == 0) - pid = elf_tdata (abfd)->core_pid; - - return pid; -} - -/* If there isn't a section called NAME, make one, using - data from SECT. Note, this function will generate a - reference to NAME, so you shouldn't deallocate or - overwrite it. */ - -static bfd_boolean -elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect) -{ - asection *sect2; - - if (bfd_get_section_by_name (abfd, name) != NULL) - return TRUE; - - sect2 = bfd_make_section_with_flags (abfd, name, sect->flags); - if (sect2 == NULL) - return FALSE; - - sect2->size = sect->size; - sect2->filepos = sect->filepos; - sect2->alignment_power = sect->alignment_power; - return TRUE; -} - -/* Create a pseudosection containing SIZE bytes at FILEPOS. This - actually creates up to two pseudosections: - - For the single-threaded case, a section named NAME, unless - such a section already exists. - - For the multi-threaded case, a section named "NAME/PID", where - PID is elfcore_make_pid (abfd). - Both pseudosections have identical contents. */ -bfd_boolean -_bfd_elfcore_make_pseudosection (bfd *abfd, - char *name, - size_t size, - ufile_ptr filepos) -{ - char buf[100]; - char *threaded_name; - size_t len; - asection *sect; - - /* Build the section name. */ - - sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd)); - len = strlen (buf) + 1; - threaded_name = (char *) bfd_alloc (abfd, len); - if (threaded_name == NULL) - return FALSE; - memcpy (threaded_name, buf, len); - - sect = bfd_make_section_anyway_with_flags (abfd, threaded_name, - SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - sect->size = size; - sect->filepos = filepos; - sect->alignment_power = 2; - - return elfcore_maybe_make_sect (abfd, name, sect); -} - -/* prstatus_t exists on: - solaris 2.5+ - linux 2.[01] + glibc - unixware 4.2 -*/ - -#if defined (HAVE_PRSTATUS_T) - -static bfd_boolean -elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) -{ - size_t size; - int offset; - - if (note->descsz == sizeof (prstatus_t)) - { - prstatus_t prstat; - - size = sizeof (prstat.pr_reg); - offset = offsetof (prstatus_t, pr_reg); - memcpy (&prstat, note->descdata, sizeof (prstat)); - - /* Do not overwrite the core signal if it - has already been set by another thread. */ - if (elf_tdata (abfd)->core_signal == 0) - elf_tdata (abfd)->core_signal = prstat.pr_cursig; - if (elf_tdata (abfd)->core_pid == 0) - elf_tdata (abfd)->core_pid = prstat.pr_pid; - - /* pr_who exists on: - solaris 2.5+ - unixware 4.2 - pr_who doesn't exist on: - linux 2.[01] - */ -#if defined (HAVE_PRSTATUS_T_PR_WHO) - elf_tdata (abfd)->core_lwpid = prstat.pr_who; -#else - elf_tdata (abfd)->core_lwpid = prstat.pr_pid; -#endif - } -#if defined (HAVE_PRSTATUS32_T) - else if (note->descsz == sizeof (prstatus32_t)) - { - /* 64-bit host, 32-bit corefile */ - prstatus32_t prstat; - - size = sizeof (prstat.pr_reg); - offset = offsetof (prstatus32_t, pr_reg); - memcpy (&prstat, note->descdata, sizeof (prstat)); - - /* Do not overwrite the core signal if it - has already been set by another thread. */ - if (elf_tdata (abfd)->core_signal == 0) - elf_tdata (abfd)->core_signal = prstat.pr_cursig; - if (elf_tdata (abfd)->core_pid == 0) - elf_tdata (abfd)->core_pid = prstat.pr_pid; - - /* pr_who exists on: - solaris 2.5+ - unixware 4.2 - pr_who doesn't exist on: - linux 2.[01] - */ -#if defined (HAVE_PRSTATUS32_T_PR_WHO) - elf_tdata (abfd)->core_lwpid = prstat.pr_who; -#else - elf_tdata (abfd)->core_lwpid = prstat.pr_pid; -#endif - } -#endif /* HAVE_PRSTATUS32_T */ - else - { - /* Fail - we don't know how to handle any other - note size (ie. data object type). */ - return TRUE; - } - - /* Make a ".reg/999" section and a ".reg" section. */ - return _bfd_elfcore_make_pseudosection (abfd, ".reg", - size, note->descpos + offset); -} -#endif /* defined (HAVE_PRSTATUS_T) */ - -/* Create a pseudosection containing the exact contents of NOTE. */ -static bfd_boolean -elfcore_make_note_pseudosection (bfd *abfd, - char *name, - Elf_Internal_Note *note) -{ - return _bfd_elfcore_make_pseudosection (abfd, name, - note->descsz, note->descpos); -} - -/* There isn't a consistent prfpregset_t across platforms, - but it doesn't matter, because we don't have to pick this - data structure apart. */ - -static bfd_boolean -elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg2", note); -} - -/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note - type of NT_PRXFPREG. Just include the whole note's contents - literally. */ - -static bfd_boolean -elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); -} - -/* Linux dumps the Intel XSAVE extended state in a note named "LINUX" - with a note type of NT_X86_XSTATE. Just include the whole note's - contents literally. */ - -static bfd_boolean -elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note); -} - -static bfd_boolean -elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note); -} - -static bfd_boolean -elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note); -} - -static bfd_boolean -elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note); -} - -static bfd_boolean -elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note); -} - -static bfd_boolean -elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note); -} - -static bfd_boolean -elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note); -} - -static bfd_boolean -elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note); -} - -static bfd_boolean -elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note); -} - -static bfd_boolean -elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note) -{ - return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note); -} - -#if defined (HAVE_PRPSINFO_T) -typedef prpsinfo_t elfcore_psinfo_t; -#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */ -typedef prpsinfo32_t elfcore_psinfo32_t; -#endif -#endif - -#if defined (HAVE_PSINFO_T) -typedef psinfo_t elfcore_psinfo_t; -#if defined (HAVE_PSINFO32_T) /* Sparc64 cross Sparc32 */ -typedef psinfo32_t elfcore_psinfo32_t; -#endif -#endif - -/* return a malloc'ed copy of a string at START which is at - most MAX bytes long, possibly without a terminating '\0'. - the copy will always have a terminating '\0'. */ - -char * -_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max) -{ - char *dups; - char *end = (char *) memchr (start, '\0', max); - size_t len; - - if (end == NULL) - len = max; - else - len = end - start; - - dups = (char *) bfd_alloc (abfd, len + 1); - if (dups == NULL) - return NULL; - - memcpy (dups, start, len); - dups[len] = '\0'; - - return dups; -} - -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) -static bfd_boolean -elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) -{ - if (note->descsz == sizeof (elfcore_psinfo_t)) - { - elfcore_psinfo_t psinfo; - - memcpy (&psinfo, note->descdata, sizeof (psinfo)); - -#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID) - elf_tdata (abfd)->core_pid = psinfo.pr_pid; -#endif - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, - sizeof (psinfo.pr_fname)); - - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, - sizeof (psinfo.pr_psargs)); - } -#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) - else if (note->descsz == sizeof (elfcore_psinfo32_t)) - { - /* 64-bit host, 32-bit corefile */ - elfcore_psinfo32_t psinfo; - - memcpy (&psinfo, note->descdata, sizeof (psinfo)); - -#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID) - elf_tdata (abfd)->core_pid = psinfo.pr_pid; -#endif - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, - sizeof (psinfo.pr_fname)); - - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, - sizeof (psinfo.pr_psargs)); - } -#endif - - else - { - /* Fail - we don't know how to handle any other - note size (ie. data object type). */ - return TRUE; - } - - /* Note that for some reason, a spurious space is tacked - onto the end of the args in some (at least one anyway) - implementations, so strip it off if it exists. */ - - { - char *command = elf_tdata (abfd)->core_command; - int n = strlen (command); - - if (0 < n && command[n - 1] == ' ') - command[n - 1] = '\0'; - } - - return TRUE; -} -#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */ - -#if defined (HAVE_PSTATUS_T) -static bfd_boolean -elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) -{ - if (note->descsz == sizeof (pstatus_t) -#if defined (HAVE_PXSTATUS_T) - || note->descsz == sizeof (pxstatus_t) -#endif - ) - { - pstatus_t pstat; - - memcpy (&pstat, note->descdata, sizeof (pstat)); - - elf_tdata (abfd)->core_pid = pstat.pr_pid; - } -#if defined (HAVE_PSTATUS32_T) - else if (note->descsz == sizeof (pstatus32_t)) - { - /* 64-bit host, 32-bit corefile */ - pstatus32_t pstat; - - memcpy (&pstat, note->descdata, sizeof (pstat)); - - elf_tdata (abfd)->core_pid = pstat.pr_pid; - } -#endif - /* Could grab some more details from the "representative" - lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an - NT_LWPSTATUS note, presumably. */ - - return TRUE; -} -#endif /* defined (HAVE_PSTATUS_T) */ - -#if defined (HAVE_LWPSTATUS_T) -static bfd_boolean -elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note) -{ - lwpstatus_t lwpstat; - char buf[100]; - char *name; - size_t len; - asection *sect; - - if (note->descsz != sizeof (lwpstat) -#if defined (HAVE_LWPXSTATUS_T) - && note->descsz != sizeof (lwpxstatus_t) -#endif - ) - return TRUE; - - memcpy (&lwpstat, note->descdata, sizeof (lwpstat)); - - elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid; - /* Do not overwrite the core signal if it has already been set by - another thread. */ - if (elf_tdata (abfd)->core_signal == 0) - elf_tdata (abfd)->core_signal = lwpstat.pr_cursig; - - /* Make a ".reg/999" section. */ - - sprintf (buf, ".reg/%d", elfcore_make_pid (abfd)); - len = strlen (buf) + 1; - name = bfd_alloc (abfd, len); - if (name == NULL) - return FALSE; - memcpy (name, buf, len); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - -#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) - sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs); - sect->filepos = note->descpos - + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs); -#endif - -#if defined (HAVE_LWPSTATUS_T_PR_REG) - sect->size = sizeof (lwpstat.pr_reg); - sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg); -#endif - - sect->alignment_power = 2; - - if (!elfcore_maybe_make_sect (abfd, ".reg", sect)) - return FALSE; - - /* Make a ".reg2/999" section */ - - sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd)); - len = strlen (buf) + 1; - name = bfd_alloc (abfd, len); - if (name == NULL) - return FALSE; - memcpy (name, buf, len); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - -#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT) - sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs); - sect->filepos = note->descpos - + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs); -#endif - -#if defined (HAVE_LWPSTATUS_T_PR_FPREG) - sect->size = sizeof (lwpstat.pr_fpreg); - sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg); -#endif - - sect->alignment_power = 2; - - return elfcore_maybe_make_sect (abfd, ".reg2", sect); -} -#endif /* defined (HAVE_LWPSTATUS_T) */ - -static bfd_boolean -elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note) -{ - char buf[30]; - char *name; - size_t len; - asection *sect; - int type; - int is_active_thread; - bfd_vma base_addr; - - if (note->descsz < 728) - return TRUE; - - if (! CONST_STRNEQ (note->namedata, "win32")) - return TRUE; - - type = bfd_get_32 (abfd, note->descdata); - - switch (type) - { - case 1 /* NOTE_INFO_PROCESS */: - /* FIXME: need to add ->core_command. */ - /* process_info.pid */ - elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 8); - /* process_info.signal */ - elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 12); - break; - - case 2 /* NOTE_INFO_THREAD */: - /* Make a ".reg/999" section. */ - /* thread_info.tid */ - sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8)); - - len = strlen (buf) + 1; - name = (char *) bfd_alloc (abfd, len); - if (name == NULL) - return FALSE; - - memcpy (name, buf, len); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - - /* sizeof (thread_info.thread_context) */ - sect->size = 716; - /* offsetof (thread_info.thread_context) */ - sect->filepos = note->descpos + 12; - sect->alignment_power = 2; - - /* thread_info.is_active_thread */ - is_active_thread = bfd_get_32 (abfd, note->descdata + 8); - - if (is_active_thread) - if (! elfcore_maybe_make_sect (abfd, ".reg", sect)) - return FALSE; - break; - - case 3 /* NOTE_INFO_MODULE */: - /* Make a ".module/xxxxxxxx" section. */ - /* module_info.base_address */ - base_addr = bfd_get_32 (abfd, note->descdata + 4); - sprintf (buf, ".module/%08lx", (unsigned long) base_addr); - - len = strlen (buf) + 1; - name = (char *) bfd_alloc (abfd, len); - if (name == NULL) - return FALSE; - - memcpy (name, buf, len); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - - if (sect == NULL) - return FALSE; - - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 2; - break; - - default: - return TRUE; - } - - return TRUE; -} - -static bfd_boolean -elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - switch (note->type) - { - default: - return TRUE; - - case NT_PRSTATUS: - if (bed->elf_backend_grok_prstatus) - if ((*bed->elf_backend_grok_prstatus) (abfd, note)) - return TRUE; -#if defined (HAVE_PRSTATUS_T) - return elfcore_grok_prstatus (abfd, note); -#else - return TRUE; -#endif - -#if defined (HAVE_PSTATUS_T) - case NT_PSTATUS: - return elfcore_grok_pstatus (abfd, note); -#endif - -#if defined (HAVE_LWPSTATUS_T) - case NT_LWPSTATUS: - return elfcore_grok_lwpstatus (abfd, note); -#endif - - case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */ - return elfcore_grok_prfpreg (abfd, note); - - case NT_WIN32PSTATUS: - return elfcore_grok_win32pstatus (abfd, note); - - case NT_PRXFPREG: /* Linux SSE extension */ - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_prxfpreg (abfd, note); - else - return TRUE; - - case NT_X86_XSTATE: /* Linux XSAVE extension */ - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_xstatereg (abfd, note); - else - return TRUE; - - case NT_PPC_VMX: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_ppc_vmx (abfd, note); - else - return TRUE; - - case NT_PPC_VSX: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_ppc_vsx (abfd, note); - else - return TRUE; - - case NT_S390_HIGH_GPRS: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_high_gprs (abfd, note); - else - return TRUE; - - case NT_S390_TIMER: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_timer (abfd, note); - else - return TRUE; - - case NT_S390_TODCMP: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_todcmp (abfd, note); - else - return TRUE; - - case NT_S390_TODPREG: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_todpreg (abfd, note); - else - return TRUE; - - case NT_S390_CTRS: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_ctrs (abfd, note); - else - return TRUE; - - case NT_S390_PREFIX: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_s390_prefix (abfd, note); - else - return TRUE; - - case NT_ARM_VFP: - if (note->namesz == 6 - && strcmp (note->namedata, "LINUX") == 0) - return elfcore_grok_arm_vfp (abfd, note); - else - return TRUE; - - case NT_PRPSINFO: - case NT_PSINFO: - if (bed->elf_backend_grok_psinfo) - if ((*bed->elf_backend_grok_psinfo) (abfd, note)) - return TRUE; -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) - return elfcore_grok_psinfo (abfd, note); -#else - return TRUE; -#endif - - case NT_AUXV: - { - asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv", - SEC_HAS_CONTENTS); - - if (sect == NULL) - return FALSE; - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; - - return TRUE; - } - } -} - -static bfd_boolean -elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note) -{ - elf_tdata (abfd)->build_id_size = note->descsz; - elf_tdata (abfd)->build_id = (bfd_byte *) bfd_alloc (abfd, note->descsz); - if (elf_tdata (abfd)->build_id == NULL) - return FALSE; - - memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz); - - return TRUE; -} - -static bfd_boolean -elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note) -{ - switch (note->type) - { - default: - return TRUE; - - case NT_GNU_BUILD_ID: - return elfobj_grok_gnu_build_id (abfd, note); - } -} - -static bfd_boolean -elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note) -{ - struct sdt_note *cur = - (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note) - + note->descsz); - - cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head; - cur->size = (bfd_size_type) note->descsz; - memcpy (cur->data, note->descdata, note->descsz); - - elf_tdata (abfd)->sdt_note_head = cur; - - return TRUE; -} - -static bfd_boolean -elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note) -{ - switch (note->type) - { - case NT_STAPSDT: - return elfobj_grok_stapsdt_note_1 (abfd, note); - - default: - return TRUE; - } -} - -static bfd_boolean -elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp) -{ - char *cp; - - cp = strchr (note->namedata, '@'); - if (cp != NULL) - { - *lwpidp = atoi(cp + 1); - return TRUE; - } - return FALSE; -} - -static bfd_boolean -elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) -{ - /* Signal number at offset 0x08. */ - elf_tdata (abfd)->core_signal - = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); - - /* Process ID at offset 0x50. */ - elf_tdata (abfd)->core_pid - = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50); - - /* Command name at 0x7c (max 32 bytes, including nul). */ - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31); - - return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo", - note); -} - -static bfd_boolean -elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) -{ - int lwp; - - if (elfcore_netbsd_get_lwpid (note, &lwp)) - elf_tdata (abfd)->core_lwpid = lwp; - - if (note->type == NT_NETBSDCORE_PROCINFO) - { - /* NetBSD-specific core "procinfo". Note that we expect to - find this note before any of the others, which is fine, - since the kernel writes this note out first when it - creates a core file. */ - - return elfcore_grok_netbsd_procinfo (abfd, note); - } - - /* As of Jan 2002 there are no other machine-independent notes - defined for NetBSD core files. If the note type is less - than the start of the machine-dependent note types, we don't - understand it. */ - - if (note->type < NT_NETBSDCORE_FIRSTMACH) - return TRUE; - - - switch (bfd_get_arch (abfd)) - { - /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and - PT_GETFPREGS == mach+2. */ - - case bfd_arch_alpha: - case bfd_arch_sparc: - switch (note->type) - { - case NT_NETBSDCORE_FIRSTMACH+0: - return elfcore_make_note_pseudosection (abfd, ".reg", note); - - case NT_NETBSDCORE_FIRSTMACH+2: - return elfcore_make_note_pseudosection (abfd, ".reg2", note); - - default: - return TRUE; - } - - /* On all other arch's, PT_GETREGS == mach+1 and - PT_GETFPREGS == mach+3. */ - - default: - switch (note->type) - { - case NT_NETBSDCORE_FIRSTMACH+1: - return elfcore_make_note_pseudosection (abfd, ".reg", note); - - case NT_NETBSDCORE_FIRSTMACH+3: - return elfcore_make_note_pseudosection (abfd, ".reg2", note); - - default: - return TRUE; - } - } - /* NOTREACHED */ -} - -static bfd_boolean -elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) -{ - /* Signal number at offset 0x08. */ - elf_tdata (abfd)->core_signal - = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); - - /* Process ID at offset 0x20. */ - elf_tdata (abfd)->core_pid - = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20); - - /* Command name at 0x48 (max 32 bytes, including nul). */ - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31); - - return TRUE; -} - -static bfd_boolean -elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note) -{ - if (note->type == NT_OPENBSD_PROCINFO) - return elfcore_grok_openbsd_procinfo (abfd, note); - - if (note->type == NT_OPENBSD_REGS) - return elfcore_make_note_pseudosection (abfd, ".reg", note); - - if (note->type == NT_OPENBSD_FPREGS) - return elfcore_make_note_pseudosection (abfd, ".reg2", note); - - if (note->type == NT_OPENBSD_XFPREGS) - return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note); - - if (note->type == NT_OPENBSD_AUXV) - { - asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv", - SEC_HAS_CONTENTS); - - if (sect == NULL) - return FALSE; - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; - - return TRUE; - } - - if (note->type == NT_OPENBSD_WCOOKIE) - { - asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie", - SEC_HAS_CONTENTS); - - if (sect == NULL) - return FALSE; - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32; - - return TRUE; - } - - return TRUE; -} - -static bfd_boolean -elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid) -{ - void *ddata = note->descdata; - char buf[100]; - char *name; - asection *sect; - short sig; - unsigned flags; - - /* nto_procfs_status 'pid' field is at offset 0. */ - elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata); - - /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ - *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); - - /* nto_procfs_status 'flags' field is at offset 8. */ - flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8); - - /* nto_procfs_status 'what' field is at offset 14. */ - if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) - { - elf_tdata (abfd)->core_signal = sig; - elf_tdata (abfd)->core_lwpid = *tid; - } - - /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores - do not come from signals so we make sure we set the current - thread just in case. */ - if (flags & 0x00000080) - elf_tdata (abfd)->core_lwpid = *tid; - - /* Make a ".qnx_core_status/%d" section. */ - sprintf (buf, ".qnx_core_status/%ld", *tid); - - name = (char *) bfd_alloc (abfd, strlen (buf) + 1); - if (name == NULL) - return FALSE; - strcpy (name, buf); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 2; - - return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect)); -} - -static bfd_boolean -elfcore_grok_nto_regs (bfd *abfd, - Elf_Internal_Note *note, - long tid, - char *base) -{ - char buf[100]; - char *name; - asection *sect; - - /* Make a "(base)/%d" section. */ - sprintf (buf, "%s/%ld", base, tid); - - name = (char *) bfd_alloc (abfd, strlen (buf) + 1); - if (name == NULL) - return FALSE; - strcpy (name, buf); - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 2; - - /* This is the current thread. */ - if (elf_tdata (abfd)->core_lwpid == tid) - return elfcore_maybe_make_sect (abfd, base, sect); - - return TRUE; -} - -#define BFD_QNT_CORE_INFO 7 -#define BFD_QNT_CORE_STATUS 8 -#define BFD_QNT_CORE_GREG 9 -#define BFD_QNT_CORE_FPREG 10 - -static bfd_boolean -elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note) -{ - /* Every GREG section has a STATUS section before it. Store the - tid from the previous call to pass down to the next gregs - function. */ - static long tid = 1; - - switch (note->type) - { - case BFD_QNT_CORE_INFO: - return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note); - case BFD_QNT_CORE_STATUS: - return elfcore_grok_nto_status (abfd, note, &tid); - case BFD_QNT_CORE_GREG: - return elfcore_grok_nto_regs (abfd, note, tid, ".reg"); - case BFD_QNT_CORE_FPREG: - return elfcore_grok_nto_regs (abfd, note, tid, ".reg2"); - default: - return TRUE; - } -} - -static bfd_boolean -elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note) -{ - char *name; - asection *sect; - size_t len; - - /* Use note name as section name. */ - len = note->namesz; - name = (char *) bfd_alloc (abfd, len); - if (name == NULL) - return FALSE; - memcpy (name, note->namedata, len); - name[len - 1] = '\0'; - - sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); - if (sect == NULL) - return FALSE; - - sect->size = note->descsz; - sect->filepos = note->descpos; - sect->alignment_power = 1; - - return TRUE; -} - -/* Function: elfcore_write_note - - Inputs: - buffer to hold note, and current size of buffer - name of note - type of note - data for note - size of data for note - - Writes note to end of buffer. ELF64 notes are written exactly as - for ELF32, despite the current (as of 2006) ELF gabi specifying - that they ought to have 8-byte namesz and descsz field, and have - 8-byte alignment. Other writers, eg. Linux kernel, do the same. - - Return: - Pointer to realloc'd buffer, *BUFSIZ updated. */ - -char * -elfcore_write_note (bfd *abfd, - char *buf, - int *bufsiz, - const char *name, - int type, - const void *input, - int size) -{ - Elf_External_Note *xnp; - size_t namesz; - size_t newspace; - char *dest; - - namesz = 0; - if (name != NULL) - namesz = strlen (name) + 1; - - newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4); - - buf = (char *) realloc (buf, *bufsiz + newspace); - if (buf == NULL) - return buf; - dest = buf + *bufsiz; - *bufsiz += newspace; - xnp = (Elf_External_Note *) dest; - H_PUT_32 (abfd, namesz, xnp->namesz); - H_PUT_32 (abfd, size, xnp->descsz); - H_PUT_32 (abfd, type, xnp->type); - dest = xnp->name; - if (name != NULL) - { - memcpy (dest, name, namesz); - dest += namesz; - while (namesz & 3) - { - *dest++ = '\0'; - ++namesz; - } - } - memcpy (dest, input, size); - dest += size; - while (size & 3) - { - *dest++ = '\0'; - ++size; - } - return buf; -} - -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) -char * -elfcore_write_prpsinfo (bfd *abfd, - char *buf, - int *bufsiz, - const char *fname, - const char *psargs) -{ - const char *note_name = "CORE"; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_write_core_note != NULL) - { - char *ret; - ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, - NT_PRPSINFO, fname, psargs); - if (ret != NULL) - return ret; - } - -#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) - if (bed->s->elfclass == ELFCLASS32) - { -#if defined (HAVE_PSINFO32_T) - psinfo32_t data; - int note_type = NT_PSINFO; -#else - prpsinfo32_t data; - int note_type = NT_PRPSINFO; -#endif - - memset (&data, 0, sizeof (data)); - strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); - strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); - return elfcore_write_note (abfd, buf, bufsiz, - note_name, note_type, &data, sizeof (data)); - } - else -#endif - { -#if defined (HAVE_PSINFO_T) - psinfo_t data; - int note_type = NT_PSINFO; -#else - prpsinfo_t data; - int note_type = NT_PRPSINFO; -#endif - - memset (&data, 0, sizeof (data)); - strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); - strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); - return elfcore_write_note (abfd, buf, bufsiz, - note_name, note_type, &data, sizeof (data)); - } -} -#endif /* PSINFO_T or PRPSINFO_T */ - -#if defined (HAVE_PRSTATUS_T) -char * -elfcore_write_prstatus (bfd *abfd, - char *buf, - int *bufsiz, - long pid, - int cursig, - const void *gregs) -{ - const char *note_name = "CORE"; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_write_core_note != NULL) - { - char *ret; - ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, - NT_PRSTATUS, - pid, cursig, gregs); - if (ret != NULL) - return ret; - } - -#if defined (HAVE_PRSTATUS32_T) - if (bed->s->elfclass == ELFCLASS32) - { - prstatus32_t prstat; - - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - return elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_PRSTATUS, &prstat, sizeof (prstat)); - } - else -#endif - { - prstatus_t prstat; - - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - return elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_PRSTATUS, &prstat, sizeof (prstat)); - } -} -#endif /* HAVE_PRSTATUS_T */ - -#if defined (HAVE_LWPSTATUS_T) -char * -elfcore_write_lwpstatus (bfd *abfd, - char *buf, - int *bufsiz, - long pid, - int cursig, - const void *gregs) -{ - lwpstatus_t lwpstat; - const char *note_name = "CORE"; - - memset (&lwpstat, 0, sizeof (lwpstat)); - lwpstat.pr_lwpid = pid >> 16; - lwpstat.pr_cursig = cursig; -#if defined (HAVE_LWPSTATUS_T_PR_REG) - memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg)); -#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT) -#if !defined(gregs) - memcpy (lwpstat.pr_context.uc_mcontext.gregs, - gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs)); -#else - memcpy (lwpstat.pr_context.uc_mcontext.__gregs, - gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs)); -#endif -#endif - return elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_LWPSTATUS, &lwpstat, sizeof (lwpstat)); -} -#endif /* HAVE_LWPSTATUS_T */ - -#if defined (HAVE_PSTATUS_T) -char * -elfcore_write_pstatus (bfd *abfd, - char *buf, - int *bufsiz, - long pid, - int cursig ATTRIBUTE_UNUSED, - const void *gregs ATTRIBUTE_UNUSED) -{ - const char *note_name = "CORE"; -#if defined (HAVE_PSTATUS32_T) - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->s->elfclass == ELFCLASS32) - { - pstatus32_t pstat; - - memset (&pstat, 0, sizeof (pstat)); - pstat.pr_pid = pid & 0xffff; - buf = elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_PSTATUS, &pstat, sizeof (pstat)); - return buf; - } - else -#endif - { - pstatus_t pstat; - - memset (&pstat, 0, sizeof (pstat)); - pstat.pr_pid = pid & 0xffff; - buf = elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_PSTATUS, &pstat, sizeof (pstat)); - return buf; - } -} -#endif /* HAVE_PSTATUS_T */ - -char * -elfcore_write_prfpreg (bfd *abfd, - char *buf, - int *bufsiz, - const void *fpregs, - int size) -{ - const char *note_name = "CORE"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_FPREGSET, fpregs, size); -} - -char * -elfcore_write_prxfpreg (bfd *abfd, - char *buf, - int *bufsiz, - const void *xfpregs, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_PRXFPREG, xfpregs, size); -} - -char * -elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz, - const void *xfpregs, int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_X86_XSTATE, xfpregs, size); -} - -char * -elfcore_write_ppc_vmx (bfd *abfd, - char *buf, - int *bufsiz, - const void *ppc_vmx, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_PPC_VMX, ppc_vmx, size); -} - -char * -elfcore_write_ppc_vsx (bfd *abfd, - char *buf, - int *bufsiz, - const void *ppc_vsx, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_PPC_VSX, ppc_vsx, size); -} - -static char * -elfcore_write_s390_high_gprs (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_high_gprs, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_HIGH_GPRS, - s390_high_gprs, size); -} - -char * -elfcore_write_s390_timer (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_timer, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_TIMER, s390_timer, size); -} - -char * -elfcore_write_s390_todcmp (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_todcmp, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_TODCMP, s390_todcmp, size); -} - -char * -elfcore_write_s390_todpreg (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_todpreg, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_TODPREG, s390_todpreg, size); -} - -char * -elfcore_write_s390_ctrs (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_ctrs, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_CTRS, s390_ctrs, size); -} - -char * -elfcore_write_s390_prefix (bfd *abfd, - char *buf, - int *bufsiz, - const void *s390_prefix, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_S390_PREFIX, s390_prefix, size); -} - -char * -elfcore_write_arm_vfp (bfd *abfd, - char *buf, - int *bufsiz, - const void *arm_vfp, - int size) -{ - char *note_name = "LINUX"; - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_ARM_VFP, arm_vfp, size); -} - -char * -elfcore_write_register_note (bfd *abfd, - char *buf, - int *bufsiz, - const char *section, - const void *data, - int size) -{ - if (strcmp (section, ".reg2") == 0) - return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-xfp") == 0) - return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-xstate") == 0) - return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-ppc-vmx") == 0) - return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-ppc-vsx") == 0) - return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-high-gprs") == 0) - return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-timer") == 0) - return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-todcmp") == 0) - return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-todpreg") == 0) - return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-ctrs") == 0) - return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-s390-prefix") == 0) - return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size); - if (strcmp (section, ".reg-arm-vfp") == 0) - return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size); - return NULL; -} - -static bfd_boolean -elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset) -{ - char *p; - - p = buf; - while (p < buf + size) - { - /* FIXME: bad alignment assumption. */ - Elf_External_Note *xnp = (Elf_External_Note *) p; - Elf_Internal_Note in; - - if (offsetof (Elf_External_Note, name) > buf - p + size) - return FALSE; - - in.type = H_GET_32 (abfd, xnp->type); - - in.namesz = H_GET_32 (abfd, xnp->namesz); - in.namedata = xnp->name; - if (in.namesz > buf - in.namedata + size) - return FALSE; - - in.descsz = H_GET_32 (abfd, xnp->descsz); - in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4); - in.descpos = offset + (in.descdata - buf); - if (in.descsz != 0 - && (in.descdata >= buf + size - || in.descsz > buf - in.descdata + size)) - return FALSE; - - switch (bfd_get_format (abfd)) - { - default: - return TRUE; - - case bfd_core: - if (CONST_STRNEQ (in.namedata, "NetBSD-CORE")) - { - if (! elfcore_grok_netbsd_note (abfd, &in)) - return FALSE; - } - else if (CONST_STRNEQ (in.namedata, "OpenBSD")) - { - if (! elfcore_grok_openbsd_note (abfd, &in)) - return FALSE; - } - else if (CONST_STRNEQ (in.namedata, "QNX")) - { - if (! elfcore_grok_nto_note (abfd, &in)) - return FALSE; - } - else if (CONST_STRNEQ (in.namedata, "SPU/")) - { - if (! elfcore_grok_spu_note (abfd, &in)) - return FALSE; - } - else - { - if (! elfcore_grok_note (abfd, &in)) - return FALSE; - } - break; - - case bfd_object: - if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0) - { - if (! elfobj_grok_gnu_note (abfd, &in)) - return FALSE; - } - else if (in.namesz == sizeof "stapsdt" - && strcmp (in.namedata, "stapsdt") == 0) - { - if (! elfobj_grok_stapsdt_note (abfd, &in)) - return FALSE; - } - break; - } - - p = in.descdata + BFD_ALIGN (in.descsz, 4); - } - - return TRUE; -} - -static bfd_boolean -elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size) -{ - char *buf; - - if (size <= 0) - return TRUE; - - if (bfd_seek (abfd, offset, SEEK_SET) != 0) - return FALSE; - - buf = (char *) bfd_malloc (size); - if (buf == NULL) - return FALSE; - - if (bfd_bread (buf, size, abfd) != size - || !elf_parse_notes (abfd, buf, size, offset)) - { - free (buf); - return FALSE; - } - - free (buf); - return TRUE; -} - -/* Providing external access to the ELF program header table. */ - -/* Return an upper bound on the number of bytes required to store a - copy of ABFD's program header table entries. Return -1 if an error - occurs; bfd_get_error will return an appropriate code. */ - -long -bfd_get_elf_phdr_upper_bound (bfd *abfd) -{ - if (abfd->xvec->flavour != bfd_target_elf_flavour) - { - bfd_set_error (bfd_error_wrong_format); - return -1; - } - - return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr); -} - -/* Copy ABFD's program header table entries to *PHDRS. The entries - will be stored as an array of Elf_Internal_Phdr structures, as - defined in include/elf/internal.h. To find out how large the - buffer needs to be, call bfd_get_elf_phdr_upper_bound. - - Return the number of program header table entries read, or -1 if an - error occurs; bfd_get_error will return an appropriate code. */ - -int -bfd_get_elf_phdrs (bfd *abfd, void *phdrs) -{ - int num_phdrs; - - if (abfd->xvec->flavour != bfd_target_elf_flavour) - { - bfd_set_error (bfd_error_wrong_format); - return -1; - } - - num_phdrs = elf_elfheader (abfd)->e_phnum; - memcpy (phdrs, elf_tdata (abfd)->phdr, - num_phdrs * sizeof (Elf_Internal_Phdr)); - - return num_phdrs; -} - -enum elf_reloc_type_class -_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) -{ - return reloc_class_normal; -} - -/* For RELA architectures, return the relocation value for a - relocation against a local symbol. */ - -bfd_vma -_bfd_elf_rela_local_sym (bfd *abfd, - Elf_Internal_Sym *sym, - asection **psec, - Elf_Internal_Rela *rel) -{ - asection *sec = *psec; - bfd_vma relocation; - - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - if ((sec->flags & SEC_MERGE) - && ELF_ST_TYPE (sym->st_info) == STT_SECTION - && sec->sec_info_type == ELF_INFO_TYPE_MERGE) - { - rel->r_addend = - _bfd_merged_section_offset (abfd, psec, - elf_section_data (sec)->sec_info, - sym->st_value + rel->r_addend); - if (sec != *psec) - { - /* If we have changed the section, and our original section is - marked with SEC_EXCLUDE, it means that the original - SEC_MERGE section has been completely subsumed in some - other SEC_MERGE section. In this case, we need to leave - some info around for --emit-relocs. */ - if ((sec->flags & SEC_EXCLUDE) != 0) - sec->kept_section = *psec; - sec = *psec; - } - rel->r_addend -= relocation; - rel->r_addend += sec->output_section->vma + sec->output_offset; - } - return relocation; -} - -bfd_vma -_bfd_elf_rel_local_sym (bfd *abfd, - Elf_Internal_Sym *sym, - asection **psec, - bfd_vma addend) -{ - asection *sec = *psec; - - if (sec->sec_info_type != ELF_INFO_TYPE_MERGE) - return sym->st_value + addend; - - return _bfd_merged_section_offset (abfd, psec, - elf_section_data (sec)->sec_info, - sym->st_value + addend); -} - -bfd_vma -_bfd_elf_section_offset (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - bfd_vma offset) -{ - switch (sec->sec_info_type) - { - case ELF_INFO_TYPE_STABS: - return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info, - offset); - case ELF_INFO_TYPE_EH_FRAME: - return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset); - default: - if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_size_type address_size = bed->s->arch_size / 8; - offset = sec->size - offset - address_size; - } - return offset; - } -} - -/* Create a new BFD as if by bfd_openr. Rather than opening a file, - reconstruct an ELF file by reading the segments out of remote memory - based on the ELF file header at EHDR_VMA and the ELF program headers it - points to. If not null, *LOADBASEP is filled in with the difference - between the VMAs from which the segments were read, and the VMAs the - file headers (and hence BFD's idea of each section's VMA) put them at. - - The function TARGET_READ_MEMORY is called to copy LEN bytes from the - remote memory at target address VMA into the local buffer at MYADDR; it - should return zero on success or an `errno' code on failure. TEMPL must - be a BFD for an ELF target with the word size and byte order found in - the remote memory. */ - -bfd * -bfd_elf_bfd_from_remote_memory - (bfd *templ, - bfd_vma ehdr_vma, - bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma, bfd_byte *, int)) -{ - return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory) - (templ, ehdr_vma, loadbasep, target_read_memory); -} - -long -_bfd_elf_get_synthetic_symtab (bfd *abfd, - long symcount ATTRIBUTE_UNUSED, - asymbol **syms ATTRIBUTE_UNUSED, - long dynsymcount, - asymbol **dynsyms, - asymbol **ret) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - asection *relplt; - asymbol *s; - const char *relplt_name; - bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); - arelent *p; - long count, i, n; - size_t size; - Elf_Internal_Shdr *hdr; - char *names; - asection *plt; - - *ret = NULL; - - if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0) - return 0; - - if (dynsymcount <= 0) - return 0; - - if (!bed->plt_sym_val) - return 0; - - relplt_name = bed->relplt_name; - if (relplt_name == NULL) - relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt"; - relplt = bfd_get_section_by_name (abfd, relplt_name); - if (relplt == NULL) - return 0; - - hdr = &elf_section_data (relplt)->this_hdr; - if (hdr->sh_link != elf_dynsymtab (abfd) - || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA)) - return 0; - - plt = bfd_get_section_by_name (abfd, ".plt"); - if (plt == NULL) - return 0; - - slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; - if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE)) - return -1; - - count = relplt->size / hdr->sh_entsize; - size = count * sizeof (asymbol); - p = relplt->relocation; - for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel) - { - size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt"); - if (p->addend != 0) - { -#ifdef BFD64 - size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64); -#else - size += sizeof ("+0x") - 1 + 8; -#endif - } - } - - s = *ret = (asymbol *) bfd_malloc (size); - if (s == NULL) - return -1; - - names = (char *) (s + count); - p = relplt->relocation; - n = 0; - for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel) - { - size_t len; - bfd_vma addr; - - addr = bed->plt_sym_val (i, plt, p); - if (addr == (bfd_vma) -1) - continue; - - *s = **p->sym_ptr_ptr; - /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since - we are defining a symbol, ensure one of them is set. */ - if ((s->flags & BSF_LOCAL) == 0) - s->flags |= BSF_GLOBAL; - s->flags |= BSF_SYNTHETIC; - s->section = plt; - s->value = addr - plt->vma; - s->name = names; - s->udata.p = NULL; - len = strlen ((*p->sym_ptr_ptr)->name); - memcpy (names, (*p->sym_ptr_ptr)->name, len); - names += len; - if (p->addend != 0) - { - char buf[30], *a; - - memcpy (names, "+0x", sizeof ("+0x") - 1); - names += sizeof ("+0x") - 1; - bfd_sprintf_vma (abfd, buf, p->addend); - for (a = buf; *a == '0'; ++a) - ; - len = strlen (a); - memcpy (names, a, len); - names += len; - } - memcpy (names, "@plt", sizeof ("@plt")); - names += sizeof ("@plt"); - ++s, ++n; - } - - return n; -} - -/* It is only used by x86-64 so far. */ -asection _bfd_elf_large_com_section - = BFD_FAKE_SECTION (_bfd_elf_large_com_section, - SEC_IS_COMMON, NULL, "LARGE_COMMON", 0); - -void -_bfd_elf_set_osabi (bfd * abfd, - struct bfd_link_info * link_info ATTRIBUTE_UNUSED) -{ - Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ - - i_ehdrp = elf_elfheader (abfd); - - i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; - - /* To make things simpler for the loader on Linux systems we set the - osabi field to ELFOSABI_GNU if the binary contains symbols of - the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */ - if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE - && elf_tdata (abfd)->has_gnu_symbols) - i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU; -} - - -/* Return TRUE for ELF symbol types that represent functions. - This is the default version of this function, which is sufficient for - most targets. It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC. */ - -bfd_boolean -_bfd_elf_is_function_type (unsigned int type) -{ - return (type == STT_FUNC - || type == STT_GNU_IFUNC); -} diff --git a/contrib/binutils-2.22/bfd/elf32-gen.c b/contrib/binutils-2.22/bfd/elf32-gen.c deleted file mode 100644 index 32814290db..0000000000 --- a/contrib/binutils-2.22/bfd/elf32-gen.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Generic support for 32-bit ELF - Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2004, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocation information, but should be - good enough for GDB or objdump to read the file. */ - -static reloc_howto_type dummy = - HOWTO (0, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "UNKNOWN", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE); /* pcrel_offset */ - -static void -elf_generic_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, - arelent *bfd_reloc, - Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED) -{ - bfd_reloc->howto = &dummy; -} - -static void -elf_generic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, - arelent *bfd_reloc, - Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED) -{ - bfd_reloc->howto = &dummy; -} - -static void -check_for_relocs (bfd * abfd, asection * o, void * failed) -{ - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Ehdr *ehdrp; - - ehdrp = elf_elfheader (abfd); - _bfd_error_handler (_("%B: Relocations in generic ELF (EM: %d)"), - abfd, ehdrp->e_machine); - - bfd_set_error (bfd_error_wrong_format); - * (bfd_boolean *) failed = TRUE; - } -} - -static bfd_boolean -elf32_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean failed = FALSE; - - /* Check if there are any relocations. */ - bfd_map_over_sections (abfd, check_for_relocs, & failed); - - if (failed) - return FALSE; - return bfd_elf_link_add_symbols (abfd, info); -} - -#define TARGET_LITTLE_SYM bfd_elf32_little_generic_vec -#define TARGET_LITTLE_NAME "elf32-little" -#define TARGET_BIG_SYM bfd_elf32_big_generic_vec -#define TARGET_BIG_NAME "elf32-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define ELF_MAXPAGESIZE 0x1 -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define bfd_elf32_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup -#define bfd_elf32_bfd_link_add_symbols elf32_generic_link_add_symbols -#define elf_info_to_howto elf_generic_info_to_howto -#define elf_info_to_howto_rel elf_generic_info_to_howto_rel - -#include "elf32-target.h" diff --git a/contrib/binutils-2.22/bfd/elf32-i386.c b/contrib/binutils-2.22/bfd/elf32-i386.c deleted file mode 100644 index d518d01477..0000000000 --- a/contrib/binutils-2.22/bfd/elf32-i386.c +++ /dev/null @@ -1,5233 +0,0 @@ -/* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf-vxworks.h" -#include "bfd_stdint.h" -#include "objalloc.h" -#include "hashtab.h" -#include "dwarf2.h" - -/* 386 uses REL relocations instead of RELA. */ -#define USE_REL 1 - -#include "elf/i386.h" - -static reloc_howto_type elf_howto_table[]= -{ - HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_NONE", - TRUE, 0x00000000, 0x00000000, FALSE), - HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_PC32", - TRUE, 0xffffffff, 0xffffffff, TRUE), - HOWTO(R_386_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_GOT32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_PLT32", - TRUE, 0xffffffff, 0xffffffff, TRUE), - HOWTO(R_386_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_COPY", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_GLOB_DAT", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_JUMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_JUMP_SLOT", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_RELATIVE", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_GOTOFF", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_GOTPC", - TRUE, 0xffffffff, 0xffffffff, TRUE), - - /* We have a gap in the reloc numbers here. - R_386_standard counts the number up to this point, and - R_386_ext_offset is the value to subtract from a reloc type of - R_386_16 thru R_386_PC8 to form an index into this table. */ -#define R_386_standard (R_386_GOTPC + 1) -#define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard) - - /* These relocs are a GNU extension. */ - HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_TPOFF", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_IE", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_GOTIE", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_LE", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_GD", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_LDM", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_16", - TRUE, 0xffff, 0xffff, FALSE), - HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_PC16", - TRUE, 0xffff, 0xffff, TRUE), - HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_8", - TRUE, 0xff, 0xff, FALSE), - HOWTO(R_386_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_386_PC8", - TRUE, 0xff, 0xff, TRUE), - -#define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset) -#define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext) - /* These are common with Solaris TLS implementation. */ - HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_LDO_32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_IE_32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_LE_32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_TPOFF32", - TRUE, 0xffffffff, 0xffffffff, FALSE), - EMPTY_HOWTO (38), - HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_GOTDESC", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL", - FALSE, 0, 0, FALSE), - HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_TLS_DESC", - TRUE, 0xffffffff, 0xffffffff, FALSE), - HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_386_IRELATIVE", - TRUE, 0xffffffff, 0xffffffff, FALSE), - - /* Another gap. */ -#define R_386_irelative (R_386_IRELATIVE + 1 - R_386_tls_offset) -#define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_irelative) - -/* GNU extension to record C++ vtable hierarchy. */ - HOWTO (R_386_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_386_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - -/* GNU extension to record C++ vtable member usage. */ - HOWTO (R_386_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_386_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE) /* pcrel_offset */ - -#define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset) - -}; - -#ifdef DEBUG_GEN_RELOC -#define TRACE(str) \ - fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) -#else -#define TRACE(str) -#endif - -static reloc_howto_type * -elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, - bfd_reloc_code_real_type code) -{ - switch (code) - { - case BFD_RELOC_NONE: - TRACE ("BFD_RELOC_NONE"); - return &elf_howto_table[R_386_NONE]; - - case BFD_RELOC_32: - TRACE ("BFD_RELOC_32"); - return &elf_howto_table[R_386_32]; - - case BFD_RELOC_CTOR: - TRACE ("BFD_RELOC_CTOR"); - return &elf_howto_table[R_386_32]; - - case BFD_RELOC_32_PCREL: - TRACE ("BFD_RELOC_PC32"); - return &elf_howto_table[R_386_PC32]; - - case BFD_RELOC_386_GOT32: - TRACE ("BFD_RELOC_386_GOT32"); - return &elf_howto_table[R_386_GOT32]; - - case BFD_RELOC_386_PLT32: - TRACE ("BFD_RELOC_386_PLT32"); - return &elf_howto_table[R_386_PLT32]; - - case BFD_RELOC_386_COPY: - TRACE ("BFD_RELOC_386_COPY"); - return &elf_howto_table[R_386_COPY]; - - case BFD_RELOC_386_GLOB_DAT: - TRACE ("BFD_RELOC_386_GLOB_DAT"); - return &elf_howto_table[R_386_GLOB_DAT]; - - case BFD_RELOC_386_JUMP_SLOT: - TRACE ("BFD_RELOC_386_JUMP_SLOT"); - return &elf_howto_table[R_386_JUMP_SLOT]; - - case BFD_RELOC_386_RELATIVE: - TRACE ("BFD_RELOC_386_RELATIVE"); - return &elf_howto_table[R_386_RELATIVE]; - - case BFD_RELOC_386_GOTOFF: - TRACE ("BFD_RELOC_386_GOTOFF"); - return &elf_howto_table[R_386_GOTOFF]; - - case BFD_RELOC_386_GOTPC: - TRACE ("BFD_RELOC_386_GOTPC"); - return &elf_howto_table[R_386_GOTPC]; - - /* These relocs are a GNU extension. */ - case BFD_RELOC_386_TLS_TPOFF: - TRACE ("BFD_RELOC_386_TLS_TPOFF"); - return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset]; - - case BFD_RELOC_386_TLS_IE: - TRACE ("BFD_RELOC_386_TLS_IE"); - return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset]; - - case BFD_RELOC_386_TLS_GOTIE: - TRACE ("BFD_RELOC_386_TLS_GOTIE"); - return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset]; - - case BFD_RELOC_386_TLS_LE: - TRACE ("BFD_RELOC_386_TLS_LE"); - return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset]; - - case BFD_RELOC_386_TLS_GD: - TRACE ("BFD_RELOC_386_TLS_GD"); - return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset]; - - case BFD_RELOC_386_TLS_LDM: - TRACE ("BFD_RELOC_386_TLS_LDM"); - return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset]; - - case BFD_RELOC_16: - TRACE ("BFD_RELOC_16"); - return &elf_howto_table[R_386_16 - R_386_ext_offset]; - - case BFD_RELOC_16_PCREL: - TRACE ("BFD_RELOC_16_PCREL"); - return &elf_howto_table[R_386_PC16 - R_386_ext_offset]; - - case BFD_RELOC_8: - TRACE ("BFD_RELOC_8"); - return &elf_howto_table[R_386_8 - R_386_ext_offset]; - - case BFD_RELOC_8_PCREL: - TRACE ("BFD_RELOC_8_PCREL"); - return &elf_howto_table[R_386_PC8 - R_386_ext_offset]; - - /* Common with Sun TLS implementation. */ - case BFD_RELOC_386_TLS_LDO_32: - TRACE ("BFD_RELOC_386_TLS_LDO_32"); - return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_IE_32: - TRACE ("BFD_RELOC_386_TLS_IE_32"); - return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_LE_32: - TRACE ("BFD_RELOC_386_TLS_LE_32"); - return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_DTPMOD32: - TRACE ("BFD_RELOC_386_TLS_DTPMOD32"); - return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_DTPOFF32: - TRACE ("BFD_RELOC_386_TLS_DTPOFF32"); - return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_TPOFF32: - TRACE ("BFD_RELOC_386_TLS_TPOFF32"); - return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_GOTDESC: - TRACE ("BFD_RELOC_386_TLS_GOTDESC"); - return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_DESC_CALL: - TRACE ("BFD_RELOC_386_TLS_DESC_CALL"); - return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset]; - - case BFD_RELOC_386_TLS_DESC: - TRACE ("BFD_RELOC_386_TLS_DESC"); - return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset]; - - case BFD_RELOC_386_IRELATIVE: - TRACE ("BFD_RELOC_386_IRELATIVE"); - return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset]; - - case BFD_RELOC_VTABLE_INHERIT: - TRACE ("BFD_RELOC_VTABLE_INHERIT"); - return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset]; - - case BFD_RELOC_VTABLE_ENTRY: - TRACE ("BFD_RELOC_VTABLE_ENTRY"); - return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset]; - - default: - break; - } - - TRACE ("Unknown"); - return 0; -} - -static reloc_howto_type * -elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, - const char *r_name) -{ - unsigned int i; - - for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++) - if (elf_howto_table[i].name != NULL - && strcasecmp (elf_howto_table[i].name, r_name) == 0) - return &elf_howto_table[i]; - - return NULL; -} - -static reloc_howto_type * -elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type) -{ - unsigned int indx; - - if ((indx = r_type) >= R_386_standard - && ((indx = r_type - R_386_ext_offset) - R_386_standard - >= R_386_ext - R_386_standard) - && ((indx = r_type - R_386_tls_offset) - R_386_ext - >= R_386_irelative - R_386_ext) - && ((indx = r_type - R_386_vt_offset) - R_386_irelative - >= R_386_vt - R_386_irelative)) - { - (*_bfd_error_handler) (_("%B: invalid relocation type %d"), - abfd, (int) r_type); - indx = R_386_NONE; - } - BFD_ASSERT (elf_howto_table [indx].type == r_type); - return &elf_howto_table[indx]; -} - -static void -elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, - arelent *cache_ptr, - Elf_Internal_Rela *dst) -{ - unsigned int r_type = ELF32_R_TYPE (dst->r_info); - cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_type); -} - -/* Return whether a symbol name implies a local label. The UnixWare - 2.1 cc generates temporary symbols that start with .X, so we - recognize them here. FIXME: do other SVR4 compilers also use .X?. - If so, we should move the .X recognition into - _bfd_elf_is_local_label_name. */ - -static bfd_boolean -elf_i386_is_local_label_name (bfd *abfd, const char *name) -{ - if (name[0] == '.' && name[1] == 'X') - return TRUE; - - return _bfd_elf_is_local_label_name (abfd, name); -} - -/* Support for core dump NOTE sections. */ - -static bfd_boolean -elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) -{ - int offset; - size_t size; - - if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0) - { - int pr_version = bfd_get_32 (abfd, note->descdata); - - if (pr_version != 1) - return FALSE; - - /* pr_cursig */ - elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 20); - - /* pr_pid */ - elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24); - - /* pr_reg */ - offset = 28; - size = bfd_get_32 (abfd, note->descdata + 8); - } - else - { - switch (note->descsz) - { - default: - return FALSE; - - case 144: /* Linux/i386 */ - /* pr_cursig */ - elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); - - /* pr_pid */ - elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24); - - /* pr_reg */ - offset = 72; - size = 68; - - break; - } - } - - /* Make a ".reg/999" section. */ - return _bfd_elfcore_make_pseudosection (abfd, ".reg", - size, note->descpos + offset); -} - -static bfd_boolean -elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) -{ - if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0) - { - int pr_version = bfd_get_32 (abfd, note->descdata); - - if (pr_version != 1) - return FALSE; - - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, note->descdata + 8, 17); - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 25, 81); - } - else - { - switch (note->descsz) - { - default: - return FALSE; - - case 124: /* Linux/i386 elf_prpsinfo. */ - elf_tdata (abfd)->core_pid - = bfd_get_32 (abfd, note->descdata + 12); - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); - } - } - - /* Note that for some reason, a spurious space is tacked - onto the end of the args in some (at least one anyway) - implementations, so strip it off if it exists. */ - { - char *command = elf_tdata (abfd)->core_command; - int n = strlen (command); - - if (0 < n && command[n - 1] == ' ') - command[n - 1] = '\0'; - } - - return TRUE; -} - -/* Functions for the i386 ELF linker. - - In order to gain some understanding of code in this file without - knowing all the intricate details of the linker, note the - following: - - Functions named elf_i386_* are called by external routines, other - functions are only called locally. elf_i386_* functions appear - in this file more or less in the order in which they are called - from external routines. eg. elf_i386_check_relocs is called - early in the link process, elf_i386_finish_dynamic_sections is - one of the last functions. */ - - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid - copying dynamic variables from a shared lib into an app's dynbss - section, and instead use a dynamic relocation to point into the - shared lib. */ -#define ELIMINATE_COPY_RELOCS 1 - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 16 - -/* The first entry in an absolute procedure linkage table looks like - this. See the SVR4 ABI i386 supplement to see how this works. - Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte. */ - -static const bfd_byte elf_i386_plt0_entry[12] = -{ - 0xff, 0x35, /* pushl contents of address */ - 0, 0, 0, 0, /* replaced with address of .got + 4. */ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0 /* replaced with address of .got + 8. */ -}; - -/* Subsequent entries in an absolute procedure linkage table look like - this. */ - -static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* The first entry in a PIC procedure linkage table look like this. - Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte. */ - -static const bfd_byte elf_i386_pic_plt0_entry[12] = -{ - 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */ - 0xff, 0xa3, 8, 0, 0, 0 /* jmp *8(%ebx) */ -}; - -/* Subsequent entries in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0xa3, /* jmp *offset(%ebx) */ - 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* .eh_frame covering the .plt section. */ - -static const bfd_byte elf_i386_eh_frame_plt[] = -{ -#define PLT_CIE_LENGTH 20 -#define PLT_FDE_LENGTH 36 -#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 -#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12 - PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ - 0, 0, 0, 0, /* CIE ID */ - 1, /* CIE version */ - 'z', 'R', 0, /* Augmentation string */ - 1, /* Code alignment factor */ - 0x7c, /* Data alignment factor */ - 8, /* Return address column */ - 1, /* Augmentation size */ - DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ - DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */ - DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */ - DW_CFA_nop, DW_CFA_nop, - - PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ - PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ - 0, 0, 0, 0, /* R_386_PC32 .plt goes here */ - 0, 0, 0, 0, /* .plt size goes here */ - 0, /* Augmentation size */ - DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */ - DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ - DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */ - DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ - DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ - 11, /* Block length */ - DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */ - DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */ - DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge, - DW_OP_lit2, DW_OP_shl, DW_OP_plus, - DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop -}; - -struct elf_i386_plt_layout -{ - /* The first entry in an absolute procedure linkage table looks like this. */ - const bfd_byte *plt0_entry; - unsigned int plt0_entry_size; - - /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2]. */ - unsigned int plt0_got1_offset; - unsigned int plt0_got2_offset; - - /* Later entries in an absolute procedure linkage table look like this. */ - const bfd_byte *plt_entry; - unsigned int plt_entry_size; - - /* Offsets into plt_entry that are to be replaced with... */ - unsigned int plt_got_offset; /* ... address of this symbol in .got. */ - unsigned int plt_reloc_offset; /* ... offset into relocation table. */ - unsigned int plt_plt_offset; /* ... offset to start of .plt. */ - - /* Offset into plt_entry where the initial value of the GOT entry points. */ - unsigned int plt_lazy_offset; - - /* The first entry in a PIC procedure linkage table looks like this. */ - const bfd_byte *pic_plt0_entry; - - /* Subsequent entries in a PIC procedure linkage table look like this. */ - const bfd_byte *pic_plt_entry; - - /* .eh_frame covering the .plt section. */ - const bfd_byte *eh_frame_plt; - unsigned int eh_frame_plt_size; -}; - -#define GET_PLT_ENTRY_SIZE(abfd) \ - get_elf_i386_backend_data (abfd)->plt->plt_entry_size - -/* These are the standard parameters. */ -static const struct elf_i386_plt_layout elf_i386_plt = - { - elf_i386_plt0_entry, /* plt0_entry */ - sizeof (elf_i386_plt0_entry), /* plt0_entry_size */ - 2, /* plt0_got1_offset */ - 8, /* plt0_got2_offset */ - elf_i386_plt_entry, /* plt_entry */ - PLT_ENTRY_SIZE, /* plt_entry_size */ - 2, /* plt_got_offset */ - 7, /* plt_reloc_offset */ - 12, /* plt_plt_offset */ - 6, /* plt_lazy_offset */ - elf_i386_pic_plt0_entry, /* pic_plt0_entry */ - elf_i386_pic_plt_entry, /* pic_plt_entry */ - elf_i386_eh_frame_plt, /* eh_frame_plt */ - sizeof (elf_i386_eh_frame_plt), /* eh_frame_plt_size */ - }; - - -/* On VxWorks, the .rel.plt.unloaded section has absolute relocations - for the PLTResolve stub and then for each PLT entry. */ -#define PLTRESOLVE_RELOCS_SHLIB 0 -#define PLTRESOLVE_RELOCS 2 -#define PLT_NON_JUMP_SLOT_RELOCS 2 - -/* Architecture-specific backend data for i386. */ - -struct elf_i386_backend_data -{ - /* Parameters describing PLT generation. */ - const struct elf_i386_plt_layout *plt; - - /* Value used to fill the unused bytes of the first PLT entry. */ - bfd_byte plt0_pad_byte; - - /* True if the target system is VxWorks. */ - int is_vxworks; -}; - -#define get_elf_i386_backend_data(abfd) \ - ((const struct elf_i386_backend_data *) \ - get_elf_backend_data (abfd)->arch_data) - -/* These are the standard parameters. */ -static const struct elf_i386_backend_data elf_i386_arch_bed = - { - &elf_i386_plt, /* plt */ - 0, /* plt0_pad_byte */ - 0, /* is_vxworks */ - }; - -#define elf_backend_arch_data &elf_i386_arch_bed - -/* i386 ELF linker hash entry. */ - -struct elf_i386_link_hash_entry -{ - struct elf_link_hash_entry elf; - - /* Track dynamic relocs copied for this symbol. */ - struct elf_dyn_relocs *dyn_relocs; - -#define GOT_UNKNOWN 0 -#define GOT_NORMAL 1 -#define GOT_TLS_GD 2 -#define GOT_TLS_IE 4 -#define GOT_TLS_IE_POS 5 -#define GOT_TLS_IE_NEG 6 -#define GOT_TLS_IE_BOTH 7 -#define GOT_TLS_GDESC 8 -#define GOT_TLS_GD_BOTH_P(type) \ - ((type) == (GOT_TLS_GD | GOT_TLS_GDESC)) -#define GOT_TLS_GD_P(type) \ - ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type)) -#define GOT_TLS_GDESC_P(type) \ - ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) -#define GOT_TLS_GD_ANY_P(type) \ - (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) - unsigned char tls_type; - - /* Offset of the GOTPLT entry reserved for the TLS descriptor, - starting at the end of the jump table. */ - bfd_vma tlsdesc_got; -}; - -#define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent)) - -struct elf_i386_obj_tdata -{ - struct elf_obj_tdata root; - - /* tls_type for each local got entry. */ - char *local_got_tls_type; - - /* GOTPLT entries for TLS descriptors. */ - bfd_vma *local_tlsdesc_gotent; -}; - -#define elf_i386_tdata(abfd) \ - ((struct elf_i386_obj_tdata *) (abfd)->tdata.any) - -#define elf_i386_local_got_tls_type(abfd) \ - (elf_i386_tdata (abfd)->local_got_tls_type) - -#define elf_i386_local_tlsdesc_gotent(abfd) \ - (elf_i386_tdata (abfd)->local_tlsdesc_gotent) - -#define is_i386_elf(bfd) \ - (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ - && elf_tdata (bfd) != NULL \ - && elf_object_id (bfd) == I386_ELF_DATA) - -static bfd_boolean -elf_i386_mkobject (bfd *abfd) -{ - return bfd_elf_allocate_object (abfd, sizeof (struct elf_i386_obj_tdata), - I386_ELF_DATA); -} - -/* i386 ELF linker hash table. */ - -struct elf_i386_link_hash_table -{ - struct elf_link_hash_table elf; - - /* Short-cuts to get to dynamic linker sections. */ - asection *sdynbss; - asection *srelbss; - asection *plt_eh_frame; - - union - { - bfd_signed_vma refcount; - bfd_vma offset; - } tls_ldm_got; - - /* The amount of space used by the reserved portion of the sgotplt - section, plus whatever space is used by the jump slots. */ - bfd_vma sgotplt_jump_table_size; - - /* Small local sym cache. */ - struct sym_cache sym_cache; - - /* _TLS_MODULE_BASE_ symbol. */ - struct bfd_link_hash_entry *tls_module_base; - - /* Used by local STT_GNU_IFUNC symbols. */ - htab_t loc_hash_table; - void * loc_hash_memory; - - /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */ - asection *srelplt2; - - /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. */ - bfd_vma next_tls_desc_index; -}; - -/* Get the i386 ELF linker hash table from a link_info structure. */ - -#define elf_i386_hash_table(p) \ - (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ - == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL) - -#define elf_i386_compute_jump_table_size(htab) \ - ((htab)->next_tls_desc_index * 4) - -/* Create an entry in an i386 ELF linker hash table. */ - -static struct bfd_hash_entry * -elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct elf_i386_link_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = _bfd_elf_link_hash_newfunc (entry, table, string); - if (entry != NULL) - { - struct elf_i386_link_hash_entry *eh; - - eh = (struct elf_i386_link_hash_entry *) entry; - eh->dyn_relocs = NULL; - eh->tls_type = GOT_UNKNOWN; - eh->tlsdesc_got = (bfd_vma) -1; - } - - return entry; -} - -/* Compute a hash of a local hash entry. We use elf_link_hash_entry - for local symbol so that we can handle local STT_GNU_IFUNC symbols - as global symbol. We reuse indx and dynstr_index for local symbol - hash since they aren't used by global symbols in this backend. */ - -static hashval_t -elf_i386_local_htab_hash (const void *ptr) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) ptr; - return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index); -} - -/* Compare local hash entries. */ - -static int -elf_i386_local_htab_eq (const void *ptr1, const void *ptr2) -{ - struct elf_link_hash_entry *h1 - = (struct elf_link_hash_entry *) ptr1; - struct elf_link_hash_entry *h2 - = (struct elf_link_hash_entry *) ptr2; - - return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index; -} - -/* Find and/or create a hash entry for local symbol. */ - -static struct elf_link_hash_entry * -elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab, - bfd *abfd, const Elf_Internal_Rela *rel, - bfd_boolean create) -{ - struct elf_i386_link_hash_entry e, *ret; - asection *sec = abfd->sections; - hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, - ELF32_R_SYM (rel->r_info)); - void **slot; - - e.elf.indx = sec->id; - e.elf.dynstr_index = ELF32_R_SYM (rel->r_info); - slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h, - create ? INSERT : NO_INSERT); - - if (!slot) - return NULL; - - if (*slot) - { - ret = (struct elf_i386_link_hash_entry *) *slot; - return &ret->elf; - } - - ret = (struct elf_i386_link_hash_entry *) - objalloc_alloc ((struct objalloc *) htab->loc_hash_memory, - sizeof (struct elf_i386_link_hash_entry)); - if (ret) - { - memset (ret, 0, sizeof (*ret)); - ret->elf.indx = sec->id; - ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info); - ret->elf.dynindx = -1; - *slot = ret; - } - return &ret->elf; -} - -/* Create an i386 ELF linker hash table. */ - -static struct bfd_link_hash_table * -elf_i386_link_hash_table_create (bfd *abfd) -{ - struct elf_i386_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_i386_link_hash_table); - - ret = (struct elf_i386_link_hash_table *) bfd_malloc (amt); - if (ret == NULL) - return NULL; - - if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, - elf_i386_link_hash_newfunc, - sizeof (struct elf_i386_link_hash_entry), - I386_ELF_DATA)) - { - free (ret); - return NULL; - } - - ret->sdynbss = NULL; - ret->srelbss = NULL; - ret->plt_eh_frame = NULL; - ret->tls_ldm_got.refcount = 0; - ret->next_tls_desc_index = 0; - ret->sgotplt_jump_table_size = 0; - ret->sym_cache.abfd = NULL; - ret->srelplt2 = NULL; - ret->tls_module_base = NULL; - - ret->loc_hash_table = htab_try_create (1024, - elf_i386_local_htab_hash, - elf_i386_local_htab_eq, - NULL); - ret->loc_hash_memory = objalloc_create (); - if (!ret->loc_hash_table || !ret->loc_hash_memory) - { - free (ret); - return NULL; - } - - return &ret->elf.root; -} - -/* Destroy an i386 ELF linker hash table. */ - -static void -elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct elf_i386_link_hash_table *htab - = (struct elf_i386_link_hash_table *) hash; - - if (htab->loc_hash_table) - htab_delete (htab->loc_hash_table); - if (htab->loc_hash_memory) - objalloc_free ((struct objalloc *) htab->loc_hash_memory); - _bfd_generic_link_hash_table_free (hash); -} - -/* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and - .rel.bss sections in DYNOBJ, and set up shortcuts to them in our - hash table. */ - -static bfd_boolean -elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) -{ - struct elf_i386_link_hash_table *htab; - - if (!_bfd_elf_create_dynamic_sections (dynobj, info)) - return FALSE; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); - if (!info->shared) - htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss"); - - if (!htab->sdynbss - || (!info->shared && !htab->srelbss)) - abort (); - - if (get_elf_i386_backend_data (dynobj)->is_vxworks - && !elf_vxworks_create_dynamic_sections (dynobj, info, - &htab->srelplt2)) - return FALSE; - - if (!info->no_ld_generated_unwind_info - && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL - && htab->elf.splt != NULL) - { - flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags; - htab->plt_eh_frame - = bfd_make_section_with_flags (dynobj, ".eh_frame", - flags | SEC_READONLY); - if (htab->plt_eh_frame == NULL - || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2)) - return FALSE; - - htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt); - htab->plt_eh_frame->contents - = bfd_alloc (dynobj, htab->plt_eh_frame->size); - memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt, - sizeof (elf_i386_eh_frame_plt)); - } - - return TRUE; -} - -/* Copy the extra info we tack onto an elf_link_hash_entry. */ - -static void -elf_i386_copy_indirect_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *dir, - struct elf_link_hash_entry *ind) -{ - struct elf_i386_link_hash_entry *edir, *eind; - - edir = (struct elf_i386_link_hash_entry *) dir; - eind = (struct elf_i386_link_hash_entry *) ind; - - if (eind->dyn_relocs != NULL) - { - if (edir->dyn_relocs != NULL) - { - struct elf_dyn_relocs **pp; - struct elf_dyn_relocs *p; - - /* Add reloc counts against the indirect sym to the direct sym - list. Merge any entries against the same section. */ - for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) - { - struct elf_dyn_relocs *q; - - for (q = edir->dyn_relocs; q != NULL; q = q->next) - if (q->sec == p->sec) - { - q->pc_count += p->pc_count; - q->count += p->count; - *pp = p->next; - break; - } - if (q == NULL) - pp = &p->next; - } - *pp = edir->dyn_relocs; - } - - edir->dyn_relocs = eind->dyn_relocs; - eind->dyn_relocs = NULL; - } - - if (ind->root.type == bfd_link_hash_indirect - && dir->got.refcount <= 0) - { - edir->tls_type = eind->tls_type; - eind->tls_type = GOT_UNKNOWN; - } - - if (ELIMINATE_COPY_RELOCS - && ind->root.type != bfd_link_hash_indirect - && dir->dynamic_adjusted) - { - /* If called to transfer flags for a weakdef during processing - of elf_adjust_dynamic_symbol, don't copy non_got_ref. - We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - dir->ref_dynamic |= ind->ref_dynamic; - dir->ref_regular |= ind->ref_regular; - dir->ref_regular_nonweak |= ind->ref_regular_nonweak; - dir->needs_plt |= ind->needs_plt; - dir->pointer_equality_needed |= ind->pointer_equality_needed; - } - else - _bfd_elf_link_hash_copy_indirect (info, dir, ind); -} - -/* Return TRUE if the TLS access code sequence support transition - from R_TYPE. */ - -static bfd_boolean -elf_i386_check_tls_transition (bfd *abfd, asection *sec, - bfd_byte *contents, - Elf_Internal_Shdr *symtab_hdr, - struct elf_link_hash_entry **sym_hashes, - unsigned int r_type, - const Elf_Internal_Rela *rel, - const Elf_Internal_Rela *relend) -{ - unsigned int val, type; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - bfd_vma offset; - - /* Get the section contents. */ - if (contents == NULL) - { - if (elf_section_data (sec)->this_hdr.contents != NULL) - contents = elf_section_data (sec)->this_hdr.contents; - else - { - /* FIXME: How to better handle error condition? */ - if (!bfd_malloc_and_get_section (abfd, sec, &contents)) - return FALSE; - - /* Cache the section contents for elf_link_input_bfd. */ - elf_section_data (sec)->this_hdr.contents = contents; - } - } - - offset = rel->r_offset; - switch (r_type) - { - case R_386_TLS_GD: - case R_386_TLS_LDM: - if (offset < 2 || (rel + 1) >= relend) - return FALSE; - - type = bfd_get_8 (abfd, contents + offset - 2); - if (r_type == R_386_TLS_GD) - { - /* Check transition from GD access model. Only - leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr - leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop - can transit to different access model. */ - if ((offset + 10) > sec->size || - (type != 0x8d && type != 0x04)) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - if (type == 0x04) - { - /* leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr */ - if (offset < 3) - return FALSE; - - if (bfd_get_8 (abfd, contents + offset - 3) != 0x8d) - return FALSE; - - if ((val & 0xc7) != 0x05 || val == (4 << 3)) - return FALSE; - } - else - { - /* leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop */ - if ((val & 0xf8) != 0x80 || (val & 7) == 4) - return FALSE; - - if (bfd_get_8 (abfd, contents + offset + 9) != 0x90) - return FALSE; - } - } - else - { - /* Check transition from LD access model. Only - leal foo@tlsgd(%reg), %eax; call ___tls_get_addr - can transit to different access model. */ - if (type != 0x8d || (offset + 9) > sec->size) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - if ((val & 0xf8) != 0x80 || (val & 7) == 4) - return FALSE; - } - - if (bfd_get_8 (abfd, contents + offset + 4) != 0xe8) - return FALSE; - - r_symndx = ELF32_R_SYM (rel[1].r_info); - if (r_symndx < symtab_hdr->sh_info) - return FALSE; - - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - /* Use strncmp to check ___tls_get_addr since ___tls_get_addr - may be versioned. */ - return (h != NULL - && h->root.root.string != NULL - && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32 - || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32) - && (strncmp (h->root.root.string, "___tls_get_addr", - 15) == 0)); - - case R_386_TLS_IE: - /* Check transition from IE access model: - movl foo@indntpoff(%rip), %eax - movl foo@indntpoff(%rip), %reg - addl foo@indntpoff(%rip), %reg - */ - - if (offset < 1 || (offset + 4) > sec->size) - return FALSE; - - /* Check "movl foo@tpoff(%rip), %eax" first. */ - val = bfd_get_8 (abfd, contents + offset - 1); - if (val == 0xa1) - return TRUE; - - if (offset < 2) - return FALSE; - - /* Check movl|addl foo@tpoff(%rip), %reg. */ - type = bfd_get_8 (abfd, contents + offset - 2); - return ((type == 0x8b || type == 0x03) - && (val & 0xc7) == 0x05); - - case R_386_TLS_GOTIE: - case R_386_TLS_IE_32: - /* Check transition from {IE_32,GOTIE} access model: - subl foo@{tpoff,gontoff}(%reg1), %reg2 - movl foo@{tpoff,gontoff}(%reg1), %reg2 - addl foo@{tpoff,gontoff}(%reg1), %reg2 - */ - - if (offset < 2 || (offset + 4) > sec->size) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - if ((val & 0xc0) != 0x80 || (val & 7) == 4) - return FALSE; - - type = bfd_get_8 (abfd, contents + offset - 2); - return type == 0x8b || type == 0x2b || type == 0x03; - - case R_386_TLS_GOTDESC: - /* Check transition from GDesc access model: - leal x@tlsdesc(%ebx), %eax - - Make sure it's a leal adding ebx to a 32-bit offset - into any register, although it's probably almost always - going to be eax. */ - - if (offset < 2 || (offset + 4) > sec->size) - return FALSE; - - if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - return (val & 0xc7) == 0x83; - - case R_386_TLS_DESC_CALL: - /* Check transition from GDesc access model: - call *x@tlsdesc(%rax) - */ - if (offset + 2 <= sec->size) - { - /* Make sure that it's a call *x@tlsdesc(%rax). */ - static const unsigned char call[] = { 0xff, 0x10 }; - return memcmp (contents + offset, call, 2) == 0; - } - - return FALSE; - - default: - abort (); - } -} - -/* Return TRUE if the TLS access transition is OK or no transition - will be performed. Update R_TYPE if there is a transition. */ - -static bfd_boolean -elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, - asection *sec, bfd_byte *contents, - Elf_Internal_Shdr *symtab_hdr, - struct elf_link_hash_entry **sym_hashes, - unsigned int *r_type, int tls_type, - const Elf_Internal_Rela *rel, - const Elf_Internal_Rela *relend, - struct elf_link_hash_entry *h, - unsigned long r_symndx) -{ - unsigned int from_type = *r_type; - unsigned int to_type = from_type; - bfd_boolean check = TRUE; - - /* Skip TLS transition for functions. */ - if (h != NULL - && (h->type == STT_FUNC - || h->type == STT_GNU_IFUNC)) - return TRUE; - - switch (from_type) - { - case R_386_TLS_GD: - case R_386_TLS_GOTDESC: - case R_386_TLS_DESC_CALL: - case R_386_TLS_IE_32: - case R_386_TLS_IE: - case R_386_TLS_GOTIE: - if (info->executable) - { - if (h == NULL) - to_type = R_386_TLS_LE_32; - else if (from_type != R_386_TLS_IE - && from_type != R_386_TLS_GOTIE) - to_type = R_386_TLS_IE_32; - } - - /* When we are called from elf_i386_relocate_section, CONTENTS - isn't NULL and there may be additional transitions based on - TLS_TYPE. */ - if (contents != NULL) - { - unsigned int new_to_type = to_type; - - if (info->executable - && h != NULL - && h->dynindx == -1 - && (tls_type & GOT_TLS_IE)) - new_to_type = R_386_TLS_LE_32; - - if (to_type == R_386_TLS_GD - || to_type == R_386_TLS_GOTDESC - || to_type == R_386_TLS_DESC_CALL) - { - if (tls_type == GOT_TLS_IE_POS) - new_to_type = R_386_TLS_GOTIE; - else if (tls_type & GOT_TLS_IE) - new_to_type = R_386_TLS_IE_32; - } - - /* We checked the transition before when we were called from - elf_i386_check_relocs. We only want to check the new - transition which hasn't been checked before. */ - check = new_to_type != to_type && from_type == to_type; - to_type = new_to_type; - } - - break; - - case R_386_TLS_LDM: - if (info->executable) - to_type = R_386_TLS_LE_32; - break; - - default: - return TRUE; - } - - /* Return TRUE if there is no transition. */ - if (from_type == to_type) - return TRUE; - - /* Check if the transition can be performed. */ - if (check - && ! elf_i386_check_tls_transition (abfd, sec, contents, - symtab_hdr, sym_hashes, - from_type, rel, relend)) - { - reloc_howto_type *from, *to; - const char *name; - - from = elf_i386_rtype_to_howto (abfd, from_type); - to = elf_i386_rtype_to_howto (abfd, to_type); - - if (h) - name = h->root.root.string; - else - { - struct elf_i386_link_hash_table *htab; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - name = "*unknown*"; - else - { - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); - } - } - - (*_bfd_error_handler) - (_("%B: TLS transition from %s to %s against `%s' at 0x%lx " - "in section `%A' failed"), - abfd, sec, from->name, to->name, name, - (unsigned long) rel->r_offset); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - *r_type = to_type; - return TRUE; -} - -/* Look through the relocs for a section during the first phase, and - calculate needed space in the global offset table, procedure linkage - table, and dynamic reloc sections. */ - -static bfd_boolean -elf_i386_check_relocs (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) -{ - struct elf_i386_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sreloc; - - if (info->relocatable) - return TRUE; - - BFD_ASSERT (is_i386_elf (abfd)); - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - symtab_hdr = &elf_symtab_hdr (abfd); - sym_hashes = elf_sym_hashes (abfd); - - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned int r_type; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *isym; - const char *name; - - r_symndx = ELF32_R_SYM (rel->r_info); - r_type = ELF32_R_TYPE (rel->r_info); - - if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) - { - (*_bfd_error_handler) (_("%B: bad symbol index: %d"), - abfd, - r_symndx); - return FALSE; - } - - if (r_symndx < symtab_hdr->sh_info) - { - /* A local symbol. */ - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - if (isym == NULL) - return FALSE; - - /* Check relocation against local STT_GNU_IFUNC symbol. */ - if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) - { - h = elf_i386_get_local_sym_hash (htab, abfd, rel, TRUE); - if (h == NULL) - return FALSE; - - /* Fake a STT_GNU_IFUNC symbol. */ - h->type = STT_GNU_IFUNC; - h->def_regular = 1; - h->ref_regular = 1; - h->forced_local = 1; - h->root.type = bfd_link_hash_defined; - } - else - h = NULL; - } - else - { - isym = NULL; - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - - if (h != NULL) - { - /* Create the ifunc sections for static executables. If we - never see an indirect function symbol nor we are building - a static executable, those sections will be empty and - won't appear in output. */ - switch (r_type) - { - default: - break; - - case R_386_32: - case R_386_PC32: - case R_386_PLT32: - case R_386_GOT32: - case R_386_GOTOFF: - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) - return FALSE; - break; - } - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - { - /* It is referenced by a non-shared object. */ - h->ref_regular = 1; - h->needs_plt = 1; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - h->plt.refcount += 1; - - /* STT_GNU_IFUNC needs dynamic sections. */ - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), abfd, - elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_386_32: - h->non_got_ref = 1; - h->pointer_equality_needed = 1; - if (info->shared) - { - /* We must copy these reloc types into the - output file. Create a reloc section in - dynobj and make room for this reloc. */ - sreloc = _bfd_elf_create_ifunc_dyn_reloc - (abfd, info, sec, sreloc, - &((struct elf_i386_link_hash_entry *) h)->dyn_relocs); - if (sreloc == NULL) - return FALSE; - } - break; - - case R_386_PC32: - h->non_got_ref = 1; - break; - - case R_386_PLT32: - break; - - case R_386_GOT32: - case R_386_GOTOFF: - h->got.refcount += 1; - if (htab->elf.sgot == NULL - && !_bfd_elf_create_got_section (htab->elf.dynobj, - info)) - return FALSE; - break; - } - - continue; - } - } - - if (! elf_i386_tls_transition (info, abfd, sec, NULL, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, rel_end, h, r_symndx)) - return FALSE; - - switch (r_type) - { - case R_386_TLS_LDM: - htab->tls_ldm_got.refcount += 1; - goto create_got; - - case R_386_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->needs_plt = 1; - h->plt.refcount += 1; - break; - - case R_386_TLS_IE_32: - case R_386_TLS_IE: - case R_386_TLS_GOTIE: - if (!info->executable) - info->flags |= DF_STATIC_TLS; - /* Fall through */ - - case R_386_GOT32: - case R_386_TLS_GD: - case R_386_TLS_GOTDESC: - case R_386_TLS_DESC_CALL: - /* This symbol requires a global offset table entry. */ - { - int tls_type, old_tls_type; - - switch (r_type) - { - default: - case R_386_GOT32: tls_type = GOT_NORMAL; break; - case R_386_TLS_GD: tls_type = GOT_TLS_GD; break; - case R_386_TLS_GOTDESC: - case R_386_TLS_DESC_CALL: - tls_type = GOT_TLS_GDESC; break; - case R_386_TLS_IE_32: - if (ELF32_R_TYPE (rel->r_info) == r_type) - tls_type = GOT_TLS_IE_NEG; - else - /* If this is a GD->IE transition, we may use either of - R_386_TLS_TPOFF and R_386_TLS_TPOFF32. */ - tls_type = GOT_TLS_IE; - break; - case R_386_TLS_IE: - case R_386_TLS_GOTIE: - tls_type = GOT_TLS_IE_POS; break; - } - - if (h != NULL) - { - h->got.refcount += 1; - old_tls_type = elf_i386_hash_entry(h)->tls_type; - } - else - { - bfd_signed_vma *local_got_refcounts; - - /* This is a global offset table entry for a local symbol. */ - local_got_refcounts = elf_local_got_refcounts (abfd); - if (local_got_refcounts == NULL) - { - bfd_size_type size; - - size = symtab_hdr->sh_info; - size *= (sizeof (bfd_signed_vma) - + sizeof (bfd_vma) + sizeof(char)); - local_got_refcounts = (bfd_signed_vma *) - bfd_zalloc (abfd, size); - if (local_got_refcounts == NULL) - return FALSE; - elf_local_got_refcounts (abfd) = local_got_refcounts; - elf_i386_local_tlsdesc_gotent (abfd) - = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info); - elf_i386_local_got_tls_type (abfd) - = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info); - } - local_got_refcounts[r_symndx] += 1; - old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx]; - } - - if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE)) - tls_type |= old_tls_type; - /* If a TLS symbol is accessed using IE at least once, - there is no point to use dynamic model for it. */ - else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN - && (! GOT_TLS_GD_ANY_P (old_tls_type) - || (tls_type & GOT_TLS_IE) == 0)) - { - if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type)) - tls_type = old_tls_type; - else if (GOT_TLS_GD_ANY_P (old_tls_type) - && GOT_TLS_GD_ANY_P (tls_type)) - tls_type |= old_tls_type; - else - { - if (h) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: `%s' accessed both as normal and " - "thread local symbol"), - abfd, name); - return FALSE; - } - } - - if (old_tls_type != tls_type) - { - if (h != NULL) - elf_i386_hash_entry (h)->tls_type = tls_type; - else - elf_i386_local_got_tls_type (abfd) [r_symndx] = tls_type; - } - } - /* Fall through */ - - case R_386_GOTOFF: - case R_386_GOTPC: - create_got: - if (htab->elf.sgot == NULL) - { - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - if (!_bfd_elf_create_got_section (htab->elf.dynobj, info)) - return FALSE; - } - if (r_type != R_386_TLS_IE) - break; - /* Fall through */ - - case R_386_TLS_LE_32: - case R_386_TLS_LE: - if (info->executable) - break; - info->flags |= DF_STATIC_TLS; - /* Fall through */ - - case R_386_32: - case R_386_PC32: - if (h != NULL && info->executable) - { - /* If this reloc is in a read-only section, we might - need a copy reloc. We can't check reliably at this - stage whether the section is read-only, as input - sections have not yet been mapped to output sections. - Tentatively set the flag for now, and correct in - adjust_dynamic_symbol. */ - h->non_got_ref = 1; - - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; - if (r_type != R_386_PC32) - h->pointer_equality_needed = 1; - } - - /* If we are creating a shared library, and this is a reloc - against a global symbol, or a non PC relative reloc - against a local symbol, then we need to copy the reloc - into the shared library. However, if we are linking with - -Bsymbolic, we do not need to copy a reloc against a - global symbol which is defined in an object we are - including in the link (i.e., DEF_REGULAR is set). At - this point we have not seen all the input files, so it is - possible that DEF_REGULAR is not set now but will be set - later (it is never cleared). In case of a weak definition, - DEF_REGULAR may be cleared later by a strong definition in - a shared library. We account for that possibility below by - storing information in the relocs_copied field of the hash - table entry. A similar situation occurs when creating - shared libraries and symbol visibility changes render the - symbol local. - - If on the other hand, we are creating an executable, we - may need to keep relocations for symbols satisfied by a - dynamic library if we manage to avoid copy relocs for the - symbol. */ - if ((info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (r_type != R_386_PC32 - || (h != NULL - && (! SYMBOLIC_BIND (info, h) - || h->root.type == bfd_link_hash_defweak - || !h->def_regular)))) - || (ELIMINATE_COPY_RELOCS - && !info->shared - && (sec->flags & SEC_ALLOC) != 0 - && h != NULL - && (h->root.type == bfd_link_hash_defweak - || !h->def_regular))) - { - struct elf_dyn_relocs *p; - struct elf_dyn_relocs **head; - - /* We must copy these reloc types into the output file. - Create a reloc section in dynobj and make room for - this reloc. */ - if (sreloc == NULL) - { - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - sreloc = _bfd_elf_make_dynamic_reloc_section - (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE); - - if (sreloc == NULL) - return FALSE; - } - - /* If this is a global symbol, we count the number of - relocations we need for this symbol. */ - if (h != NULL) - { - head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs; - } - else - { - /* Track dynamic relocs needed for local syms too. - We really need local syms available to do this - easily. Oh well. */ - void **vpp; - asection *s; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - if (isym == NULL) - return FALSE; - - s = bfd_section_from_elf_index (abfd, isym->st_shndx); - if (s == NULL) - s = sec; - - vpp = &elf_section_data (s)->local_dynrel; - head = (struct elf_dyn_relocs **)vpp; - } - - p = *head; - if (p == NULL || p->sec != sec) - { - bfd_size_type amt = sizeof *p; - p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, - amt); - if (p == NULL) - return FALSE; - p->next = *head; - *head = p; - p->sec = sec; - p->count = 0; - p->pc_count = 0; - } - - p->count += 1; - if (r_type == R_386_PC32) - p->pc_count += 1; - } - break; - - /* This relocation describes the C++ object vtable hierarchy. - Reconstruct it for later use during GC. */ - case R_386_GNU_VTINHERIT: - if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return FALSE; - break; - - /* This relocation describes which C++ vtable entries are actually - used. Record for later use during GC. */ - case R_386_GNU_VTENTRY: - BFD_ASSERT (h != NULL); - if (h != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) - return FALSE; - break; - - default: - break; - } - } - - return TRUE; -} - -/* Return the section that should be marked against GC for a given - relocation. */ - -static asection * -elf_i386_gc_mark_hook (asection *sec, - struct bfd_link_info *info, - Elf_Internal_Rela *rel, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - if (h != NULL) - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_GNU_VTINHERIT: - case R_386_GNU_VTENTRY: - return NULL; - } - - return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); -} - -/* Update the got entry reference counts for the section being removed. */ - -static bfd_boolean -elf_i386_gc_sweep_hook (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) -{ - struct elf_i386_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; - const Elf_Internal_Rela *rel, *relend; - - if (info->relocatable) - return TRUE; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - elf_section_data (sec)->local_dynrel = NULL; - - symtab_hdr = &elf_symtab_hdr (abfd); - sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); - - relend = relocs + sec->reloc_count; - for (rel = relocs; rel < relend; rel++) - { - unsigned long r_symndx; - unsigned int r_type; - struct elf_link_hash_entry *h = NULL; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - else - { - /* A local symbol. */ - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - - /* Check relocation against local STT_GNU_IFUNC symbol. */ - if (isym != NULL - && ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) - { - h = elf_i386_get_local_sym_hash (htab, abfd, rel, FALSE); - if (h == NULL) - abort (); - } - } - - if (h) - { - struct elf_i386_link_hash_entry *eh; - struct elf_dyn_relocs **pp; - struct elf_dyn_relocs *p; - - eh = (struct elf_i386_link_hash_entry *) h; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) - if (p->sec == sec) - { - /* Everything must go for SEC. */ - *pp = p->next; - break; - } - } - - r_type = ELF32_R_TYPE (rel->r_info); - if (! elf_i386_tls_transition (info, abfd, sec, NULL, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, relend, h, r_symndx)) - return FALSE; - - switch (r_type) - { - case R_386_TLS_LDM: - if (htab->tls_ldm_got.refcount > 0) - htab->tls_ldm_got.refcount -= 1; - break; - - case R_386_TLS_GD: - case R_386_TLS_GOTDESC: - case R_386_TLS_DESC_CALL: - case R_386_TLS_IE_32: - case R_386_TLS_IE: - case R_386_TLS_GOTIE: - case R_386_GOT32: - if (h != NULL) - { - if (h->got.refcount > 0) - h->got.refcount -= 1; - if (h->type == STT_GNU_IFUNC) - { - if (h->plt.refcount > 0) - h->plt.refcount -= 1; - } - } - else if (local_got_refcounts != NULL) - { - if (local_got_refcounts[r_symndx] > 0) - local_got_refcounts[r_symndx] -= 1; - } - break; - - case R_386_32: - case R_386_PC32: - if (info->shared - && (h == NULL || h->type != STT_GNU_IFUNC)) - break; - /* Fall through */ - - case R_386_PLT32: - if (h != NULL) - { - if (h->plt.refcount > 0) - h->plt.refcount -= 1; - } - break; - - case R_386_GOTOFF: - if (h != NULL && h->type == STT_GNU_IFUNC) - { - if (h->got.refcount > 0) - h->got.refcount -= 1; - if (h->plt.refcount > 0) - h->plt.refcount -= 1; - } - break; - - default: - break; - } - } - - return TRUE; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static bfd_boolean -elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) -{ - struct elf_i386_link_hash_table *htab; - asection *s; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - if (h->type == STT_GNU_IFUNC) - { - if (h->plt.refcount <= 0) - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - return TRUE; - } - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || h->needs_plt) - { - if (h->plt.refcount <= 0 - || SYMBOL_CALLS_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak)) - { - /* This case can occur if we saw a PLT32 reloc in an input - file, but the symbol was never referred to by a dynamic - object, or if all references were garbage collected. In - such a case, we don't actually need to build a procedure - linkage table, and we can just do a PC32 reloc instead. */ - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - - return TRUE; - } - else - /* It's possible that we incorrectly decided a .plt reloc was - needed for an R_386_PC32 reloc to a non-function sym in - check_relocs. We can't decide accurately between function and - non-function syms in check-relocs; Objects loaded later in - the link may change h->type. So fix it now. */ - h->plt.offset = (bfd_vma) -1; - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->u.weakdef != NULL) - { - BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined - || h->u.weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->u.weakdef->root.u.def.section; - h->root.u.def.value = h->u.weakdef->root.u.def.value; - if (ELIMINATE_COPY_RELOCS || info->nocopyreloc) - h->non_got_ref = h->u.weakdef->non_got_ref; - return TRUE; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return TRUE; - - /* If there are no references to this symbol that do not use the - GOT, we don't need to generate a copy reloc. */ - if (!h->non_got_ref) - return TRUE; - - /* If -z nocopyreloc was given, we won't generate them either. */ - if (info->nocopyreloc) - { - h->non_got_ref = 0; - return TRUE; - } - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - /* If there aren't any dynamic relocs in read-only sections, then - we can keep the dynamic relocs and avoid the copy reloc. This - doesn't work on VxWorks, where we can not have dynamic relocations - (other than copy and jump slot relocations) in an executable. */ - if (ELIMINATE_COPY_RELOCS - && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks) - { - struct elf_i386_link_hash_entry * eh; - struct elf_dyn_relocs *p; - - eh = (struct elf_i386_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - s = p->sec->output_section; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - break; - } - - if (p == NULL) - { - h->non_got_ref = 0; - return TRUE; - } - } - - if (h->size == 0) - { - (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), - h->root.root.string); - return TRUE; - } - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - /* We must generate a R_386_COPY reloc to tell the dynamic linker to - copy the initial value out of the dynamic object and into the - runtime process image. */ - if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) - { - htab->srelbss->size += sizeof (Elf32_External_Rel); - h->needs_copy = 1; - } - - s = htab->sdynbss; - - return _bfd_elf_adjust_dynamic_copy (h, s); -} - -/* Allocate space in .plt, .got and associated reloc sections for - dynamic relocs. */ - -static bfd_boolean -elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) -{ - struct bfd_link_info *info; - struct elf_i386_link_hash_table *htab; - struct elf_i386_link_hash_entry *eh; - struct elf_dyn_relocs *p; - unsigned plt_entry_size; - - if (h->root.type == bfd_link_hash_indirect) - return TRUE; - - eh = (struct elf_i386_link_hash_entry *) h; - - info = (struct bfd_link_info *) inf; - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd); - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it - here if it is defined and referenced in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, - plt_entry_size, 4); - else if (htab->elf.dynamic_sections_created - && h->plt.refcount > 0) - { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - if (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) - { - asection *s = htab->elf.splt; - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->size == 0) - s->size += plt_entry_size; - - h->plt.offset = s->size; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && !h->def_regular) - { - h->root.u.def.section = s; - h->root.u.def.value = h->plt.offset; - } - - /* Make room for this entry. */ - s->size += plt_entry_size; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - htab->elf.sgotplt->size += 4; - - /* We also need to make an entry in the .rel.plt section. */ - htab->elf.srelplt->size += sizeof (Elf32_External_Rel); - htab->next_tls_desc_index++; - - if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks - && !info->shared) - { - /* VxWorks has a second set of relocations for each PLT entry - in executables. They go in a separate relocation section, - which is processed by the kernel loader. */ - - /* There are two relocations for the initial PLT entry: an - R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an - R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8. */ - - if (h->plt.offset == plt_entry_size) - htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2); - - /* There are two extra relocations for each subsequent PLT entry: - an R_386_32 relocation for the GOT entry, and an R_386_32 - relocation for the PLT entry. */ - - htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2); - } - } - else - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - } - else - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - - eh->tlsdesc_got = (bfd_vma) -1; - - /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary, - make it a R_386_TLS_LE_32 requiring no TLS entry. */ - if (h->got.refcount > 0 - && info->executable - && h->dynindx == -1 - && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE)) - h->got.offset = (bfd_vma) -1; - else if (h->got.refcount > 0) - { - asection *s; - bfd_boolean dyn; - int tls_type = elf_i386_hash_entry(h)->tls_type; - - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - s = htab->elf.sgot; - if (GOT_TLS_GDESC_P (tls_type)) - { - eh->tlsdesc_got = htab->elf.sgotplt->size - - elf_i386_compute_jump_table_size (htab); - htab->elf.sgotplt->size += 8; - h->got.offset = (bfd_vma) -2; - } - if (! GOT_TLS_GDESC_P (tls_type) - || GOT_TLS_GD_P (tls_type)) - { - h->got.offset = s->size; - s->size += 4; - /* R_386_TLS_GD needs 2 consecutive GOT slots. */ - if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH) - s->size += 4; - } - dyn = htab->elf.dynamic_sections_created; - /* R_386_TLS_IE_32 needs one dynamic relocation, - R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation, - (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we - need two), R_386_TLS_GD needs one if local symbol and two if - global. */ - if (tls_type == GOT_TLS_IE_BOTH) - htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); - else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) - || (tls_type & GOT_TLS_IE)) - htab->elf.srelgot->size += sizeof (Elf32_External_Rel); - else if (GOT_TLS_GD_P (tls_type)) - htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel); - else if (! GOT_TLS_GDESC_P (tls_type) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) - && (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) - htab->elf.srelgot->size += sizeof (Elf32_External_Rel); - if (GOT_TLS_GDESC_P (tls_type)) - htab->elf.srelplt->size += sizeof (Elf32_External_Rel); - } - else - h->got.offset = (bfd_vma) -1; - - if (eh->dyn_relocs == NULL) - return TRUE; - - /* In the shared -Bsymbolic case, discard space allocated for - dynamic pc-relative relocs against symbols which turn out to be - defined in regular objects. For the normal shared case, discard - space for pc-relative relocs that have become local due to symbol - visibility changes. */ - - if (info->shared) - { - /* The only reloc that uses pc_count is R_386_PC32, which will - appear on a call or on something like ".long foo - .". We - want calls to protected symbols to resolve directly to the - function rather than going via the plt. If people want - function pointer comparisons to work as expected then they - should avoid writing assembly like ".long foo - .". */ - if (SYMBOL_CALLS_LOCAL (info, h)) - { - struct elf_dyn_relocs **pp; - - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) - { - p->count -= p->pc_count; - p->pc_count = 0; - if (p->count == 0) - *pp = p->next; - else - pp = &p->next; - } - } - - if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks) - { - struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) - { - if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) - *pp = p->next; - else - pp = &p->next; - } - } - - /* Also discard relocs on undefined weak syms with non-default - visibility. */ - if (eh->dyn_relocs != NULL - && h->root.type == bfd_link_hash_undefweak) - { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - eh->dyn_relocs = NULL; - - /* Make sure undefined weak symbols are output as a dynamic - symbol in PIEs. */ - else if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - } - } - else if (ELIMINATE_COPY_RELOCS) - { - /* For the non-shared case, discard space for relocs against - symbols which turn out to need copy relocs or are not - dynamic. */ - - if (!h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || (htab->elf.dynamic_sections_created - && (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_undefined)))) - { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - /* If that succeeded, we know we'll be keeping all the - relocs. */ - if (h->dynindx != -1) - goto keep; - } - - eh->dyn_relocs = NULL; - - keep: ; - } - - /* Finally, allocate space. */ - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *sreloc; - - sreloc = elf_section_data (p->sec)->sreloc; - - BFD_ASSERT (sreloc != NULL); - sreloc->size += p->count * sizeof (Elf32_External_Rel); - } - - return TRUE; -} - -/* Allocate space in .plt, .got and associated reloc sections for - local dynamic relocs. */ - -static bfd_boolean -elf_i386_allocate_local_dynrelocs (void **slot, void *inf) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) *slot; - - if (h->type != STT_GNU_IFUNC - || !h->def_regular - || !h->ref_regular - || !h->forced_local - || h->root.type != bfd_link_hash_defined) - abort (); - - return elf_i386_allocate_dynrelocs (h, inf); -} - -/* Find any dynamic relocs that apply to read-only sections. */ - -static bfd_boolean -elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) -{ - struct elf_i386_link_hash_entry *eh; - struct elf_dyn_relocs *p; - - /* Skip local IFUNC symbols. */ - if (h->forced_local && h->type == STT_GNU_IFUNC) - return TRUE; - - eh = (struct elf_i386_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; - - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - info->flags |= DF_TEXTREL; - - if (info->warn_shared_textrel && info->shared) - info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"), - p->sec->owner, h->root.root.string, - p->sec); - - /* Not an error, just cut short the traversal. */ - return FALSE; - } - } - return TRUE; -} - -/* Set the sizes of the dynamic sections. */ - -static bfd_boolean -elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) -{ - struct elf_i386_link_hash_table *htab; - bfd *dynobj; - asection *s; - bfd_boolean relocs; - bfd *ibfd; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - dynobj = htab->elf.dynobj; - if (dynobj == NULL) - abort (); - - if (htab->elf.dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (info->executable) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - if (s == NULL) - abort (); - s->size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - - /* Set up .got offsets for local syms, and space for local dynamic - relocs. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) - { - bfd_signed_vma *local_got; - bfd_signed_vma *end_local_got; - char *local_tls_type; - bfd_vma *local_tlsdesc_gotent; - bfd_size_type locsymcount; - Elf_Internal_Shdr *symtab_hdr; - asection *srel; - - if (! is_i386_elf (ibfd)) - continue; - - for (s = ibfd->sections; s != NULL; s = s->next) - { - struct elf_dyn_relocs *p; - - for (p = ((struct elf_dyn_relocs *) - elf_section_data (s)->local_dynrel); - p != NULL; - p = p->next) - { - if (!bfd_is_abs_section (p->sec) - && bfd_is_abs_section (p->sec->output_section)) - { - /* Input section has been discarded, either because - it is a copy of a linkonce section or due to - linker script /DISCARD/, so we'll be discarding - the relocs too. */ - } - else if (get_elf_i386_backend_data (output_bfd)->is_vxworks - && strcmp (p->sec->output_section->name, - ".tls_vars") == 0) - { - /* Relocations in vxworks .tls_vars sections are - handled specially by the loader. */ - } - else if (p->count != 0) - { - srel = elf_section_data (p->sec)->sreloc; - srel->size += p->count * sizeof (Elf32_External_Rel); - if ((p->sec->output_section->flags & SEC_READONLY) != 0 - && (info->flags & DF_TEXTREL) == 0) - { - info->flags |= DF_TEXTREL; - if (info->warn_shared_textrel && info->shared) - info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"), - p->sec->owner, p->sec); - } - } - } - } - - local_got = elf_local_got_refcounts (ibfd); - if (!local_got) - continue; - - symtab_hdr = &elf_symtab_hdr (ibfd); - locsymcount = symtab_hdr->sh_info; - end_local_got = local_got + locsymcount; - local_tls_type = elf_i386_local_got_tls_type (ibfd); - local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd); - s = htab->elf.sgot; - srel = htab->elf.srelgot; - for (; local_got < end_local_got; - ++local_got, ++local_tls_type, ++local_tlsdesc_gotent) - { - *local_tlsdesc_gotent = (bfd_vma) -1; - if (*local_got > 0) - { - if (GOT_TLS_GDESC_P (*local_tls_type)) - { - *local_tlsdesc_gotent = htab->elf.sgotplt->size - - elf_i386_compute_jump_table_size (htab); - htab->elf.sgotplt->size += 8; - *local_got = (bfd_vma) -2; - } - if (! GOT_TLS_GDESC_P (*local_tls_type) - || GOT_TLS_GD_P (*local_tls_type)) - { - *local_got = s->size; - s->size += 4; - if (GOT_TLS_GD_P (*local_tls_type) - || *local_tls_type == GOT_TLS_IE_BOTH) - s->size += 4; - } - if (info->shared - || GOT_TLS_GD_ANY_P (*local_tls_type) - || (*local_tls_type & GOT_TLS_IE)) - { - if (*local_tls_type == GOT_TLS_IE_BOTH) - srel->size += 2 * sizeof (Elf32_External_Rel); - else if (GOT_TLS_GD_P (*local_tls_type) - || ! GOT_TLS_GDESC_P (*local_tls_type)) - srel->size += sizeof (Elf32_External_Rel); - if (GOT_TLS_GDESC_P (*local_tls_type)) - htab->elf.srelplt->size += sizeof (Elf32_External_Rel); - } - } - else - *local_got = (bfd_vma) -1; - } - } - - if (htab->tls_ldm_got.refcount > 0) - { - /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM - relocs. */ - htab->tls_ldm_got.offset = htab->elf.sgot->size; - htab->elf.sgot->size += 8; - htab->elf.srelgot->size += sizeof (Elf32_External_Rel); - } - else - htab->tls_ldm_got.offset = -1; - - /* Allocate global sym .plt and .got entries, and space for global - sym dynamic relocs. */ - elf_link_hash_traverse (&htab->elf, elf_i386_allocate_dynrelocs, info); - - /* Allocate .plt and .got entries, and space for local symbols. */ - htab_traverse (htab->loc_hash_table, - elf_i386_allocate_local_dynrelocs, - info); - - /* For every jump slot reserved in the sgotplt, reloc_count is - incremented. However, when we reserve space for TLS descriptors, - it's not incremented, so in order to compute the space reserved - for them, it suffices to multiply the reloc count by the jump - slot size. */ - if (htab->elf.srelplt) - htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4; - - if (htab->elf.sgotplt) - { - struct elf_link_hash_entry *got; - got = elf_link_hash_lookup (elf_hash_table (info), - "_GLOBAL_OFFSET_TABLE_", - FALSE, FALSE, FALSE); - - /* Don't allocate .got.plt section if there are no GOT nor PLT - entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */ - if ((got == NULL - || !got->ref_regular_nonweak) - && (htab->elf.sgotplt->size - == get_elf_backend_data (output_bfd)->got_header_size) - && (htab->elf.splt == NULL - || htab->elf.splt->size == 0) - && (htab->elf.sgot == NULL - || htab->elf.sgot->size == 0) - && (htab->elf.iplt == NULL - || htab->elf.iplt->size == 0) - && (htab->elf.igotplt == NULL - || htab->elf.igotplt->size == 0)) - htab->elf.sgotplt->size = 0; - } - - /* We now have determined the sizes of the various dynamic sections. - Allocate memory for them. */ - relocs = FALSE; - for (s = dynobj->sections; s != NULL; s = s->next) - { - bfd_boolean strip_section = TRUE; - - if ((s->flags & SEC_LINKER_CREATED) == 0) - continue; - - if (s == htab->elf.splt - || s == htab->elf.sgot - || s == htab->elf.sgotplt - || s == htab->elf.iplt - || s == htab->elf.igotplt - || s == htab->sdynbss) - { - /* Strip this section if we don't need it; see the - comment below. */ - /* We'd like to strip these sections if they aren't needed, but if - we've exported dynamic symbols from them we must leave them. - It's too late to tell BFD to get rid of the symbols. */ - - if (htab->elf.hplt != NULL) - strip_section = FALSE; - } - else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel")) - { - if (s->size != 0 - && s != htab->elf.srelplt - && s != htab->srelplt2) - relocs = TRUE; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - else - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (s->size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rel.bss and - .rel.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - if (strip_section) - s->flags |= SEC_EXCLUDE; - continue; - } - - if ((s->flags & SEC_HAS_CONTENTS) == 0) - continue; - - /* Allocate memory for the section contents. We use bfd_zalloc - here in case unused entries are not reclaimed before the - section's contents are written out. This should not happen, - but this way if it does, we get a R_386_NONE reloc instead - of garbage. */ - s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size); - if (s->contents == NULL) - return FALSE; - } - - if (htab->plt_eh_frame != NULL - && htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && (htab->elf.splt->flags & SEC_EXCLUDE) == 0) - bfd_put_32 (dynobj, htab->elf.splt->size, - htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); - - if (htab->elf.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_i386_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ -#define add_dynamic_entry(TAG, VAL) \ - _bfd_elf_add_dynamic_entry (info, TAG, VAL) - - if (info->executable) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_REL) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_REL, 0) - || !add_dynamic_entry (DT_RELSZ, 0) - || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel))) - return FALSE; - - /* If any dynamic relocs apply to a read-only section, - then we need a DT_TEXTREL entry. */ - if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, - elf_i386_readonly_dynrelocs, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - if (get_elf_i386_backend_data (output_bfd)->is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; - } -#undef add_dynamic_entry - - return TRUE; -} - -static bfd_boolean -elf_i386_always_size_sections (bfd *output_bfd, - struct bfd_link_info *info) -{ - asection *tls_sec = elf_hash_table (info)->tls_sec; - - if (tls_sec) - { - struct elf_link_hash_entry *tlsbase; - - tlsbase = elf_link_hash_lookup (elf_hash_table (info), - "_TLS_MODULE_BASE_", - FALSE, FALSE, FALSE); - - if (tlsbase && tlsbase->type == STT_TLS) - { - struct elf_i386_link_hash_table *htab; - struct bfd_link_hash_entry *bh = NULL; - const struct elf_backend_data *bed - = get_elf_backend_data (output_bfd); - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL, - tls_sec, 0, NULL, FALSE, - bed->collect, &bh))) - return FALSE; - - htab->tls_module_base = bh; - - tlsbase = (struct elf_link_hash_entry *)bh; - tlsbase->def_regular = 1; - tlsbase->other = STV_HIDDEN; - (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); - } - } - - return TRUE; -} - -/* Set the correct type for an x86 ELF section. We do this by the - section name, which is a hack, but ought to work. */ - -static bfd_boolean -elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, - Elf_Internal_Shdr *hdr, - asection *sec) -{ - const char *name; - - name = bfd_get_section_name (abfd, sec); - - /* This is an ugly, but unfortunately necessary hack that is - needed when producing EFI binaries on x86. It tells - elf.c:elf_fake_sections() not to consider ".reloc" as a section - containing ELF relocation info. We need this hack in order to - be able to generate ELF binaries that can be translated into - EFI applications (which are essentially COFF objects). Those - files contain a COFF ".reloc" section inside an ELFNN object, - which would normally cause BFD to segfault because it would - attempt to interpret this section as containing relocation - entries for section "oc". With this hack enabled, ".reloc" - will be treated as a normal data section, which will avoid the - segfault. However, you won't be able to create an ELFNN binary - with a section named "oc" that needs relocations, but that's - the kind of ugly side-effects you get when detecting section - types based on their names... In practice, this limitation is - unlikely to bite. */ - if (strcmp (name, ".reloc") == 0) - hdr->sh_type = SHT_PROGBITS; - - return TRUE; -} - -/* _TLS_MODULE_BASE_ needs to be treated especially when linking - executables. Rather than setting it to the beginning of the TLS - section, we have to set it to the end. This function may be called - multiple times, it is idempotent. */ - -static void -elf_i386_set_tls_module_base (struct bfd_link_info *info) -{ - struct elf_i386_link_hash_table *htab; - struct bfd_link_hash_entry *base; - - if (!info->executable) - return; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return; - - base = htab->tls_module_base; - if (base == NULL) - return; - - base->u.def.value = htab->elf.tls_size; -} - -/* Return the base VMA address which should be subtracted from real addresses - when resolving @dtpoff relocation. - This is PT_TLS segment p_vaddr. */ - -static bfd_vma -elf_i386_dtpoff_base (struct bfd_link_info *info) -{ - /* If tls_sec is NULL, we should have signalled an error already. */ - if (elf_hash_table (info)->tls_sec == NULL) - return 0; - return elf_hash_table (info)->tls_sec->vma; -} - -/* Return the relocation value for @tpoff relocation - if STT_TLS virtual address is ADDRESS. */ - -static bfd_vma -elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address) -{ - struct elf_link_hash_table *htab = elf_hash_table (info); - const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd); - bfd_vma static_tls_size; - - /* If tls_sec is NULL, we should have signalled an error already. */ - if (htab->tls_sec == NULL) - return 0; - - /* Consider special static TLS alignment requirements. */ - static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment); - return static_tls_size + htab->tls_sec->vma - address; -} - -/* Relocate an i386 ELF section. */ - -static bfd_boolean -elf_i386_relocate_section (bfd *output_bfd, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, - asection **local_sections) -{ - struct elf_i386_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - bfd_vma *local_tlsdesc_gotents; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - bfd_boolean is_vxworks_tls; - unsigned plt_entry_size; - - BFD_ASSERT (is_i386_elf (input_bfd)); - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - symtab_hdr = &elf_symtab_hdr (input_bfd); - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd); - /* We have to handle relocations in vxworks .tls_vars sections - specially, because the dynamic loader is 'weird'. */ - is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks - && info->shared - && !strcmp (input_section->output_section->name, - ".tls_vars")); - - elf_i386_set_tls_module_base (info); - - plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - unsigned int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma off, offplt; - bfd_vma relocation; - bfd_boolean unresolved_reloc; - bfd_reloc_status_type r; - unsigned int indx; - int tls_type; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type == R_386_GNU_VTINHERIT - || r_type == R_386_GNU_VTENTRY) - continue; - - if ((indx = r_type) >= R_386_standard - && ((indx = r_type - R_386_ext_offset) - R_386_standard - >= R_386_ext - R_386_standard) - && ((indx = r_type - R_386_tls_offset) - R_386_ext - >= R_386_irelative - R_386_ext)) - { - (*_bfd_error_handler) - (_("%B: unrecognized relocation (0x%x) in section `%A'"), - input_bfd, input_section, r_type); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - howto = elf_howto_table + indx; - - r_symndx = ELF32_R_SYM (rel->r_info); - h = NULL; - sym = NULL; - sec = NULL; - unresolved_reloc = FALSE; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION - && ((sec->flags & SEC_MERGE) != 0 - || (info->relocatable - && sec->output_offset != 0))) - { - bfd_vma addend; - bfd_byte *where = contents + rel->r_offset; - - switch (howto->size) - { - case 0: - addend = bfd_get_8 (input_bfd, where); - if (howto->pc_relative) - { - addend = (addend ^ 0x80) - 0x80; - addend += 1; - } - break; - case 1: - addend = bfd_get_16 (input_bfd, where); - if (howto->pc_relative) - { - addend = (addend ^ 0x8000) - 0x8000; - addend += 2; - } - break; - case 2: - addend = bfd_get_32 (input_bfd, where); - if (howto->pc_relative) - { - addend = (addend ^ 0x80000000) - 0x80000000; - addend += 4; - } - break; - default: - abort (); - } - - if (info->relocatable) - addend += sec->output_offset; - else - { - asection *msec = sec; - addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, - addend); - addend -= relocation; - addend += msec->output_section->vma + msec->output_offset; - } - - switch (howto->size) - { - case 0: - /* FIXME: overflow checks. */ - if (howto->pc_relative) - addend -= 1; - bfd_put_8 (input_bfd, addend, where); - break; - case 1: - if (howto->pc_relative) - addend -= 2; - bfd_put_16 (input_bfd, addend, where); - break; - case 2: - if (howto->pc_relative) - addend -= 4; - bfd_put_32 (input_bfd, addend, where); - break; - } - } - else if (!info->relocatable - && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) - { - /* Relocate against local STT_GNU_IFUNC symbol. */ - h = elf_i386_get_local_sym_hash (htab, input_bfd, rel, - FALSE); - if (h == NULL) - abort (); - - /* Set STT_GNU_IFUNC symbol value. */ - h->root.u.def.value = sym->st_value; - h->root.u.def.section = sec; - } - } - else - { - bfd_boolean warned ATTRIBUTE_UNUSED; - - RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, - r_symndx, symtab_hdr, sym_hashes, - h, sec, relocation, - unresolved_reloc, warned); - } - - if (sec != NULL && elf_discarded_section (sec)) - RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, relend, howto, contents); - - if (info->relocatable) - continue; - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h != NULL - && h->type == STT_GNU_IFUNC - && h->def_regular) - { - asection *plt, *gotplt, *base_got; - bfd_vma plt_index; - const char *name; - - if ((input_section->flags & SEC_ALLOC) == 0 - || h->plt.offset == (bfd_vma) -1) - abort (); - - /* STT_GNU_IFUNC symbol must go through PLT. */ - if (htab->elf.splt != NULL) - { - plt = htab->elf.splt; - gotplt = htab->elf.sgotplt; - } - else - { - plt = htab->elf.iplt; - gotplt = htab->elf.igotplt; - } - - relocation = (plt->output_section->vma - + plt->output_offset + h->plt.offset); - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), input_bfd, - elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_386_32: - /* Generate dynamic relcoation only when there is a - non-GOF reference in a shared object. */ - if (info->shared && h->non_got_ref) - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - asection *sreloc; - bfd_vma offset; - - /* Need a dynamic relocation to get the real function - adddress. */ - offset = _bfd_elf_section_offset (output_bfd, - info, - input_section, - rel->r_offset); - if (offset == (bfd_vma) -1 - || offset == (bfd_vma) -2) - abort (); - - outrel.r_offset = (input_section->output_section->vma - + input_section->output_offset - + offset); - - if (h->dynindx == -1 - || h->forced_local - || info->executable) - { - /* This symbol is resolved locally. */ - outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); - bfd_put_32 (output_bfd, - (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset), - contents + offset); - } - else - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - - sreloc = htab->elf.irelifunc; - loc = sreloc->contents; - loc += (sreloc->reloc_count++ - * sizeof (Elf32_External_Rel)); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - - /* If this reloc is against an external symbol, we - do not want to fiddle with the addend. Otherwise, - we need to include the symbol value so that it - becomes an addend for the dynamic reloc. For an - internal symbol, we have updated addend. */ - continue; - } - /* FALLTHROUGH */ - case R_386_PC32: - case R_386_PLT32: - goto do_relocation; - - case R_386_GOT32: - base_got = htab->elf.sgot; - off = h->got.offset; - - if (base_got == NULL) - abort (); - - if (off == (bfd_vma) -1) - { - /* We can't use h->got.offset here to save state, or - even just remember the offset, as finish_dynamic_symbol - would use that as offset into .got. */ - - if (htab->elf.splt != NULL) - { - plt_index = h->plt.offset / plt_entry_size - 1; - off = (plt_index + 3) * 4; - base_got = htab->elf.sgotplt; - } - else - { - plt_index = h->plt.offset / plt_entry_size; - off = plt_index * 4; - base_got = htab->elf.igotplt; - } - - if (h->dynindx == -1 - || h->forced_local - || info->symbolic) - { - /* This references the local defitionion. We must - initialize this entry in the global offset table. - Since the offset must always be a multiple of 8, - we use the least significant bit to record - whether we have initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - base_got->contents + off); - h->got.offset |= 1; - } - } - - relocation = off; - - /* Adjust for static executables. */ - if (htab->elf.splt == NULL) - relocation += gotplt->output_offset; - } - else - { - relocation = (base_got->output_section->vma - + base_got->output_offset + off - - gotplt->output_section->vma - - gotplt->output_offset); - /* Adjust for static executables. */ - if (htab->elf.splt == NULL) - relocation += gotplt->output_offset; - } - - goto do_relocation; - - case R_386_GOTOFF: - relocation -= (gotplt->output_section->vma - + gotplt->output_offset); - goto do_relocation; - } - } - - switch (r_type) - { - case R_386_GOT32: - /* Relocation is to the entry for this symbol in the global - offset table. */ - if (htab->elf.sgot == NULL) - abort (); - - if (h != NULL) - { - bfd_boolean dyn; - - off = h->got.offset; - dyn = htab->elf.dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) - || (info->shared - && SYMBOL_REFERENCES_LOCAL (info, h)) - || (ELF_ST_VISIBILITY (h->other) - && h->root.type == bfd_link_hash_undefweak)) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally, or the symbol was forced to be local - because of a version file. We must initialize - this entry in the global offset table. Since the - offset must always be a multiple of 4, we use the - least significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rel.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - htab->elf.sgot->contents + off); - h->got.offset |= 1; - } - } - else - unresolved_reloc = FALSE; - } - else - { - if (local_got_offsets == NULL) - abort (); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - htab->elf.sgot->contents + off); - - if (info->shared) - { - asection *s; - Elf_Internal_Rela outrel; - bfd_byte *loc; - - s = htab->elf.srelgot; - if (s == NULL) - abort (); - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - loc = s->contents; - loc += s->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - } - - local_got_offsets[r_symndx] |= 1; - } - } - - if (off >= (bfd_vma) -2) - abort (); - - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset; - break; - - case R_386_GOTOFF: - /* Relocation is relative to the start of the global offset - table. */ - - /* Check to make sure it isn't a protected function symbol - for shared library since it may not be local when used - as function address. We also need to make sure that a - symbol is defined locally. */ - if (info->shared && h) - { - if (!h->def_regular) - { - const char *v; - - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_HIDDEN: - v = _("hidden symbol"); - break; - case STV_INTERNAL: - v = _("internal symbol"); - break; - case STV_PROTECTED: - v = _("protected symbol"); - break; - default: - v = _("symbol"); - break; - } - - (*_bfd_error_handler) - (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"), - input_bfd, v, h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - else if (!info->executable - && h->type == STT_FUNC - && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) - { - (*_bfd_error_handler) - (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"), - input_bfd, h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - } - - /* Note that sgot is not involved in this - calculation. We always want the start of .got.plt. If we - defined _GLOBAL_OFFSET_TABLE_ in a different way, as is - permitted by the ABI, we might have to change this - calculation. */ - relocation -= htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - break; - - case R_386_GOTPC: - /* Use global offset table as symbol value. */ - relocation = htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - unresolved_reloc = FALSE; - break; - - case R_386_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLT32 reloc against a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt.offset == (bfd_vma) -1 - || htab->elf.splt == NULL) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - relocation = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + h->plt.offset); - unresolved_reloc = FALSE; - break; - - case R_386_32: - case R_386_PC32: - if ((input_section->flags & SEC_ALLOC) == 0 - || is_vxworks_tls) - break; - - if ((info->shared - && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) - && (r_type != R_386_PC32 - || !SYMBOL_CALLS_LOCAL (info, h))) - || (ELIMINATE_COPY_RELOCS - && !info->shared - && h != NULL - && h->dynindx != -1 - && !h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_undefined))) - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - bfd_boolean skip, relocate; - asection *sreloc; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - skip = FALSE; - relocate = FALSE; - - outrel.r_offset = - _bfd_elf_section_offset (output_bfd, info, input_section, - rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1) - skip = TRUE; - else if (outrel.r_offset == (bfd_vma) -2) - skip = TRUE, relocate = TRUE; - outrel.r_offset += (input_section->output_section->vma - + input_section->output_offset); - - if (skip) - memset (&outrel, 0, sizeof outrel); - else if (h != NULL - && h->dynindx != -1 - && (r_type == R_386_PC32 - || !info->shared - || !SYMBOLIC_BIND (info, h) - || !h->def_regular)) - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - else - { - /* This symbol is local, or marked to become local. */ - relocate = TRUE; - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - } - - sreloc = elf_section_data (input_section)->sreloc; - - if (sreloc == NULL || sreloc->contents == NULL) - { - r = bfd_reloc_notsupported; - goto check_relocation_error; - } - - loc = sreloc->contents; - loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel); - - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - - /* If this reloc is against an external symbol, we do - not want to fiddle with the addend. Otherwise, we - need to include the symbol value so that it becomes - an addend for the dynamic reloc. */ - if (! relocate) - continue; - } - break; - - case R_386_TLS_IE: - if (!info->executable) - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - asection *sreloc; - - outrel.r_offset = rel->r_offset - + input_section->output_section->vma - + input_section->output_offset; - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - sreloc = elf_section_data (input_section)->sreloc; - if (sreloc == NULL) - abort (); - loc = sreloc->contents; - loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - } - /* Fall through */ - - case R_386_TLS_GD: - case R_386_TLS_GOTDESC: - case R_386_TLS_DESC_CALL: - case R_386_TLS_IE_32: - case R_386_TLS_GOTIE: - tls_type = GOT_UNKNOWN; - if (h == NULL && local_got_offsets) - tls_type = elf_i386_local_got_tls_type (input_bfd) [r_symndx]; - else if (h != NULL) - tls_type = elf_i386_hash_entry(h)->tls_type; - if (tls_type == GOT_TLS_IE) - tls_type = GOT_TLS_IE_NEG; - - if (! elf_i386_tls_transition (info, input_bfd, - input_section, contents, - symtab_hdr, sym_hashes, - &r_type, tls_type, rel, - relend, h, r_symndx)) - return FALSE; - - if (r_type == R_386_TLS_LE_32) - { - BFD_ASSERT (! unresolved_reloc); - if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD) - { - unsigned int type; - bfd_vma roff; - - /* GD->LE transition. */ - type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); - if (type == 0x04) - { - /* leal foo(,%reg,1), %eax; call ___tls_get_addr - Change it into: - movl %gs:0, %eax; subl $foo@tpoff, %eax - (6 byte form of subl). */ - memcpy (contents + rel->r_offset - 3, - "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12); - roff = rel->r_offset + 5; - } - else - { - /* leal foo(%reg), %eax; call ___tls_get_addr; nop - Change it into: - movl %gs:0, %eax; subl $foo@tpoff, %eax - (6 byte form of subl). */ - memcpy (contents + rel->r_offset - 2, - "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12); - roff = rel->r_offset + 6; - } - bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation), - contents + roff); - /* Skip R_386_PC32/R_386_PLT32. */ - rel++; - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) - { - /* GDesc -> LE transition. - It's originally something like: - leal x@tlsdesc(%ebx), %eax - - leal x@ntpoff, %eax - - Registers other than %eax may be set up here. */ - - unsigned int val; - bfd_vma roff; - - roff = rel->r_offset; - val = bfd_get_8 (input_bfd, contents + roff - 1); - - /* Now modify the instruction as appropriate. */ - /* aoliva FIXME: remove the above and xor the byte - below with 0x86. */ - bfd_put_8 (output_bfd, val ^ 0x86, - contents + roff - 1); - bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation), - contents + roff); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL) - { - /* GDesc -> LE transition. - It's originally: - call *(%eax) - Turn it into: - xchg %ax,%ax */ - - bfd_vma roff; - - roff = rel->r_offset; - bfd_put_8 (output_bfd, 0x66, contents + roff); - bfd_put_8 (output_bfd, 0x90, contents + roff + 1); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE) - { - unsigned int val; - - /* IE->LE transition: - Originally it can be one of: - movl foo, %eax - movl foo, %reg - addl foo, %reg - We change it into: - movl $foo, %eax - movl $foo, %reg - addl $foo, %reg. */ - val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); - if (val == 0xa1) - { - /* movl foo, %eax. */ - bfd_put_8 (output_bfd, 0xb8, - contents + rel->r_offset - 1); - } - else - { - unsigned int type; - - type = bfd_get_8 (input_bfd, - contents + rel->r_offset - 2); - switch (type) - { - case 0x8b: - /* movl */ - bfd_put_8 (output_bfd, 0xc7, - contents + rel->r_offset - 2); - bfd_put_8 (output_bfd, - 0xc0 | ((val >> 3) & 7), - contents + rel->r_offset - 1); - break; - case 0x03: - /* addl */ - bfd_put_8 (output_bfd, 0x81, - contents + rel->r_offset - 2); - bfd_put_8 (output_bfd, - 0xc0 | ((val >> 3) & 7), - contents + rel->r_offset - 1); - break; - default: - BFD_FAIL (); - break; - } - } - bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation), - contents + rel->r_offset); - continue; - } - else - { - unsigned int val, type; - - /* {IE_32,GOTIE}->LE transition: - Originally it can be one of: - subl foo(%reg1), %reg2 - movl foo(%reg1), %reg2 - addl foo(%reg1), %reg2 - We change it into: - subl $foo, %reg2 - movl $foo, %reg2 (6 byte form) - addl $foo, %reg2. */ - type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); - val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); - if (type == 0x8b) - { - /* movl */ - bfd_put_8 (output_bfd, 0xc7, - contents + rel->r_offset - 2); - bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), - contents + rel->r_offset - 1); - } - else if (type == 0x2b) - { - /* subl */ - bfd_put_8 (output_bfd, 0x81, - contents + rel->r_offset - 2); - bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7), - contents + rel->r_offset - 1); - } - else if (type == 0x03) - { - /* addl */ - bfd_put_8 (output_bfd, 0x81, - contents + rel->r_offset - 2); - bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), - contents + rel->r_offset - 1); - } - else - BFD_FAIL (); - if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE) - bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation), - contents + rel->r_offset); - else - bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation), - contents + rel->r_offset); - continue; - } - } - - if (htab->elf.sgot == NULL) - abort (); - - if (h != NULL) - { - off = h->got.offset; - offplt = elf_i386_hash_entry (h)->tlsdesc_got; - } - else - { - if (local_got_offsets == NULL) - abort (); - - off = local_got_offsets[r_symndx]; - offplt = local_tlsdesc_gotents[r_symndx]; - } - - if ((off & 1) != 0) - off &= ~1; - else - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - int dr_type; - asection *sreloc; - - if (htab->elf.srelgot == NULL) - abort (); - - indx = h && h->dynindx != -1 ? h->dynindx : 0; - - if (GOT_TLS_GDESC_P (tls_type)) - { - outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC); - BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8 - <= htab->elf.sgotplt->size); - outrel.r_offset = (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + offplt - + htab->sgotplt_jump_table_size); - sreloc = htab->elf.srelplt; - loc = sreloc->contents; - loc += (htab->next_tls_desc_index++ - * sizeof (Elf32_External_Rel)); - BFD_ASSERT (loc + sizeof (Elf32_External_Rel) - <= sreloc->contents + sreloc->size); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - if (indx == 0) - { - BFD_ASSERT (! unresolved_reloc); - bfd_put_32 (output_bfd, - relocation - elf_i386_dtpoff_base (info), - htab->elf.sgotplt->contents + offplt - + htab->sgotplt_jump_table_size + 4); - } - else - { - bfd_put_32 (output_bfd, 0, - htab->elf.sgotplt->contents + offplt - + htab->sgotplt_jump_table_size + 4); - } - } - - sreloc = htab->elf.srelgot; - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off); - - if (GOT_TLS_GD_P (tls_type)) - dr_type = R_386_TLS_DTPMOD32; - else if (GOT_TLS_GDESC_P (tls_type)) - goto dr_done; - else if (tls_type == GOT_TLS_IE_POS) - dr_type = R_386_TLS_TPOFF; - else - dr_type = R_386_TLS_TPOFF32; - - if (dr_type == R_386_TLS_TPOFF && indx == 0) - bfd_put_32 (output_bfd, - relocation - elf_i386_dtpoff_base (info), - htab->elf.sgot->contents + off); - else if (dr_type == R_386_TLS_TPOFF32 && indx == 0) - bfd_put_32 (output_bfd, - elf_i386_dtpoff_base (info) - relocation, - htab->elf.sgot->contents + off); - else if (dr_type != R_386_TLS_DESC) - bfd_put_32 (output_bfd, 0, - htab->elf.sgot->contents + off); - outrel.r_info = ELF32_R_INFO (indx, dr_type); - - loc = sreloc->contents; - loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel); - BFD_ASSERT (loc + sizeof (Elf32_External_Rel) - <= sreloc->contents + sreloc->size); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - - if (GOT_TLS_GD_P (tls_type)) - { - if (indx == 0) - { - BFD_ASSERT (! unresolved_reloc); - bfd_put_32 (output_bfd, - relocation - elf_i386_dtpoff_base (info), - htab->elf.sgot->contents + off + 4); - } - else - { - bfd_put_32 (output_bfd, 0, - htab->elf.sgot->contents + off + 4); - outrel.r_info = ELF32_R_INFO (indx, - R_386_TLS_DTPOFF32); - outrel.r_offset += 4; - sreloc->reloc_count++; - loc += sizeof (Elf32_External_Rel); - BFD_ASSERT (loc + sizeof (Elf32_External_Rel) - <= sreloc->contents + sreloc->size); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - } - } - else if (tls_type == GOT_TLS_IE_BOTH) - { - bfd_put_32 (output_bfd, - (indx == 0 - ? relocation - elf_i386_dtpoff_base (info) - : 0), - htab->elf.sgot->contents + off + 4); - outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF); - outrel.r_offset += 4; - sreloc->reloc_count++; - loc += sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - } - - dr_done: - if (h != NULL) - h->got.offset |= 1; - else - local_got_offsets[r_symndx] |= 1; - } - - if (off >= (bfd_vma) -2 - && ! GOT_TLS_GDESC_P (tls_type)) - abort (); - if (r_type == R_386_TLS_GOTDESC - || r_type == R_386_TLS_DESC_CALL) - { - relocation = htab->sgotplt_jump_table_size + offplt; - unresolved_reloc = FALSE; - } - else if (r_type == ELF32_R_TYPE (rel->r_info)) - { - bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - g_o_t; - if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE) - && tls_type == GOT_TLS_IE_BOTH) - relocation += 4; - if (r_type == R_386_TLS_IE) - relocation += g_o_t; - unresolved_reloc = FALSE; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD) - { - unsigned int val, type; - bfd_vma roff; - - /* GD->IE transition. */ - type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); - val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); - if (type == 0x04) - { - /* leal foo(,%reg,1), %eax; call ___tls_get_addr - Change it into: - movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax. */ - val >>= 3; - roff = rel->r_offset - 3; - } - else - { - /* leal foo(%reg), %eax; call ___tls_get_addr; nop - Change it into: - movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax. */ - roff = rel->r_offset - 2; - } - memcpy (contents + roff, - "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12); - contents[roff + 7] = 0x80 | (val & 7); - /* If foo is used only with foo@gotntpoff(%reg) and - foo@indntpoff, but not with foo@gottpoff(%reg), change - subl $foo@gottpoff(%reg), %eax - into: - addl $foo@gotntpoff(%reg), %eax. */ - if (tls_type == GOT_TLS_IE_POS) - contents[roff + 6] = 0x03; - bfd_put_32 (output_bfd, - htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset, - contents + roff + 8); - /* Skip R_386_PLT32. */ - rel++; - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC) - { - /* GDesc -> IE transition. - It's originally something like: - leal x@tlsdesc(%ebx), %eax - - Change it to: - movl x@gotntpoff(%ebx), %eax # before xchg %ax,%ax - or: - movl x@gottpoff(%ebx), %eax # before negl %eax - - Registers other than %eax may be set up here. */ - - bfd_vma roff; - - /* First, make sure it's a leal adding ebx to a 32-bit - offset into any register, although it's probably - almost always going to be eax. */ - roff = rel->r_offset; - - /* Now modify the instruction as appropriate. */ - /* To turn a leal into a movl in the form we use it, it - suffices to change the first byte from 0x8d to 0x8b. - aoliva FIXME: should we decide to keep the leal, all - we have to do is remove the statement below, and - adjust the relaxation of R_386_TLS_DESC_CALL. */ - bfd_put_8 (output_bfd, 0x8b, contents + roff - 2); - - if (tls_type == GOT_TLS_IE_BOTH) - off += 4; - - bfd_put_32 (output_bfd, - htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset, - contents + roff); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL) - { - /* GDesc -> IE transition. - It's originally: - call *(%eax) - - Change it to: - xchg %ax,%ax - or - negl %eax - depending on how we transformed the TLS_GOTDESC above. - */ - - bfd_vma roff; - - roff = rel->r_offset; - - /* Now modify the instruction as appropriate. */ - if (tls_type != GOT_TLS_IE_NEG) - { - /* xchg %ax,%ax */ - bfd_put_8 (output_bfd, 0x66, contents + roff); - bfd_put_8 (output_bfd, 0x90, contents + roff + 1); - } - else - { - /* negl %eax */ - bfd_put_8 (output_bfd, 0xf7, contents + roff); - bfd_put_8 (output_bfd, 0xd8, contents + roff + 1); - } - - continue; - } - else - BFD_ASSERT (FALSE); - break; - - case R_386_TLS_LDM: - if (! elf_i386_tls_transition (info, input_bfd, - input_section, contents, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, rel, - relend, h, r_symndx)) - return FALSE; - - if (r_type != R_386_TLS_LDM) - { - /* LD->LE transition: - leal foo(%reg), %eax; call ___tls_get_addr. - We change it into: - movl %gs:0, %eax; nop; leal 0(%esi,1), %esi. */ - BFD_ASSERT (r_type == R_386_TLS_LE_32); - memcpy (contents + rel->r_offset - 2, - "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11); - /* Skip R_386_PC32/R_386_PLT32. */ - rel++; - continue; - } - - if (htab->elf.sgot == NULL) - abort (); - - off = htab->tls_ldm_got.offset; - if (off & 1) - off &= ~1; - else - { - Elf_Internal_Rela outrel; - bfd_byte *loc; - - if (htab->elf.srelgot == NULL) - abort (); - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off); - - bfd_put_32 (output_bfd, 0, - htab->elf.sgot->contents + off); - bfd_put_32 (output_bfd, 0, - htab->elf.sgot->contents + off + 4); - outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32); - loc = htab->elf.srelgot->contents; - loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - htab->tls_ldm_got.offset |= 1; - } - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset; - unresolved_reloc = FALSE; - break; - - case R_386_TLS_LDO_32: - if (!info->executable || (input_section->flags & SEC_CODE) == 0) - relocation -= elf_i386_dtpoff_base (info); - else - /* When converting LDO to LE, we must negate. */ - relocation = -elf_i386_tpoff (info, relocation); - break; - - case R_386_TLS_LE_32: - case R_386_TLS_LE: - if (!info->executable) - { - Elf_Internal_Rela outrel; - asection *sreloc; - bfd_byte *loc; - - outrel.r_offset = rel->r_offset - + input_section->output_section->vma - + input_section->output_offset; - if (h != NULL && h->dynindx != -1) - indx = h->dynindx; - else - indx = 0; - if (r_type == R_386_TLS_LE_32) - outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32); - else - outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF); - sreloc = elf_section_data (input_section)->sreloc; - if (sreloc == NULL) - abort (); - loc = sreloc->contents; - loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); - if (indx) - continue; - else if (r_type == R_386_TLS_LE_32) - relocation = elf_i386_dtpoff_base (info) - relocation; - else - relocation -= elf_i386_dtpoff_base (info); - } - else if (r_type == R_386_TLS_LE_32) - relocation = elf_i386_tpoff (info, relocation); - else - relocation = -elf_i386_tpoff (info, relocation); - break; - - default: - break; - } - - /* Dynamic relocs are not propagated for SEC_DEBUGGING sections - because such sections are not SEC_ALLOC and thus ld.so will - not process them. */ - if (unresolved_reloc - && !((input_section->flags & SEC_DEBUGGING) != 0 - && h->def_dynamic)) - { - (*_bfd_error_handler) - (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), - input_bfd, - input_section, - (long) rel->r_offset, - howto->name, - h->root.root.string); - return FALSE; - } - -do_relocation: - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, 0); - -check_relocation_error: - if (r != bfd_reloc_ok) - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return FALSE; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - - if (r == bfd_reloc_overflow) - { - if (! ((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, howto->name, - (bfd_vma) 0, input_bfd, input_section, - rel->r_offset))) - return FALSE; - } - else - { - (*_bfd_error_handler) - (_("%B(%A+0x%lx): reloc against `%s': error %d"), - input_bfd, input_section, - (long) rel->r_offset, name, (int) r); - return FALSE; - } - } - } - - return TRUE; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static bfd_boolean -elf_i386_finish_dynamic_symbol (bfd *output_bfd, - struct bfd_link_info *info, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - struct elf_i386_link_hash_table *htab; - unsigned plt_entry_size; - const struct elf_i386_backend_data *abed; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - abed = get_elf_i386_backend_data (output_bfd); - plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd); - - if (h->plt.offset != (bfd_vma) -1) - { - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rela rel; - bfd_byte *loc; - asection *plt, *gotplt, *relplt; - - /* When building a static executable, use .iplt, .igot.plt and - .rel.iplt sections for STT_GNU_IFUNC symbols. */ - if (htab->elf.splt != NULL) - { - plt = htab->elf.splt; - gotplt = htab->elf.sgotplt; - relplt = htab->elf.srelplt; - } - else - { - plt = htab->elf.iplt; - gotplt = htab->elf.igotplt; - relplt = htab->elf.irelplt; - } - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - if ((h->dynindx == -1 - && !((h->forced_local || info->executable) - && h->def_regular - && h->type == STT_GNU_IFUNC)) - || plt == NULL - || gotplt == NULL - || relplt == NULL) - return FALSE; - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. - - Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. - - For static executables, we don't reserve anything. */ - - if (plt == htab->elf.splt) - { - plt_index = h->plt.offset / plt_entry_size - 1; - got_offset = (plt_index + 3) * 4; - } - else - { - plt_index = h->plt.offset / plt_entry_size; - got_offset = plt_index * 4; - } - - /* Fill in the entry in the procedure linkage table. */ - if (! info->shared) - { - memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry, - abed->plt->plt_entry_size); - bfd_put_32 (output_bfd, - (gotplt->output_section->vma - + gotplt->output_offset - + got_offset), - plt->contents + h->plt.offset - + abed->plt->plt_got_offset); - - if (abed->is_vxworks) - { - int s, k, reloc_index; - - /* Create the R_386_32 relocation referencing the GOT - for this PLT entry. */ - - /* S: Current slot number (zero-based). */ - s = ((h->plt.offset - abed->plt->plt_entry_size) - / abed->plt->plt_entry_size); - /* K: Number of relocations for PLTResolve. */ - if (info->shared) - k = PLTRESOLVE_RELOCS_SHLIB; - else - k = PLTRESOLVE_RELOCS; - /* Skip the PLTresolve relocations, and the relocations for - the other PLT slots. */ - reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS; - loc = (htab->srelplt2->contents + reloc_index - * sizeof (Elf32_External_Rel)); - - rel.r_offset = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + h->plt.offset + 2), - rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); - - /* Create the R_386_32 relocation referencing the beginning of - the PLT for this GOT entry. */ - rel.r_offset = (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + got_offset); - rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - loc + sizeof (Elf32_External_Rel)); - } - } - else - { - memcpy (plt->contents + h->plt.offset, abed->plt->pic_plt_entry, - abed->plt->plt_entry_size); - bfd_put_32 (output_bfd, got_offset, - plt->contents + h->plt.offset - + abed->plt->plt_got_offset); - } - - /* Don't fill PLT entry for static executables. */ - if (plt == htab->elf.splt) - { - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - plt->contents + h->plt.offset - + abed->plt->plt_reloc_offset); - bfd_put_32 (output_bfd, - (h->plt.offset - + abed->plt->plt_plt_offset + 4), - plt->contents + h->plt.offset - + abed->plt->plt_plt_offset); - } - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (plt->output_section->vma - + plt->output_offset - + h->plt.offset - + abed->plt->plt_lazy_offset), - gotplt->contents + got_offset); - - /* Fill in the entry in the .rel.plt section. */ - rel.r_offset = (gotplt->output_section->vma - + gotplt->output_offset - + got_offset); - if (h->dynindx == -1 - || ((info->executable - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular - && h->type == STT_GNU_IFUNC)) - { - /* If an STT_GNU_IFUNC symbol is locally defined, generate - R_386_IRELATIVE instead of R_386_JUMP_SLOT. Store addend - in the .got.plt section. */ - bfd_put_32 (output_bfd, - (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset), - gotplt->contents + got_offset); - rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE); - } - else - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); - loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); - - if (!h->def_regular) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value if there were any - relocations where pointer equality matters (this is a clue - for the dynamic linker, to make function pointer - comparisons work between an application and shared - library), otherwise set it to zero. If a function is only - called from a binary, there is no need to slow down - shared libraries because of that. */ - sym->st_shndx = SHN_UNDEF; - if (!h->pointer_equality_needed) - sym->st_value = 0; - } - } - - if (h->got.offset != (bfd_vma) -1 - && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type) - && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0) - { - Elf_Internal_Rela rel; - bfd_byte *loc; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL) - abort (); - - rel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + (h->got.offset & ~(bfd_vma) 1)); - - /* If this is a static link, or it is a -Bsymbolic link and the - symbol is defined locally or was forced to be local because - of a version file, we just want to emit a RELATIVE reloc. - The entry in the global offset table will already have been - initialized in the relocate_section function. */ - if (h->def_regular - && h->type == STT_GNU_IFUNC) - { - if (info->shared) - { - /* Generate R_386_GLOB_DAT. */ - goto do_glob_dat; - } - else - { - asection *plt; - - if (!h->pointer_equality_needed) - abort (); - - /* For non-shared object, we can't use .got.plt, which - contains the real function addres if we need pointer - equality. We load the GOT entry with the PLT entry. */ - plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; - bfd_put_32 (output_bfd, - (plt->output_section->vma - + plt->output_offset + h->plt.offset), - htab->elf.sgot->contents + h->got.offset); - return TRUE; - } - } - else if (info->shared - && SYMBOL_REFERENCES_LOCAL (info, h)) - { - BFD_ASSERT((h->got.offset & 1) != 0); - rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - } - else - { - BFD_ASSERT((h->got.offset & 1) == 0); -do_glob_dat: - bfd_put_32 (output_bfd, (bfd_vma) 0, - htab->elf.sgot->contents + h->got.offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); - } - - loc = htab->elf.srelgot->contents; - loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); - } - - if (h->needs_copy) - { - Elf_Internal_Rela rel; - bfd_byte *loc; - - /* This symbol needs a copy reloc. Set it up. */ - - if (h->dynindx == -1 - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - || htab->srelbss == NULL) - abort (); - - rel.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY); - loc = htab->srelbss->contents; - loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rel); - bfd_elf32_swap_reloc_out (output_bfd, &rel, loc); - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may - be NULL for local symbols. - - On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it - is relative to the ".got" section. */ - if (sym != NULL - && (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || (!abed->is_vxworks - && h == htab->elf.hgot))) - sym->st_shndx = SHN_ABS; - - return TRUE; -} - -/* Finish up local dynamic symbol handling. We set the contents of - various dynamic sections here. */ - -static bfd_boolean -elf_i386_finish_local_dynamic_symbol (void **slot, void *inf) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) *slot; - struct bfd_link_info *info - = (struct bfd_link_info *) inf; - - return elf_i386_finish_dynamic_symbol (info->output_bfd, info, - h, NULL); -} - -/* Used to decide how to sort relocs in an optimal manner for the - dynamic linker, before writing them out. */ - -static enum elf_reloc_type_class -elf_i386_reloc_type_class (const Elf_Internal_Rela *rela) -{ - switch (ELF32_R_TYPE (rela->r_info)) - { - case R_386_RELATIVE: - return reloc_class_relative; - case R_386_JUMP_SLOT: - return reloc_class_plt; - case R_386_COPY: - return reloc_class_copy; - default: - return reloc_class_normal; - } -} - -/* Finish up the dynamic sections. */ - -static bfd_boolean -elf_i386_finish_dynamic_sections (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_i386_link_hash_table *htab; - bfd *dynobj; - asection *sdyn; - const struct elf_i386_backend_data *abed; - - htab = elf_i386_hash_table (info); - if (htab == NULL) - return FALSE; - - dynobj = htab->elf.dynobj; - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - abed = get_elf_i386_backend_data (output_bfd); - - if (htab->elf.dynamic_sections_created) - { - Elf32_External_Dyn *dyncon, *dynconend; - - if (sdyn == NULL || htab->elf.sgot == NULL) - abort (); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - if (abed->is_vxworks - && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn)) - break; - continue; - - case DT_PLTGOT: - s = htab->elf.sgotplt; - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; - break; - - case DT_JMPREL: - s = htab->elf.srelplt; - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; - break; - - case DT_PLTRELSZ: - s = htab->elf.srelplt; - dyn.d_un.d_val = s->size; - break; - - case DT_RELSZ: - /* My reading of the SVR4 ABI indicates that the - procedure linkage table relocs (DT_JMPREL) should be - included in the overall relocs (DT_REL). This is - what Solaris does. However, UnixWare can not handle - that case. Therefore, we override the DT_RELSZ entry - here to make it not include the JMPREL relocs. */ - s = htab->elf.srelplt; - if (s == NULL) - continue; - dyn.d_un.d_val -= s->size; - break; - - case DT_REL: - /* We may not be using the standard ELF linker script. - If .rel.plt is the first .rel section, we adjust - DT_REL to not include it. */ - s = htab->elf.srelplt; - if (s == NULL) - continue; - if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset) - continue; - dyn.d_un.d_ptr += s->size; - break; - } - - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - - /* Fill in the first entry in the procedure linkage table. */ - if (htab->elf.splt && htab->elf.splt->size > 0) - { - if (info->shared) - { - memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry, - abed->plt->plt0_entry_size); - memset (htab->elf.splt->contents + abed->plt->plt0_entry_size, - abed->plt0_pad_byte, - abed->plt->plt_entry_size - abed->plt->plt0_entry_size); - } - else - { - memcpy (htab->elf.splt->contents, abed->plt->plt0_entry, - abed->plt->plt0_entry_size); - memset (htab->elf.splt->contents + abed->plt->plt0_entry_size, - abed->plt0_pad_byte, - abed->plt->plt_entry_size - abed->plt->plt0_entry_size); - bfd_put_32 (output_bfd, - (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + 4), - htab->elf.splt->contents - + abed->plt->plt0_got1_offset); - bfd_put_32 (output_bfd, - (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + 8), - htab->elf.splt->contents - + abed->plt->plt0_got2_offset); - - if (abed->is_vxworks) - { - Elf_Internal_Rela rel; - - /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4. - On IA32 we use REL relocations so the addend goes in - the PLT directly. */ - rel.r_offset = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + abed->plt->plt0_got1_offset); - rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - htab->srelplt2->contents); - /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8. */ - rel.r_offset = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + abed->plt->plt0_got2_offset); - rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - htab->srelplt2->contents + - sizeof (Elf32_External_Rel)); - } - } - - /* UnixWare sets the entsize of .plt to 4, although that doesn't - really seem like the right value. */ - elf_section_data (htab->elf.splt->output_section) - ->this_hdr.sh_entsize = 4; - - /* Correct the .rel.plt.unloaded relocations. */ - if (abed->is_vxworks && !info->shared) - { - int num_plts = (htab->elf.splt->size - / abed->plt->plt_entry_size) - 1; - unsigned char *p; - - p = htab->srelplt2->contents; - if (info->shared) - p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel); - else - p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel); - - for (; num_plts; num_plts--) - { - Elf_Internal_Rela rel; - bfd_elf32_swap_reloc_in (output_bfd, p, &rel); - rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, p); - p += sizeof (Elf32_External_Rel); - - bfd_elf32_swap_reloc_in (output_bfd, p, &rel); - rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32); - bfd_elf32_swap_reloc_out (output_bfd, &rel, p); - p += sizeof (Elf32_External_Rel); - } - } - } - } - - if (htab->elf.sgotplt) - { - if (bfd_is_abs_section (htab->elf.sgotplt->output_section)) - { - (*_bfd_error_handler) - (_("discarded output section: `%A'"), htab->elf.sgotplt); - return FALSE; - } - - /* Fill in the first three entries in the global offset table. */ - if (htab->elf.sgotplt->size > 0) - { - bfd_put_32 (output_bfd, - (sdyn == NULL ? 0 - : sdyn->output_section->vma + sdyn->output_offset), - htab->elf.sgotplt->contents); - bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4); - bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8); - } - - elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4; - } - - /* Adjust .eh_frame for .plt section. */ - if (htab->plt_eh_frame != NULL) - { - if (htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && (htab->elf.splt->flags & SEC_EXCLUDE) == 0 - && htab->elf.splt->output_section != NULL - && htab->plt_eh_frame->output_section != NULL) - { - bfd_vma plt_start = htab->elf.splt->output_section->vma; - bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma - + htab->plt_eh_frame->output_offset - + PLT_FDE_START_OFFSET; - bfd_put_signed_32 (dynobj, plt_start - eh_frame_start, - htab->plt_eh_frame->contents - + PLT_FDE_START_OFFSET); - } - if (htab->plt_eh_frame->sec_info_type - == ELF_INFO_TYPE_EH_FRAME) - { - if (! _bfd_elf_write_section_eh_frame (output_bfd, info, - htab->plt_eh_frame, - htab->plt_eh_frame->contents)) - return FALSE; - } - } - - if (htab->elf.sgot && htab->elf.sgot->size > 0) - elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4; - - /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ - htab_traverse (htab->loc_hash_table, - elf_i386_finish_local_dynamic_symbol, - info); - - return TRUE; -} - -/* Return address for Ith PLT stub in section PLT, for relocation REL - or (bfd_vma) -1 if it should not be included. */ - -static bfd_vma -elf_i386_plt_sym_val (bfd_vma i, const asection *plt, - const arelent *rel ATTRIBUTE_UNUSED) -{ - return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner); -} - -/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ - -static bfd_boolean -elf_i386_hash_symbol (struct elf_link_hash_entry *h) -{ - if (h->plt.offset != (bfd_vma) -1 - && !h->def_regular - && !h->pointer_equality_needed) - return FALSE; - - return _bfd_elf_hash_symbol (h); -} - -/* Hook called by the linker routine which adds symbols from an object - file. */ - -static bfd_boolean -elf_i386_add_symbol_hook (bfd * abfd, - struct bfd_link_info * info ATTRIBUTE_UNUSED, - Elf_Internal_Sym * sym, - const char ** namep ATTRIBUTE_UNUSED, - flagword * flagsp ATTRIBUTE_UNUSED, - asection ** secp ATTRIBUTE_UNUSED, - bfd_vma * valp ATTRIBUTE_UNUSED) -{ - if ((abfd->flags & DYNAMIC) == 0 - && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC - || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)) - elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE; - - return TRUE; -} - -#define TARGET_LITTLE_SYM bfd_elf32_i386_vec -#define TARGET_LITTLE_NAME "elf32-i386" -#define ELF_ARCH bfd_arch_i386 -#define ELF_TARGET_ID I386_ELF_DATA -#define ELF_MACHINE_CODE EM_386 -#define ELF_MAXPAGESIZE 0x1000 - -#define elf_backend_can_gc_sections 1 -#define elf_backend_can_refcount 1 -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 -#define elf_backend_got_header_size 12 -#define elf_backend_plt_alignment 4 - -/* Support RELA for objdump of prelink objects. */ -#define elf_info_to_howto elf_i386_info_to_howto_rel -#define elf_info_to_howto_rel elf_i386_info_to_howto_rel - -#define bfd_elf32_mkobject elf_i386_mkobject - -#define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name -#define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free elf_i386_link_hash_table_free -#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup -#define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup - -#define elf_backend_adjust_dynamic_symbol elf_i386_adjust_dynamic_symbol -#define elf_backend_relocs_compatible _bfd_elf_relocs_compatible -#define elf_backend_check_relocs elf_i386_check_relocs -#define elf_backend_copy_indirect_symbol elf_i386_copy_indirect_symbol -#define elf_backend_create_dynamic_sections elf_i386_create_dynamic_sections -#define elf_backend_fake_sections elf_i386_fake_sections -#define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections -#define elf_backend_finish_dynamic_symbol elf_i386_finish_dynamic_symbol -#define elf_backend_gc_mark_hook elf_i386_gc_mark_hook -#define elf_backend_gc_sweep_hook elf_i386_gc_sweep_hook -#define elf_backend_grok_prstatus elf_i386_grok_prstatus -#define elf_backend_grok_psinfo elf_i386_grok_psinfo -#define elf_backend_reloc_type_class elf_i386_reloc_type_class -#define elf_backend_relocate_section elf_i386_relocate_section -#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections -#define elf_backend_always_size_sections elf_i386_always_size_sections -#define elf_backend_omit_section_dynsym \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) -#define elf_backend_plt_sym_val elf_i386_plt_sym_val -#define elf_backend_hash_symbol elf_i386_hash_symbol -#define elf_backend_add_symbol_hook elf_i386_add_symbol_hook -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers _bfd_elf_set_osabi - -#include "elf32-target.h" - -/* FreeBSD support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_freebsd_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-i386-freebsd" -#undef ELF_OSABI -#define ELF_OSABI ELFOSABI_FREEBSD - -/* The kernel recognizes executables as valid only if they carry a - "FreeBSD" label in the ELF header. So we put this label on all - executables and (for simplicity) also all other object files. */ - -static void -elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) -{ - _bfd_elf_set_osabi (abfd, info); - -#ifdef OLD_FREEBSD_ABI_LABEL - /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ - memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); -#endif -} - -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers elf_i386_fbsd_post_process_headers -#undef elf32_bed -#define elf32_bed elf32_i386_fbsd_bed - -#undef elf_backend_add_symbol_hook - -#include "elf32-target.h" - -/* Solaris 2. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_sol2_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-i386-sol2" - -/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE - objects won't be recognized. */ -#undef ELF_OSABI - -#undef elf32_bed -#define elf32_bed elf32_i386_sol2_bed - -/* The 32-bit static TLS arena size is rounded to the nearest 8-byte - boundary. */ -#undef elf_backend_static_tls_alignment -#define elf_backend_static_tls_alignment 8 - -/* The Solaris 2 ABI requires a plt symbol on all platforms. - - Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output - File, p.63. */ -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 1 - -#include "elf32-target.h" - -/* Native Client support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_nacl_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-i386-nacl" -#undef elf32_bed -#define elf32_bed elf32_i386_nacl_bed - -#undef ELF_MAXPAGESIZE -#define ELF_MAXPAGESIZE 0x10000 - -/* Restore defaults. */ -#undef ELF_OSABI -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers _bfd_elf_set_osabi -#undef elf_backend_static_tls_alignment - -/* NaCl uses substantially different PLT entries for the same effects. */ - -#undef elf_backend_plt_alignment -#define elf_backend_plt_alignment 5 -#define NACL_PLT_ENTRY_SIZE 64 -#define NACLMASK 0xe0 /* 32-byte alignment mask. */ - -static const bfd_byte elf_i386_nacl_plt0_entry[] = - { - 0xff, 0x35, /* pushl contents of address */ - 0, 0, 0, 0, /* replaced with address of .got + 4. */ - 0x8b, 0x0d, /* movl contents of address, %ecx */ - 0, 0, 0, 0, /* replaced with address of .got + 8. */ - 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */ - 0xff, 0xe1 /* jmp *%ecx */ - }; - -static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] = - { - 0x8b, 0x0d, /* movl contents of address, %ecx */ - 0, 0, 0, 0, /* replaced with GOT slot address. */ - 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */ - 0xff, 0xe1, /* jmp *%ecx */ - - /* Pad to the next 32-byte boundary with nop instructions. */ - 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - - /* Lazy GOT entries point here (32-byte aligned). */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with reloc offset. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0, /* replaced with offset to .plt. */ - - /* Pad to the next 32-byte boundary with nop instructions. */ - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90 - }; - -static const bfd_byte -elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] = - { - 0xff, 0x73, 0x04, /* pushl 4(%ebx) */ - 0x8b, 0x4b, 0x08, /* mov 0x8(%ebx), %ecx */ - 0x83, 0xe1, 0xe0, /* and $NACLMASK, %ecx */ - 0xff, 0xe1, /* jmp *%ecx */ - 0x90 /* nop */ - }; - -static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] = - { - 0x8b, 0x8b, /* movl offset(%ebx), %ecx */ - 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ - 0x83, 0xe1, 0xe0, /* andl $NACLMASK, %ecx */ - 0xff, 0xe1, /* jmp *%ecx */ - - /* Pad to the next 32-byte boundary with nop instructions. */ - 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - - /* Lazy GOT entries point here (32-byte aligned). */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0, /* replaced with offset to start of .plt. */ - - /* Pad to the next 32-byte boundary with nop instructions. */ - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90 - }; - -static const bfd_byte elf_i386_nacl_eh_frame_plt[] = - { -#if (PLT_CIE_LENGTH != 20 \ - || PLT_FDE_LENGTH != 36 \ - || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \ - || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12) -# error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!" -#endif - PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ - 0, 0, 0, 0, /* CIE ID */ - 1, /* CIE version */ - 'z', 'R', 0, /* Augmentation string */ - 1, /* Code alignment factor */ - 0x7c, /* Data alignment factor: -4 */ - 8, /* Return address column */ - 1, /* Augmentation size */ - DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ - DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */ - DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */ - DW_CFA_nop, DW_CFA_nop, - - PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ - PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ - 0, 0, 0, 0, /* R_386_PC32 .plt goes here */ - 0, 0, 0, 0, /* .plt size goes here */ - 0, /* Augmentation size */ - DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */ - DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ - DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */ - DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */ - DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ - 13, /* Block length */ - DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */ - DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */ - DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge, - DW_OP_lit2, DW_OP_shl, DW_OP_plus, - DW_CFA_nop, DW_CFA_nop - }; - -static const struct elf_i386_plt_layout elf_i386_nacl_plt = - { - elf_i386_nacl_plt0_entry, /* plt0_entry */ - sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */ - 2, /* plt0_got1_offset */ - 8, /* plt0_got2_offset */ - elf_i386_nacl_plt_entry, /* plt_entry */ - NACL_PLT_ENTRY_SIZE, /* plt_entry_size */ - 2, /* plt_got_offset */ - 33, /* plt_reloc_offset */ - 38, /* plt_plt_offset */ - 32, /* plt_lazy_offset */ - elf_i386_nacl_pic_plt0_entry, /* pic_plt0_entry */ - elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */ - elf_i386_nacl_eh_frame_plt, /* eh_frame_plt */ - sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */ - }; - -static const struct elf_i386_backend_data elf_i386_nacl_arch_bed = - { - &elf_i386_nacl_plt, /* plt */ - 0x90, /* plt0_pad_byte: nop insn */ - 0, /* is_vxworks */ - }; - -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_nacl_arch_bed - -#include "elf32-target.h" - -/* VxWorks support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_i386_vxworks_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-i386-vxworks" -#undef ELF_OSABI -#undef elf_backend_plt_alignment -#define elf_backend_plt_alignment 4 - -static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed = - { - &elf_i386_plt, /* plt */ - 0x90, /* plt0_pad_byte */ - 1, /* is_vxworks */ - }; - -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_vxworks_arch_bed - -#undef elf_backend_relocs_compatible -#undef elf_backend_post_process_headers -#undef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook \ - elf_vxworks_add_symbol_hook -#undef elf_backend_link_output_symbol_hook -#define elf_backend_link_output_symbol_hook \ - elf_vxworks_link_output_symbol_hook -#undef elf_backend_emit_relocs -#define elf_backend_emit_relocs elf_vxworks_emit_relocs -#undef elf_backend_final_write_processing -#define elf_backend_final_write_processing \ - elf_vxworks_final_write_processing -#undef elf_backend_static_tls_alignment - -/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so - define it. */ -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 1 - -#undef elf32_bed -#define elf32_bed elf32_i386_vxworks_bed - -#include "elf32-target.h" diff --git a/contrib/binutils-2.22/bfd/elf32.c b/contrib/binutils-2.22/bfd/elf32.c deleted file mode 100644 index 98dacc1f36..0000000000 --- a/contrib/binutils-2.22/bfd/elf32.c +++ /dev/null @@ -1,24 +0,0 @@ -/* ELF 32-bit executable support for BFD. - Copyright 1993, 2001, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#define ARCH_SIZE 32 - -#include "elfcode.h" diff --git a/contrib/binutils-2.22/bfd/elf64-gen.c b/contrib/binutils-2.22/bfd/elf64-gen.c deleted file mode 100644 index 1b0dadebe6..0000000000 --- a/contrib/binutils-2.22/bfd/elf64-gen.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Generic support for 64-bit ELF - Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2004, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocation information, but should be - good enough for GDB or objdump to read the file. */ - -static reloc_howto_type dummy = - HOWTO (0, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "UNKNOWN", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE); /* pcrel_offset */ - -static void -elf_generic_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, - arelent *bfd_reloc, - Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED) -{ - bfd_reloc->howto = &dummy; -} - -static void -elf_generic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, - arelent *bfd_reloc, - Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED) -{ - bfd_reloc->howto = &dummy; -} - -static void -check_for_relocs (bfd * abfd, asection * o, void * failed) -{ - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Ehdr *ehdrp; - - ehdrp = elf_elfheader (abfd); - _bfd_error_handler (_("%B: Relocations in generic ELF (EM: %d)"), - abfd, ehdrp->e_machine); - - bfd_set_error (bfd_error_wrong_format); - * (bfd_boolean *) failed = TRUE; - } -} - -static bfd_boolean -elf64_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean failed = FALSE; - - /* Check if there are any relocations. */ - bfd_map_over_sections (abfd, check_for_relocs, & failed); - - if (failed) - return FALSE; - return bfd_elf_link_add_symbols (abfd, info); -} - -#define TARGET_LITTLE_SYM bfd_elf64_little_generic_vec -#define TARGET_LITTLE_NAME "elf64-little" -#define TARGET_BIG_SYM bfd_elf64_big_generic_vec -#define TARGET_BIG_NAME "elf64-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define ELF_MAXPAGESIZE 0x1 -#define bfd_elf64_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define bfd_elf64_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup -#define bfd_elf64_bfd_link_add_symbols elf64_generic_link_add_symbols -#define elf_info_to_howto elf_generic_info_to_howto -#define elf_info_to_howto_rel elf_generic_info_to_howto_rel - -#include "elf64-target.h" diff --git a/contrib/binutils-2.22/bfd/elf64-x86-64.c b/contrib/binutils-2.22/bfd/elf64-x86-64.c deleted file mode 100644 index 3a2444b90c..0000000000 --- a/contrib/binutils-2.22/bfd/elf64-x86-64.c +++ /dev/null @@ -1,5156 +0,0 @@ -/* X86-64 specific support for ELF - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2011 - Free Software Foundation, Inc. - Contributed by Jan Hubicka . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "bfd_stdint.h" -#include "objalloc.h" -#include "hashtab.h" -#include "dwarf2.h" -#include "libiberty.h" - -#include "elf/x86-64.h" - -#ifdef CORE_HEADER -#include -#include CORE_HEADER -#endif - -/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */ -#define MINUS_ONE (~ (bfd_vma) 0) - -/* Since both 32-bit and 64-bit x86-64 encode relocation type in the - identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get - relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE - since they are the same. */ - -#define ABI_64_P(abfd) \ - (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) - -/* The relocation "howto" table. Order of fields: - type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow, - special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */ -static reloc_howto_type x86_64_elf_howto_table[] = -{ - HOWTO(R_X86_64_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont, - bfd_elf_generic_reloc, "R_X86_64_NONE", FALSE, 0x00000000, 0x00000000, - FALSE), - HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE, - FALSE), - HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff, - TRUE), - HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff, - FALSE), - HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff, - TRUE), - HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff, - FALSE), - HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff, - 0xffffffff, TRUE), - HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned, - bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff, - FALSE), - HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff, - FALSE), - HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE), - HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE), - HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE), - HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE), - HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff, - 0xffffffff, TRUE), - HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff, - 0xffffffff, TRUE), - HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff, - 0xffffffff, FALSE), - HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff, - 0xffffffff, TRUE), - HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff, - 0xffffffff, FALSE), - HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE, - TRUE), - HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", - FALSE, MINUS_ONE, MINUS_ONE, FALSE), - HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPC32", - FALSE, 0xffffffff, 0xffffffff, TRUE), - HOWTO(R_X86_64_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOT64", FALSE, MINUS_ONE, MINUS_ONE, - FALSE), - HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", FALSE, MINUS_ONE, - MINUS_ONE, TRUE), - HOWTO(R_X86_64_GOTPC64, 0, 4, 64, TRUE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPC64", - FALSE, MINUS_ONE, MINUS_ONE, TRUE), - HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed, - bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - EMPTY_HOWTO (32), - EMPTY_HOWTO (33), - HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0, - complain_overflow_bitfield, bfd_elf_generic_reloc, - "R_X86_64_GOTPC32_TLSDESC", - FALSE, 0xffffffff, 0xffffffff, TRUE), - HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0, - complain_overflow_dont, bfd_elf_generic_reloc, - "R_X86_64_TLSDESC_CALL", - FALSE, 0, 0, FALSE), - HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0, - complain_overflow_bitfield, bfd_elf_generic_reloc, - "R_X86_64_TLSDESC", - FALSE, MINUS_ONE, MINUS_ONE, FALSE), - HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE, - MINUS_ONE, FALSE), - - /* We have a gap in the reloc numbers here. - R_X86_64_standard counts the number up to this point, and - R_X86_64_vt_offset is the value to subtract from a reloc type of - R_X86_64_GNU_VT* to form an index into this table. */ -#define R_X86_64_standard (R_X86_64_IRELATIVE + 1) -#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard) - -/* GNU extension to record C++ vtable hierarchy. */ - HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont, - NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE), - -/* GNU extension to record C++ vtable member usage. */ - HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont, - _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0, - FALSE), - -/* Use complain_overflow_bitfield on R_X86_64_32 for x32. */ - HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff, - FALSE) -}; - -#define IS_X86_64_PCREL_TYPE(TYPE) \ - ( ((TYPE) == R_X86_64_PC8) \ - || ((TYPE) == R_X86_64_PC16) \ - || ((TYPE) == R_X86_64_PC32) \ - || ((TYPE) == R_X86_64_PC64)) - -/* Map BFD relocs to the x86_64 elf relocs. */ -struct elf_reloc_map -{ - bfd_reloc_code_real_type bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static const struct elf_reloc_map x86_64_reloc_map[] = -{ - { BFD_RELOC_NONE, R_X86_64_NONE, }, - { BFD_RELOC_64, R_X86_64_64, }, - { BFD_RELOC_32_PCREL, R_X86_64_PC32, }, - { BFD_RELOC_X86_64_GOT32, R_X86_64_GOT32,}, - { BFD_RELOC_X86_64_PLT32, R_X86_64_PLT32,}, - { BFD_RELOC_X86_64_COPY, R_X86_64_COPY, }, - { BFD_RELOC_X86_64_GLOB_DAT, R_X86_64_GLOB_DAT, }, - { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, }, - { BFD_RELOC_X86_64_RELATIVE, R_X86_64_RELATIVE, }, - { BFD_RELOC_X86_64_GOTPCREL, R_X86_64_GOTPCREL, }, - { BFD_RELOC_32, R_X86_64_32, }, - { BFD_RELOC_X86_64_32S, R_X86_64_32S, }, - { BFD_RELOC_16, R_X86_64_16, }, - { BFD_RELOC_16_PCREL, R_X86_64_PC16, }, - { BFD_RELOC_8, R_X86_64_8, }, - { BFD_RELOC_8_PCREL, R_X86_64_PC8, }, - { BFD_RELOC_X86_64_DTPMOD64, R_X86_64_DTPMOD64, }, - { BFD_RELOC_X86_64_DTPOFF64, R_X86_64_DTPOFF64, }, - { BFD_RELOC_X86_64_TPOFF64, R_X86_64_TPOFF64, }, - { BFD_RELOC_X86_64_TLSGD, R_X86_64_TLSGD, }, - { BFD_RELOC_X86_64_TLSLD, R_X86_64_TLSLD, }, - { BFD_RELOC_X86_64_DTPOFF32, R_X86_64_DTPOFF32, }, - { BFD_RELOC_X86_64_GOTTPOFF, R_X86_64_GOTTPOFF, }, - { BFD_RELOC_X86_64_TPOFF32, R_X86_64_TPOFF32, }, - { BFD_RELOC_64_PCREL, R_X86_64_PC64, }, - { BFD_RELOC_X86_64_GOTOFF64, R_X86_64_GOTOFF64, }, - { BFD_RELOC_X86_64_GOTPC32, R_X86_64_GOTPC32, }, - { BFD_RELOC_X86_64_GOT64, R_X86_64_GOT64, }, - { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, }, - { BFD_RELOC_X86_64_GOTPC64, R_X86_64_GOTPC64, }, - { BFD_RELOC_X86_64_GOTPLT64, R_X86_64_GOTPLT64, }, - { BFD_RELOC_X86_64_PLTOFF64, R_X86_64_PLTOFF64, }, - { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, }, - { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, }, - { BFD_RELOC_X86_64_TLSDESC, R_X86_64_TLSDESC, }, - { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, }, - { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, - { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, -}; - -static reloc_howto_type * -elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type) -{ - unsigned i; - - if (r_type == (unsigned int) R_X86_64_32) - { - if (ABI_64_P (abfd)) - i = r_type; - else - i = ARRAY_SIZE (x86_64_elf_howto_table) - 1; - } - else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT - || r_type >= (unsigned int) R_X86_64_max) - { - if (r_type >= (unsigned int) R_X86_64_standard) - { - (*_bfd_error_handler) (_("%B: invalid relocation type %d"), - abfd, (int) r_type); - r_type = R_X86_64_NONE; - } - i = r_type; - } - else - i = r_type - (unsigned int) R_X86_64_vt_offset; - BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type); - return &x86_64_elf_howto_table[i]; -} - -/* Given a BFD reloc type, return a HOWTO structure. */ -static reloc_howto_type * -elf_x86_64_reloc_type_lookup (bfd *abfd, - bfd_reloc_code_real_type code) -{ - unsigned int i; - - for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map); - i++) - { - if (x86_64_reloc_map[i].bfd_reloc_val == code) - return elf_x86_64_rtype_to_howto (abfd, - x86_64_reloc_map[i].elf_reloc_val); - } - return 0; -} - -static reloc_howto_type * -elf_x86_64_reloc_name_lookup (bfd *abfd, - const char *r_name) -{ - unsigned int i; - - if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0) - { - /* Get x32 R_X86_64_32. */ - reloc_howto_type *reloc - = &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1]; - BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32); - return reloc; - } - - for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++) - if (x86_64_elf_howto_table[i].name != NULL - && strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0) - return &x86_64_elf_howto_table[i]; - - return NULL; -} - -/* Given an x86_64 ELF reloc type, fill in an arelent structure. */ - -static void -elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, - Elf_Internal_Rela *dst) -{ - unsigned r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type); - BFD_ASSERT (r_type == cache_ptr->howto->type); -} - -/* Support for core dump NOTE sections. */ -static bfd_boolean -elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) -{ - int offset; - size_t size; - - switch (note->descsz) - { - default: - return FALSE; - - case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */ - /* pr_cursig */ - elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); - - /* pr_pid */ - elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24); - - /* pr_reg */ - offset = 72; - size = 216; - - break; - - case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */ - /* pr_cursig */ - elf_tdata (abfd)->core_signal - = bfd_get_16 (abfd, note->descdata + 12); - - /* pr_pid */ - elf_tdata (abfd)->core_lwpid - = bfd_get_32 (abfd, note->descdata + 32); - - /* pr_reg */ - offset = 112; - size = 216; - - break; - } - - /* Make a ".reg/999" section. */ - return _bfd_elfcore_make_pseudosection (abfd, ".reg", - size, note->descpos + offset); -} - -static bfd_boolean -elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) -{ - switch (note->descsz) - { - default: - return FALSE; - - case 124: /* sizeof(struct elf_prpsinfo) on Linux/x32 */ - elf_tdata (abfd)->core_pid - = bfd_get_32 (abfd, note->descdata + 12); - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); - break; - - case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */ - elf_tdata (abfd)->core_pid - = bfd_get_32 (abfd, note->descdata + 24); - elf_tdata (abfd)->core_program - = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); - elf_tdata (abfd)->core_command - = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80); - } - - /* Note that for some reason, a spurious space is tacked - onto the end of the args in some (at least one anyway) - implementations, so strip it off if it exists. */ - - { - char *command = elf_tdata (abfd)->core_command; - int n = strlen (command); - - if (0 < n && command[n - 1] == ' ') - command[n - 1] = '\0'; - } - - return TRUE; -} - -#ifdef CORE_HEADER -static char * -elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz, - int note_type, ...) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - const void *p; - int size; - va_list ap; - const char *fname, *psargs; - long pid; - int cursig; - const void *gregs; - - switch (note_type) - { - default: - return NULL; - - case NT_PRPSINFO: - va_start (ap, note_type); - fname = va_arg (ap, const char *); - psargs = va_arg (ap, const char *); - va_end (ap); - - if (bed->s->elfclass == ELFCLASS32) - { - prpsinfo32_t data; - memset (&data, 0, sizeof (data)); - strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); - strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); - p = (const void *) &data; - size = sizeof (data); - } - else - { - prpsinfo_t data; - memset (&data, 0, sizeof (data)); - strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); - strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); - p = (const void *) &data; - size = sizeof (data); - } - break; - - case NT_PRSTATUS: - va_start (ap, note_type); - pid = va_arg (ap, long); - cursig = va_arg (ap, int); - gregs = va_arg (ap, const void *); - va_end (ap); - - if (bed->s->elfclass == ELFCLASS32) - { - if (bed->elf_machine_code == EM_X86_64) - { - prstatusx32_t prstat; - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - p = (const void *) &prstat; - size = sizeof (prstat); - } - else - { - prstatus32_t prstat; - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - p = (const void *) &prstat; - size = sizeof (prstat); - } - } - else - { - prstatus_t prstat; - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - p = (const void *) &prstat; - size = sizeof (prstat); - } - break; - } - - return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, p, - size); -} -#endif - -/* Functions for the x86-64 ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1" -#define ELF32_DYNAMIC_INTERPRETER "/lib/ld32.so.1" - -/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid - copying dynamic variables from a shared lib into an app's dynbss - section, and instead use a dynamic relocation to point into the - shared lib. */ -#define ELIMINATE_COPY_RELOCS 1 - -/* The size in bytes of an entry in the global offset table. */ - -#define GOT_ENTRY_SIZE 8 - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 16 - -/* The first entry in a procedure linkage table looks like this. See the - SVR4 ABI i386 supplement and the x86-64 ABI to see how this works. */ - -static const bfd_byte elf_x86_64_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ - 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */ - 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */ -}; - -/* Subsequent entries in a procedure linkage table look like this. */ - -static const bfd_byte elf_x86_64_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */ - 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ - 0x68, /* pushq immediate */ - 0, 0, 0, 0, /* replaced with index into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt0. */ -}; - -/* .eh_frame covering the .plt section. */ - -static const bfd_byte elf_x86_64_eh_frame_plt[] = -{ -#define PLT_CIE_LENGTH 20 -#define PLT_FDE_LENGTH 36 -#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 -#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12 - PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ - 0, 0, 0, 0, /* CIE ID */ - 1, /* CIE version */ - 'z', 'R', 0, /* Augmentation string */ - 1, /* Code alignment factor */ - 0x78, /* Data alignment factor */ - 16, /* Return address column */ - 1, /* Augmentation size */ - DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ - DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ - DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ - DW_CFA_nop, DW_CFA_nop, - - PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ - PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ - 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */ - 0, 0, 0, 0, /* .plt size goes here */ - 0, /* Augmentation size */ - DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */ - DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ - DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */ - DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ - DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ - 11, /* Block length */ - DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */ - DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */ - DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge, - DW_OP_lit3, DW_OP_shl, DW_OP_plus, - DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop -}; - -/* x86-64 ELF linker hash entry. */ - -struct elf_x86_64_link_hash_entry -{ - struct elf_link_hash_entry elf; - - /* Track dynamic relocs copied for this symbol. */ - struct elf_dyn_relocs *dyn_relocs; - -#define GOT_UNKNOWN 0 -#define GOT_NORMAL 1 -#define GOT_TLS_GD 2 -#define GOT_TLS_IE 3 -#define GOT_TLS_GDESC 4 -#define GOT_TLS_GD_BOTH_P(type) \ - ((type) == (GOT_TLS_GD | GOT_TLS_GDESC)) -#define GOT_TLS_GD_P(type) \ - ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type)) -#define GOT_TLS_GDESC_P(type) \ - ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) -#define GOT_TLS_GD_ANY_P(type) \ - (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) - unsigned char tls_type; - - /* Offset of the GOTPLT entry reserved for the TLS descriptor, - starting at the end of the jump table. */ - bfd_vma tlsdesc_got; -}; - -#define elf_x86_64_hash_entry(ent) \ - ((struct elf_x86_64_link_hash_entry *)(ent)) - -struct elf_x86_64_obj_tdata -{ - struct elf_obj_tdata root; - - /* tls_type for each local got entry. */ - char *local_got_tls_type; - - /* GOTPLT entries for TLS descriptors. */ - bfd_vma *local_tlsdesc_gotent; -}; - -#define elf_x86_64_tdata(abfd) \ - ((struct elf_x86_64_obj_tdata *) (abfd)->tdata.any) - -#define elf_x86_64_local_got_tls_type(abfd) \ - (elf_x86_64_tdata (abfd)->local_got_tls_type) - -#define elf_x86_64_local_tlsdesc_gotent(abfd) \ - (elf_x86_64_tdata (abfd)->local_tlsdesc_gotent) - -#define is_x86_64_elf(bfd) \ - (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ - && elf_tdata (bfd) != NULL \ - && elf_object_id (bfd) == X86_64_ELF_DATA) - -static bfd_boolean -elf_x86_64_mkobject (bfd *abfd) -{ - return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_64_obj_tdata), - X86_64_ELF_DATA); -} - -/* x86-64 ELF linker hash table. */ - -struct elf_x86_64_link_hash_table -{ - struct elf_link_hash_table elf; - - /* Short-cuts to get to dynamic linker sections. */ - asection *sdynbss; - asection *srelbss; - asection *plt_eh_frame; - - union - { - bfd_signed_vma refcount; - bfd_vma offset; - } tls_ld_got; - - /* The amount of space used by the jump slots in the GOT. */ - bfd_vma sgotplt_jump_table_size; - - /* Small local sym cache. */ - struct sym_cache sym_cache; - - bfd_vma (*r_info) (bfd_vma, bfd_vma); - bfd_vma (*r_sym) (bfd_vma); - unsigned int pointer_r_type; - const char *dynamic_interpreter; - int dynamic_interpreter_size; - - /* _TLS_MODULE_BASE_ symbol. */ - struct bfd_link_hash_entry *tls_module_base; - - /* Used by local STT_GNU_IFUNC symbols. */ - htab_t loc_hash_table; - void * loc_hash_memory; - - /* The offset into splt of the PLT entry for the TLS descriptor - resolver. Special values are 0, if not necessary (or not found - to be necessary yet), and -1 if needed but not determined - yet. */ - bfd_vma tlsdesc_plt; - /* The offset into sgot of the GOT entry used by the PLT entry - above. */ - bfd_vma tlsdesc_got; -}; - -/* Get the x86-64 ELF linker hash table from a link_info structure. */ - -#define elf_x86_64_hash_table(p) \ - (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ - == X86_64_ELF_DATA ? ((struct elf_x86_64_link_hash_table *) ((p)->hash)) : NULL) - -#define elf_x86_64_compute_jump_table_size(htab) \ - ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE) - -/* Create an entry in an x86-64 ELF linker hash table. */ - -static struct bfd_hash_entry * -elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf_x86_64_link_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = _bfd_elf_link_hash_newfunc (entry, table, string); - if (entry != NULL) - { - struct elf_x86_64_link_hash_entry *eh; - - eh = (struct elf_x86_64_link_hash_entry *) entry; - eh->dyn_relocs = NULL; - eh->tls_type = GOT_UNKNOWN; - eh->tlsdesc_got = (bfd_vma) -1; - } - - return entry; -} - -/* Compute a hash of a local hash entry. We use elf_link_hash_entry - for local symbol so that we can handle local STT_GNU_IFUNC symbols - as global symbol. We reuse indx and dynstr_index for local symbol - hash since they aren't used by global symbols in this backend. */ - -static hashval_t -elf_x86_64_local_htab_hash (const void *ptr) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) ptr; - return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index); -} - -/* Compare local hash entries. */ - -static int -elf_x86_64_local_htab_eq (const void *ptr1, const void *ptr2) -{ - struct elf_link_hash_entry *h1 - = (struct elf_link_hash_entry *) ptr1; - struct elf_link_hash_entry *h2 - = (struct elf_link_hash_entry *) ptr2; - - return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index; -} - -/* Find and/or create a hash entry for local symbol. */ - -static struct elf_link_hash_entry * -elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab, - bfd *abfd, const Elf_Internal_Rela *rel, - bfd_boolean create) -{ - struct elf_x86_64_link_hash_entry e, *ret; - asection *sec = abfd->sections; - hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, - htab->r_sym (rel->r_info)); - void **slot; - - e.elf.indx = sec->id; - e.elf.dynstr_index = htab->r_sym (rel->r_info); - slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h, - create ? INSERT : NO_INSERT); - - if (!slot) - return NULL; - - if (*slot) - { - ret = (struct elf_x86_64_link_hash_entry *) *slot; - return &ret->elf; - } - - ret = (struct elf_x86_64_link_hash_entry *) - objalloc_alloc ((struct objalloc *) htab->loc_hash_memory, - sizeof (struct elf_x86_64_link_hash_entry)); - if (ret) - { - memset (ret, 0, sizeof (*ret)); - ret->elf.indx = sec->id; - ret->elf.dynstr_index = htab->r_sym (rel->r_info); - ret->elf.dynindx = -1; - *slot = ret; - } - return &ret->elf; -} - -/* Create an X86-64 ELF linker hash table. */ - -static struct bfd_link_hash_table * -elf_x86_64_link_hash_table_create (bfd *abfd) -{ - struct elf_x86_64_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table); - - ret = (struct elf_x86_64_link_hash_table *) bfd_malloc (amt); - if (ret == NULL) - return NULL; - - if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, - elf_x86_64_link_hash_newfunc, - sizeof (struct elf_x86_64_link_hash_entry), - X86_64_ELF_DATA)) - { - free (ret); - return NULL; - } - - ret->sdynbss = NULL; - ret->srelbss = NULL; - ret->plt_eh_frame = NULL; - ret->sym_cache.abfd = NULL; - ret->tlsdesc_plt = 0; - ret->tlsdesc_got = 0; - ret->tls_ld_got.refcount = 0; - ret->sgotplt_jump_table_size = 0; - ret->tls_module_base = NULL; - - if (ABI_64_P (abfd)) - { - ret->r_info = elf64_r_info; - ret->r_sym = elf64_r_sym; - ret->pointer_r_type = R_X86_64_64; - ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER; - ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER; - } - else - { - ret->r_info = elf32_r_info; - ret->r_sym = elf32_r_sym; - ret->pointer_r_type = R_X86_64_32; - ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER; - ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER; - } - - ret->loc_hash_table = htab_try_create (1024, - elf_x86_64_local_htab_hash, - elf_x86_64_local_htab_eq, - NULL); - ret->loc_hash_memory = objalloc_create (); - if (!ret->loc_hash_table || !ret->loc_hash_memory) - { - free (ret); - return NULL; - } - - return &ret->elf.root; -} - -/* Destroy an X86-64 ELF linker hash table. */ - -static void -elf_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct elf_x86_64_link_hash_table *htab - = (struct elf_x86_64_link_hash_table *) hash; - - if (htab->loc_hash_table) - htab_delete (htab->loc_hash_table); - if (htab->loc_hash_memory) - objalloc_free ((struct objalloc *) htab->loc_hash_memory); - _bfd_generic_link_hash_table_free (hash); -} - -/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and - .rela.bss sections in DYNOBJ, and set up shortcuts to them in our - hash table. */ - -static bfd_boolean -elf_x86_64_create_dynamic_sections (bfd *dynobj, - struct bfd_link_info *info) -{ - struct elf_x86_64_link_hash_table *htab; - - if (!_bfd_elf_create_dynamic_sections (dynobj, info)) - return FALSE; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); - if (!info->shared) - htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); - - if (!htab->sdynbss - || (!info->shared && !htab->srelbss)) - abort (); - - if (!info->no_ld_generated_unwind_info - && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL - && htab->elf.splt != NULL) - { - flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags; - htab->plt_eh_frame - = bfd_make_section_with_flags (dynobj, ".eh_frame", - flags | SEC_READONLY); - if (htab->plt_eh_frame == NULL - || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3)) - return FALSE; - - htab->plt_eh_frame->size = sizeof (elf_x86_64_eh_frame_plt); - htab->plt_eh_frame->contents - = bfd_alloc (dynobj, htab->plt_eh_frame->size); - memcpy (htab->plt_eh_frame->contents, elf_x86_64_eh_frame_plt, - sizeof (elf_x86_64_eh_frame_plt)); - } - return TRUE; -} - -/* Copy the extra info we tack onto an elf_link_hash_entry. */ - -static void -elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *dir, - struct elf_link_hash_entry *ind) -{ - struct elf_x86_64_link_hash_entry *edir, *eind; - - edir = (struct elf_x86_64_link_hash_entry *) dir; - eind = (struct elf_x86_64_link_hash_entry *) ind; - - if (eind->dyn_relocs != NULL) - { - if (edir->dyn_relocs != NULL) - { - struct elf_dyn_relocs **pp; - struct elf_dyn_relocs *p; - - /* Add reloc counts against the indirect sym to the direct sym - list. Merge any entries against the same section. */ - for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) - { - struct elf_dyn_relocs *q; - - for (q = edir->dyn_relocs; q != NULL; q = q->next) - if (q->sec == p->sec) - { - q->pc_count += p->pc_count; - q->count += p->count; - *pp = p->next; - break; - } - if (q == NULL) - pp = &p->next; - } - *pp = edir->dyn_relocs; - } - - edir->dyn_relocs = eind->dyn_relocs; - eind->dyn_relocs = NULL; - } - - if (ind->root.type == bfd_link_hash_indirect - && dir->got.refcount <= 0) - { - edir->tls_type = eind->tls_type; - eind->tls_type = GOT_UNKNOWN; - } - - if (ELIMINATE_COPY_RELOCS - && ind->root.type != bfd_link_hash_indirect - && dir->dynamic_adjusted) - { - /* If called to transfer flags for a weakdef during processing - of elf_adjust_dynamic_symbol, don't copy non_got_ref. - We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - dir->ref_dynamic |= ind->ref_dynamic; - dir->ref_regular |= ind->ref_regular; - dir->ref_regular_nonweak |= ind->ref_regular_nonweak; - dir->needs_plt |= ind->needs_plt; - dir->pointer_equality_needed |= ind->pointer_equality_needed; - } - else - _bfd_elf_link_hash_copy_indirect (info, dir, ind); -} - -static bfd_boolean -elf64_x86_64_elf_object_p (bfd *abfd) -{ - /* Set the right machine number for an x86-64 elf64 file. */ - bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64); - return TRUE; -} - -/* Return TRUE if the TLS access code sequence support transition - from R_TYPE. */ - -static bfd_boolean -elf_x86_64_check_tls_transition (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - bfd_byte *contents, - Elf_Internal_Shdr *symtab_hdr, - struct elf_link_hash_entry **sym_hashes, - unsigned int r_type, - const Elf_Internal_Rela *rel, - const Elf_Internal_Rela *relend) -{ - unsigned int val; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - bfd_vma offset; - struct elf_x86_64_link_hash_table *htab; - - /* Get the section contents. */ - if (contents == NULL) - { - if (elf_section_data (sec)->this_hdr.contents != NULL) - contents = elf_section_data (sec)->this_hdr.contents; - else - { - /* FIXME: How to better handle error condition? */ - if (!bfd_malloc_and_get_section (abfd, sec, &contents)) - return FALSE; - - /* Cache the section contents for elf_link_input_bfd. */ - elf_section_data (sec)->this_hdr.contents = contents; - } - } - - htab = elf_x86_64_hash_table (info); - offset = rel->r_offset; - switch (r_type) - { - case R_X86_64_TLSGD: - case R_X86_64_TLSLD: - if ((rel + 1) >= relend) - return FALSE; - - if (r_type == R_X86_64_TLSGD) - { - /* Check transition from GD access model. For 64bit, only - .byte 0x66; leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr - can transit to different access model. For 32bit, only - leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr - can transit to different access model. */ - - static const unsigned char call[] = { 0x66, 0x66, 0x48, 0xe8 }; - static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d }; - - if ((offset + 12) > sec->size - || memcmp (contents + offset + 4, call, 4) != 0) - return FALSE; - - if (ABI_64_P (abfd)) - { - if (offset < 4 - || memcmp (contents + offset - 4, leaq, 4) != 0) - return FALSE; - } - else - { - if (offset < 3 - || memcmp (contents + offset - 3, leaq + 1, 3) != 0) - return FALSE; - } - } - else - { - /* Check transition from LD access model. Only - leaq foo@tlsld(%rip), %rdi; - call __tls_get_addr - can transit to different access model. */ - - static const unsigned char lea[] = { 0x48, 0x8d, 0x3d }; - - if (offset < 3 || (offset + 9) > sec->size) - return FALSE; - - if (memcmp (contents + offset - 3, lea, 3) != 0 - || 0xe8 != *(contents + offset + 4)) - return FALSE; - } - - r_symndx = htab->r_sym (rel[1].r_info); - if (r_symndx < symtab_hdr->sh_info) - return FALSE; - - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - /* Use strncmp to check __tls_get_addr since __tls_get_addr - may be versioned. */ - return (h != NULL - && h->root.root.string != NULL - && (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32 - || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32) - && (strncmp (h->root.root.string, - "__tls_get_addr", 14) == 0)); - - case R_X86_64_GOTTPOFF: - /* Check transition from IE access model: - mov foo@gottpoff(%rip), %reg - add foo@gottpoff(%rip), %reg - */ - - /* Check REX prefix first. */ - if (offset >= 3 && (offset + 4) <= sec->size) - { - val = bfd_get_8 (abfd, contents + offset - 3); - if (val != 0x48 && val != 0x4c) - { - /* X32 may have 0x44 REX prefix or no REX prefix. */ - if (ABI_64_P (abfd)) - return FALSE; - } - } - else - { - /* X32 may not have any REX prefix. */ - if (ABI_64_P (abfd)) - return FALSE; - if (offset < 2 || (offset + 3) > sec->size) - return FALSE; - } - - val = bfd_get_8 (abfd, contents + offset - 2); - if (val != 0x8b && val != 0x03) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - return (val & 0xc7) == 5; - - case R_X86_64_GOTPC32_TLSDESC: - /* Check transition from GDesc access model: - leaq x@tlsdesc(%rip), %rax - - Make sure it's a leaq adding rip to a 32-bit offset - into any register, although it's probably almost always - going to be rax. */ - - if (offset < 3 || (offset + 4) > sec->size) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 3); - if ((val & 0xfb) != 0x48) - return FALSE; - - if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d) - return FALSE; - - val = bfd_get_8 (abfd, contents + offset - 1); - return (val & 0xc7) == 0x05; - - case R_X86_64_TLSDESC_CALL: - /* Check transition from GDesc access model: - call *x@tlsdesc(%rax) - */ - if (offset + 2 <= sec->size) - { - /* Make sure that it's a call *x@tlsdesc(%rax). */ - static const unsigned char call[] = { 0xff, 0x10 }; - return memcmp (contents + offset, call, 2) == 0; - } - - return FALSE; - - default: - abort (); - } -} - -/* Return TRUE if the TLS access transition is OK or no transition - will be performed. Update R_TYPE if there is a transition. */ - -static bfd_boolean -elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, - asection *sec, bfd_byte *contents, - Elf_Internal_Shdr *symtab_hdr, - struct elf_link_hash_entry **sym_hashes, - unsigned int *r_type, int tls_type, - const Elf_Internal_Rela *rel, - const Elf_Internal_Rela *relend, - struct elf_link_hash_entry *h, - unsigned long r_symndx) -{ - unsigned int from_type = *r_type; - unsigned int to_type = from_type; - bfd_boolean check = TRUE; - - /* Skip TLS transition for functions. */ - if (h != NULL - && (h->type == STT_FUNC - || h->type == STT_GNU_IFUNC)) - return TRUE; - - switch (from_type) - { - case R_X86_64_TLSGD: - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_TLSDESC_CALL: - case R_X86_64_GOTTPOFF: - if (info->executable) - { - if (h == NULL) - to_type = R_X86_64_TPOFF32; - else - to_type = R_X86_64_GOTTPOFF; - } - - /* When we are called from elf_x86_64_relocate_section, - CONTENTS isn't NULL and there may be additional transitions - based on TLS_TYPE. */ - if (contents != NULL) - { - unsigned int new_to_type = to_type; - - if (info->executable - && h != NULL - && h->dynindx == -1 - && tls_type == GOT_TLS_IE) - new_to_type = R_X86_64_TPOFF32; - - if (to_type == R_X86_64_TLSGD - || to_type == R_X86_64_GOTPC32_TLSDESC - || to_type == R_X86_64_TLSDESC_CALL) - { - if (tls_type == GOT_TLS_IE) - new_to_type = R_X86_64_GOTTPOFF; - } - - /* We checked the transition before when we were called from - elf_x86_64_check_relocs. We only want to check the new - transition which hasn't been checked before. */ - check = new_to_type != to_type && from_type == to_type; - to_type = new_to_type; - } - - break; - - case R_X86_64_TLSLD: - if (info->executable) - to_type = R_X86_64_TPOFF32; - break; - - default: - return TRUE; - } - - /* Return TRUE if there is no transition. */ - if (from_type == to_type) - return TRUE; - - /* Check if the transition can be performed. */ - if (check - && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents, - symtab_hdr, sym_hashes, - from_type, rel, relend)) - { - reloc_howto_type *from, *to; - const char *name; - - from = elf_x86_64_rtype_to_howto (abfd, from_type); - to = elf_x86_64_rtype_to_howto (abfd, to_type); - - if (h) - name = h->root.root.string; - else - { - struct elf_x86_64_link_hash_table *htab; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - name = "*unknown*"; - else - { - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); - } - } - - (*_bfd_error_handler) - (_("%B: TLS transition from %s to %s against `%s' at 0x%lx " - "in section `%A' failed"), - abfd, sec, from->name, to->name, name, - (unsigned long) rel->r_offset); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - *r_type = to_type; - return TRUE; -} - -/* Look through the relocs for a section during the first phase, and - calculate needed space in the global offset table, procedure - linkage table, and dynamic reloc sections. */ - -static bfd_boolean -elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) -{ - struct elf_x86_64_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sreloc; - - if (info->relocatable) - return TRUE; - - BFD_ASSERT (is_x86_64_elf (abfd)); - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - symtab_hdr = &elf_symtab_hdr (abfd); - sym_hashes = elf_sym_hashes (abfd); - - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned int r_type; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *isym; - const char *name; - - r_symndx = htab->r_sym (rel->r_info); - r_type = ELF32_R_TYPE (rel->r_info); - - if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) - { - (*_bfd_error_handler) (_("%B: bad symbol index: %d"), - abfd, r_symndx); - return FALSE; - } - - if (r_symndx < symtab_hdr->sh_info) - { - /* A local symbol. */ - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - if (isym == NULL) - return FALSE; - - /* Check relocation against local STT_GNU_IFUNC symbol. */ - if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) - { - h = elf_x86_64_get_local_sym_hash (htab, abfd, rel, - TRUE); - if (h == NULL) - return FALSE; - - /* Fake a STT_GNU_IFUNC symbol. */ - h->type = STT_GNU_IFUNC; - h->def_regular = 1; - h->ref_regular = 1; - h->forced_local = 1; - h->root.type = bfd_link_hash_defined; - } - else - h = NULL; - } - else - { - isym = NULL; - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - - /* Check invalid x32 relocations. */ - if (!ABI_64_P (abfd)) - switch (r_type) - { - default: - break; - - case R_X86_64_DTPOFF64: - case R_X86_64_TPOFF64: - case R_X86_64_PC64: - case R_X86_64_GOTOFF64: - case R_X86_64_GOT64: - case R_X86_64_GOTPCREL64: - case R_X86_64_GOTPC64: - case R_X86_64_GOTPLT64: - case R_X86_64_PLTOFF64: - { - if (h) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against symbol `%s' isn't " - "supported in x32 mode"), abfd, - x86_64_elf_howto_table[r_type].name, name); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - break; - } - - if (h != NULL) - { - /* Create the ifunc sections for static executables. If we - never see an indirect function symbol nor we are building - a static executable, those sections will be empty and - won't appear in output. */ - switch (r_type) - { - default: - break; - - case R_X86_64_32S: - case R_X86_64_32: - case R_X86_64_64: - case R_X86_64_PC32: - case R_X86_64_PC64: - case R_X86_64_PLT32: - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCREL64: - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) - return FALSE; - break; - } - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - { - /* It is referenced by a non-shared object. */ - h->ref_regular = 1; - h->needs_plt = 1; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - h->plt.refcount += 1; - - /* STT_GNU_IFUNC needs dynamic sections. */ - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), abfd, - x86_64_elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_X86_64_32: - if (ABI_64_P (abfd)) - goto not_pointer; - case R_X86_64_64: - h->non_got_ref = 1; - h->pointer_equality_needed = 1; - if (info->shared) - { - /* We must copy these reloc types into the output - file. Create a reloc section in dynobj and - make room for this reloc. */ - sreloc = _bfd_elf_create_ifunc_dyn_reloc - (abfd, info, sec, sreloc, - &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs); - if (sreloc == NULL) - return FALSE; - } - break; - - case R_X86_64_32S: - case R_X86_64_PC32: - case R_X86_64_PC64: -not_pointer: - h->non_got_ref = 1; - if (r_type != R_X86_64_PC32 - && r_type != R_X86_64_PC64) - h->pointer_equality_needed = 1; - break; - - case R_X86_64_PLT32: - break; - - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCREL64: - h->got.refcount += 1; - if (htab->elf.sgot == NULL - && !_bfd_elf_create_got_section (htab->elf.dynobj, - info)) - return FALSE; - break; - } - - continue; - } - } - - if (! elf_x86_64_tls_transition (info, abfd, sec, NULL, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, rel_end, h, r_symndx)) - return FALSE; - - switch (r_type) - { - case R_X86_64_TLSLD: - htab->tls_ld_got.refcount += 1; - goto create_got; - - case R_X86_64_TPOFF32: - if (!info->executable && ABI_64_P (abfd)) - { - if (h) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), - abfd, - x86_64_elf_howto_table[r_type].name, name); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - break; - - case R_X86_64_GOTTPOFF: - if (!info->executable) - info->flags |= DF_STATIC_TLS; - /* Fall through */ - - case R_X86_64_GOT32: - case R_X86_64_GOTPCREL: - case R_X86_64_TLSGD: - case R_X86_64_GOT64: - case R_X86_64_GOTPCREL64: - case R_X86_64_GOTPLT64: - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_TLSDESC_CALL: - /* This symbol requires a global offset table entry. */ - { - int tls_type, old_tls_type; - - switch (r_type) - { - default: tls_type = GOT_NORMAL; break; - case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break; - case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break; - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_TLSDESC_CALL: - tls_type = GOT_TLS_GDESC; break; - } - - if (h != NULL) - { - if (r_type == R_X86_64_GOTPLT64) - { - /* This relocation indicates that we also need - a PLT entry, as this is a function. We don't need - a PLT entry for local symbols. */ - h->needs_plt = 1; - h->plt.refcount += 1; - } - h->got.refcount += 1; - old_tls_type = elf_x86_64_hash_entry (h)->tls_type; - } - else - { - bfd_signed_vma *local_got_refcounts; - - /* This is a global offset table entry for a local symbol. */ - local_got_refcounts = elf_local_got_refcounts (abfd); - if (local_got_refcounts == NULL) - { - bfd_size_type size; - - size = symtab_hdr->sh_info; - size *= sizeof (bfd_signed_vma) - + sizeof (bfd_vma) + sizeof (char); - local_got_refcounts = ((bfd_signed_vma *) - bfd_zalloc (abfd, size)); - if (local_got_refcounts == NULL) - return FALSE; - elf_local_got_refcounts (abfd) = local_got_refcounts; - elf_x86_64_local_tlsdesc_gotent (abfd) - = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info); - elf_x86_64_local_got_tls_type (abfd) - = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info); - } - local_got_refcounts[r_symndx] += 1; - old_tls_type - = elf_x86_64_local_got_tls_type (abfd) [r_symndx]; - } - - /* If a TLS symbol is accessed using IE at least once, - there is no point to use dynamic model for it. */ - if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN - && (! GOT_TLS_GD_ANY_P (old_tls_type) - || tls_type != GOT_TLS_IE)) - { - if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type)) - tls_type = old_tls_type; - else if (GOT_TLS_GD_ANY_P (old_tls_type) - && GOT_TLS_GD_ANY_P (tls_type)) - tls_type |= old_tls_type; - else - { - if (h) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, - isym, NULL); - (*_bfd_error_handler) - (_("%B: '%s' accessed both as normal and thread local symbol"), - abfd, name); - return FALSE; - } - } - - if (old_tls_type != tls_type) - { - if (h != NULL) - elf_x86_64_hash_entry (h)->tls_type = tls_type; - else - elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type; - } - } - /* Fall through */ - - case R_X86_64_GOTOFF64: - case R_X86_64_GOTPC32: - case R_X86_64_GOTPC64: - create_got: - if (htab->elf.sgot == NULL) - { - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - if (!_bfd_elf_create_got_section (htab->elf.dynobj, - info)) - return FALSE; - } - break; - - case R_X86_64_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->needs_plt = 1; - h->plt.refcount += 1; - break; - - case R_X86_64_PLTOFF64: - /* This tries to form the 'address' of a function relative - to GOT. For global symbols we need a PLT entry. */ - if (h != NULL) - { - h->needs_plt = 1; - h->plt.refcount += 1; - } - goto create_got; - - case R_X86_64_32: - if (!ABI_64_P (abfd)) - goto pointer; - case R_X86_64_8: - case R_X86_64_16: - case R_X86_64_32S: - /* Let's help debug shared library creation. These relocs - cannot be used in shared libs. Don't error out for - sections we don't care about, such as debug sections or - non-constant sections. */ - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (sec->flags & SEC_READONLY) != 0) - { - if (h) - name = h->root.root.string; - else - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), - abfd, x86_64_elf_howto_table[r_type].name, name); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - /* Fall through. */ - - case R_X86_64_PC8: - case R_X86_64_PC16: - case R_X86_64_PC32: - case R_X86_64_PC64: - case R_X86_64_64: -pointer: - if (h != NULL && info->executable) - { - /* If this reloc is in a read-only section, we might - need a copy reloc. We can't check reliably at this - stage whether the section is read-only, as input - sections have not yet been mapped to output sections. - Tentatively set the flag for now, and correct in - adjust_dynamic_symbol. */ - h->non_got_ref = 1; - - /* We may need a .plt entry if the function this reloc - refers to is in a shared lib. */ - h->plt.refcount += 1; - if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64) - h->pointer_equality_needed = 1; - } - - /* If we are creating a shared library, and this is a reloc - against a global symbol, or a non PC relative reloc - against a local symbol, then we need to copy the reloc - into the shared library. However, if we are linking with - -Bsymbolic, we do not need to copy a reloc against a - global symbol which is defined in an object we are - including in the link (i.e., DEF_REGULAR is set). At - this point we have not seen all the input files, so it is - possible that DEF_REGULAR is not set now but will be set - later (it is never cleared). In case of a weak definition, - DEF_REGULAR may be cleared later by a strong definition in - a shared library. We account for that possibility below by - storing information in the relocs_copied field of the hash - table entry. A similar situation occurs when creating - shared libraries and symbol visibility changes render the - symbol local. - - If on the other hand, we are creating an executable, we - may need to keep relocations for symbols satisfied by a - dynamic library if we manage to avoid copy relocs for the - symbol. */ - if ((info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (! IS_X86_64_PCREL_TYPE (r_type) - || (h != NULL - && (! SYMBOLIC_BIND (info, h) - || h->root.type == bfd_link_hash_defweak - || !h->def_regular)))) - || (ELIMINATE_COPY_RELOCS - && !info->shared - && (sec->flags & SEC_ALLOC) != 0 - && h != NULL - && (h->root.type == bfd_link_hash_defweak - || !h->def_regular))) - { - struct elf_dyn_relocs *p; - struct elf_dyn_relocs **head; - - /* We must copy these reloc types into the output file. - Create a reloc section in dynobj and make room for - this reloc. */ - if (sreloc == NULL) - { - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - sreloc = _bfd_elf_make_dynamic_reloc_section - (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2, - abfd, /*rela?*/ TRUE); - - if (sreloc == NULL) - return FALSE; - } - - /* If this is a global symbol, we count the number of - relocations we need for this symbol. */ - if (h != NULL) - { - head = &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs; - } - else - { - /* Track dynamic relocs needed for local syms too. - We really need local syms available to do this - easily. Oh well. */ - asection *s; - void **vpp; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - if (isym == NULL) - return FALSE; - - s = bfd_section_from_elf_index (abfd, isym->st_shndx); - if (s == NULL) - s = sec; - - /* Beware of type punned pointers vs strict aliasing - rules. */ - vpp = &(elf_section_data (s)->local_dynrel); - head = (struct elf_dyn_relocs **)vpp; - } - - p = *head; - if (p == NULL || p->sec != sec) - { - bfd_size_type amt = sizeof *p; - - p = ((struct elf_dyn_relocs *) - bfd_alloc (htab->elf.dynobj, amt)); - if (p == NULL) - return FALSE; - p->next = *head; - *head = p; - p->sec = sec; - p->count = 0; - p->pc_count = 0; - } - - p->count += 1; - if (IS_X86_64_PCREL_TYPE (r_type)) - p->pc_count += 1; - } - break; - - /* This relocation describes the C++ object vtable hierarchy. - Reconstruct it for later use during GC. */ - case R_X86_64_GNU_VTINHERIT: - if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return FALSE; - break; - - /* This relocation describes which C++ vtable entries are actually - used. Record for later use during GC. */ - case R_X86_64_GNU_VTENTRY: - BFD_ASSERT (h != NULL); - if (h != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) - return FALSE; - break; - - default: - break; - } - } - - return TRUE; -} - -/* Return the section that should be marked against GC for a given - relocation. */ - -static asection * -elf_x86_64_gc_mark_hook (asection *sec, - struct bfd_link_info *info, - Elf_Internal_Rela *rel, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - if (h != NULL) - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_X86_64_GNU_VTINHERIT: - case R_X86_64_GNU_VTENTRY: - return NULL; - } - - return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); -} - -/* Update the got entry reference counts for the section being removed. */ - -static bfd_boolean -elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) -{ - struct elf_x86_64_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; - const Elf_Internal_Rela *rel, *relend; - - if (info->relocatable) - return TRUE; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - elf_section_data (sec)->local_dynrel = NULL; - - symtab_hdr = &elf_symtab_hdr (abfd); - sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); - - htab = elf_x86_64_hash_table (info); - relend = relocs + sec->reloc_count; - for (rel = relocs; rel < relend; rel++) - { - unsigned long r_symndx; - unsigned int r_type; - struct elf_link_hash_entry *h = NULL; - - r_symndx = htab->r_sym (rel->r_info); - if (r_symndx >= symtab_hdr->sh_info) - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - } - else - { - /* A local symbol. */ - Elf_Internal_Sym *isym; - - isym = bfd_sym_from_r_symndx (&htab->sym_cache, - abfd, r_symndx); - - /* Check relocation against local STT_GNU_IFUNC symbol. */ - if (isym != NULL - && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) - { - h = elf_x86_64_get_local_sym_hash (htab, abfd, rel, FALSE); - if (h == NULL) - abort (); - } - } - - if (h) - { - struct elf_x86_64_link_hash_entry *eh; - struct elf_dyn_relocs **pp; - struct elf_dyn_relocs *p; - - eh = (struct elf_x86_64_link_hash_entry *) h; - - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) - if (p->sec == sec) - { - /* Everything must go for SEC. */ - *pp = p->next; - break; - } - } - - r_type = ELF32_R_TYPE (rel->r_info); - if (! elf_x86_64_tls_transition (info, abfd, sec, NULL, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, relend, h, r_symndx)) - return FALSE; - - switch (r_type) - { - case R_X86_64_TLSLD: - if (htab->tls_ld_got.refcount > 0) - htab->tls_ld_got.refcount -= 1; - break; - - case R_X86_64_TLSGD: - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_TLSDESC_CALL: - case R_X86_64_GOTTPOFF: - case R_X86_64_GOT32: - case R_X86_64_GOTPCREL: - case R_X86_64_GOT64: - case R_X86_64_GOTPCREL64: - case R_X86_64_GOTPLT64: - if (h != NULL) - { - if (r_type == R_X86_64_GOTPLT64 && h->plt.refcount > 0) - h->plt.refcount -= 1; - if (h->got.refcount > 0) - h->got.refcount -= 1; - if (h->type == STT_GNU_IFUNC) - { - if (h->plt.refcount > 0) - h->plt.refcount -= 1; - } - } - else if (local_got_refcounts != NULL) - { - if (local_got_refcounts[r_symndx] > 0) - local_got_refcounts[r_symndx] -= 1; - } - break; - - case R_X86_64_8: - case R_X86_64_16: - case R_X86_64_32: - case R_X86_64_64: - case R_X86_64_32S: - case R_X86_64_PC8: - case R_X86_64_PC16: - case R_X86_64_PC32: - case R_X86_64_PC64: - if (info->shared - && (h == NULL || h->type != STT_GNU_IFUNC)) - break; - /* Fall thru */ - - case R_X86_64_PLT32: - case R_X86_64_PLTOFF64: - if (h != NULL) - { - if (h->plt.refcount > 0) - h->plt.refcount -= 1; - } - break; - - default: - break; - } - } - - return TRUE; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static bfd_boolean -elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) -{ - struct elf_x86_64_link_hash_table *htab; - asection *s; - - /* STT_GNU_IFUNC symbol must go through PLT. */ - if (h->type == STT_GNU_IFUNC) - { - if (h->plt.refcount <= 0) - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - return TRUE; - } - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || h->needs_plt) - { - if (h->plt.refcount <= 0 - || SYMBOL_CALLS_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak)) - { - /* This case can occur if we saw a PLT32 reloc in an input - file, but the symbol was never referred to by a dynamic - object, or if all references were garbage collected. In - such a case, we don't actually need to build a procedure - linkage table, and we can just do a PC32 reloc instead. */ - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - - return TRUE; - } - else - /* It's possible that we incorrectly decided a .plt reloc was - needed for an R_X86_64_PC32 reloc to a non-function sym in - check_relocs. We can't decide accurately between function and - non-function syms in check-relocs; Objects loaded later in - the link may change h->type. So fix it now. */ - h->plt.offset = (bfd_vma) -1; - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->u.weakdef != NULL) - { - BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined - || h->u.weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->u.weakdef->root.u.def.section; - h->root.u.def.value = h->u.weakdef->root.u.def.value; - if (ELIMINATE_COPY_RELOCS || info->nocopyreloc) - h->non_got_ref = h->u.weakdef->non_got_ref; - return TRUE; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return TRUE; - - /* If there are no references to this symbol that do not use the - GOT, we don't need to generate a copy reloc. */ - if (!h->non_got_ref) - return TRUE; - - /* If -z nocopyreloc was given, we won't generate them either. */ - if (info->nocopyreloc) - { - h->non_got_ref = 0; - return TRUE; - } - - if (ELIMINATE_COPY_RELOCS) - { - struct elf_x86_64_link_hash_entry * eh; - struct elf_dyn_relocs *p; - - eh = (struct elf_x86_64_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - s = p->sec->output_section; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - break; - } - - /* If we didn't find any dynamic relocs in read-only sections, then - we'll be keeping the dynamic relocs and avoiding the copy reloc. */ - if (p == NULL) - { - h->non_got_ref = 0; - return TRUE; - } - } - - if (h->size == 0) - { - (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), - h->root.root.string); - return TRUE; - } - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker - to copy the initial value out of the dynamic object and into the - runtime process image. */ - if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) - { - const struct elf_backend_data *bed; - bed = get_elf_backend_data (info->output_bfd); - htab->srelbss->size += bed->s->sizeof_rela; - h->needs_copy = 1; - } - - s = htab->sdynbss; - - return _bfd_elf_adjust_dynamic_copy (h, s); -} - -/* Allocate space in .plt, .got and associated reloc sections for - dynamic relocs. */ - -static bfd_boolean -elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) -{ - struct bfd_link_info *info; - struct elf_x86_64_link_hash_table *htab; - struct elf_x86_64_link_hash_entry *eh; - struct elf_dyn_relocs *p; - const struct elf_backend_data *bed; - - if (h->root.type == bfd_link_hash_indirect) - return TRUE; - - eh = (struct elf_x86_64_link_hash_entry *) h; - - info = (struct bfd_link_info *) inf; - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - bed = get_elf_backend_data (info->output_bfd); - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it - here if it is defined and referenced in a non-shared object. */ - if (h->type == STT_GNU_IFUNC - && h->def_regular) - return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, - &eh->dyn_relocs, - PLT_ENTRY_SIZE, - GOT_ENTRY_SIZE); - else if (htab->elf.dynamic_sections_created - && h->plt.refcount > 0) - { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - if (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) - { - asection *s = htab->elf.splt; - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->size == 0) - s->size += PLT_ENTRY_SIZE; - - h->plt.offset = s->size; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && !h->def_regular) - { - h->root.u.def.section = s; - h->root.u.def.value = h->plt.offset; - } - - /* Make room for this entry. */ - s->size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - htab->elf.sgotplt->size += GOT_ENTRY_SIZE; - - /* We also need to make an entry in the .rela.plt section. */ - htab->elf.srelplt->size += bed->s->sizeof_rela; - htab->elf.srelplt->reloc_count++; - } - else - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - } - else - { - h->plt.offset = (bfd_vma) -1; - h->needs_plt = 0; - } - - eh->tlsdesc_got = (bfd_vma) -1; - - /* If R_X86_64_GOTTPOFF symbol is now local to the binary, - make it a R_X86_64_TPOFF32 requiring no GOT entry. */ - if (h->got.refcount > 0 - && info->executable - && h->dynindx == -1 - && elf_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE) - { - h->got.offset = (bfd_vma) -1; - } - else if (h->got.refcount > 0) - { - asection *s; - bfd_boolean dyn; - int tls_type = elf_x86_64_hash_entry (h)->tls_type; - - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && !h->forced_local) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - if (GOT_TLS_GDESC_P (tls_type)) - { - eh->tlsdesc_got = htab->elf.sgotplt->size - - elf_x86_64_compute_jump_table_size (htab); - htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE; - h->got.offset = (bfd_vma) -2; - } - if (! GOT_TLS_GDESC_P (tls_type) - || GOT_TLS_GD_P (tls_type)) - { - s = htab->elf.sgot; - h->got.offset = s->size; - s->size += GOT_ENTRY_SIZE; - if (GOT_TLS_GD_P (tls_type)) - s->size += GOT_ENTRY_SIZE; - } - dyn = htab->elf.dynamic_sections_created; - /* R_X86_64_TLSGD needs one dynamic relocation if local symbol - and two if global. - R_X86_64_GOTTPOFF needs one dynamic relocation. */ - if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) - || tls_type == GOT_TLS_IE) - htab->elf.srelgot->size += bed->s->sizeof_rela; - else if (GOT_TLS_GD_P (tls_type)) - htab->elf.srelgot->size += 2 * bed->s->sizeof_rela; - else if (! GOT_TLS_GDESC_P (tls_type) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) - && (info->shared - || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) - htab->elf.srelgot->size += bed->s->sizeof_rela; - if (GOT_TLS_GDESC_P (tls_type)) - { - htab->elf.srelplt->size += bed->s->sizeof_rela; - htab->tlsdesc_plt = (bfd_vma) -1; - } - } - else - h->got.offset = (bfd_vma) -1; - - if (eh->dyn_relocs == NULL) - return TRUE; - - /* In the shared -Bsymbolic case, discard space allocated for - dynamic pc-relative relocs against symbols which turn out to be - defined in regular objects. For the normal shared case, discard - space for pc-relative relocs that have become local due to symbol - visibility changes. */ - - if (info->shared) - { - /* Relocs that use pc_count are those that appear on a call - insn, or certain REL relocs that can generated via assembly. - We want calls to protected symbols to resolve directly to the - function rather than going via the plt. If people want - function pointer comparisons to work as expected then they - should avoid writing weird assembly. */ - if (SYMBOL_CALLS_LOCAL (info, h)) - { - struct elf_dyn_relocs **pp; - - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) - { - p->count -= p->pc_count; - p->pc_count = 0; - if (p->count == 0) - *pp = p->next; - else - pp = &p->next; - } - } - - /* Also discard relocs on undefined weak syms with non-default - visibility. */ - if (eh->dyn_relocs != NULL - && h->root.type == bfd_link_hash_undefweak) - { - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - eh->dyn_relocs = NULL; - - /* Make sure undefined weak symbols are output as a dynamic - symbol in PIEs. */ - else if (h->dynindx == -1 - && ! h->forced_local - && ! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - } - - } - else if (ELIMINATE_COPY_RELOCS) - { - /* For the non-shared case, discard space for relocs against - symbols which turn out to need copy relocs or are not - dynamic. */ - - if (!h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || (htab->elf.dynamic_sections_created - && (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_undefined)))) - { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (h->dynindx == -1 - && ! h->forced_local - && ! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - - /* If that succeeded, we know we'll be keeping all the - relocs. */ - if (h->dynindx != -1) - goto keep; - } - - eh->dyn_relocs = NULL; - - keep: ; - } - - /* Finally, allocate space. */ - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection * sreloc; - - sreloc = elf_section_data (p->sec)->sreloc; - - BFD_ASSERT (sreloc != NULL); - - sreloc->size += p->count * bed->s->sizeof_rela; - } - - return TRUE; -} - -/* Allocate space in .plt, .got and associated reloc sections for - local dynamic relocs. */ - -static bfd_boolean -elf_x86_64_allocate_local_dynrelocs (void **slot, void *inf) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) *slot; - - if (h->type != STT_GNU_IFUNC - || !h->def_regular - || !h->ref_regular - || !h->forced_local - || h->root.type != bfd_link_hash_defined) - abort (); - - return elf_x86_64_allocate_dynrelocs (h, inf); -} - -/* Find any dynamic relocs that apply to read-only sections. */ - -static bfd_boolean -elf_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h, - void * inf) -{ - struct elf_x86_64_link_hash_entry *eh; - struct elf_dyn_relocs *p; - - /* Skip local IFUNC symbols. */ - if (h->forced_local && h->type == STT_GNU_IFUNC) - return TRUE; - - eh = (struct elf_x86_64_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; - - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - info->flags |= DF_TEXTREL; - - if (info->warn_shared_textrel && info->shared) - info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"), - p->sec->owner, h->root.root.string, - p->sec); - - /* Not an error, just cut short the traversal. */ - return FALSE; - } - } - return TRUE; -} - -/* Set the sizes of the dynamic sections. */ - -static bfd_boolean -elf_x86_64_size_dynamic_sections (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_x86_64_link_hash_table *htab; - bfd *dynobj; - asection *s; - bfd_boolean relocs; - bfd *ibfd; - const struct elf_backend_data *bed; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - bed = get_elf_backend_data (output_bfd); - - dynobj = htab->elf.dynobj; - if (dynobj == NULL) - abort (); - - if (htab->elf.dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (info->executable) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - if (s == NULL) - abort (); - s->size = htab->dynamic_interpreter_size; - s->contents = (unsigned char *) htab->dynamic_interpreter; - } - } - - /* Set up .got offsets for local syms, and space for local dynamic - relocs. */ - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) - { - bfd_signed_vma *local_got; - bfd_signed_vma *end_local_got; - char *local_tls_type; - bfd_vma *local_tlsdesc_gotent; - bfd_size_type locsymcount; - Elf_Internal_Shdr *symtab_hdr; - asection *srel; - - if (! is_x86_64_elf (ibfd)) - continue; - - for (s = ibfd->sections; s != NULL; s = s->next) - { - struct elf_dyn_relocs *p; - - for (p = (struct elf_dyn_relocs *) - (elf_section_data (s)->local_dynrel); - p != NULL; - p = p->next) - { - if (!bfd_is_abs_section (p->sec) - && bfd_is_abs_section (p->sec->output_section)) - { - /* Input section has been discarded, either because - it is a copy of a linkonce section or due to - linker script /DISCARD/, so we'll be discarding - the relocs too. */ - } - else if (p->count != 0) - { - srel = elf_section_data (p->sec)->sreloc; - srel->size += p->count * bed->s->sizeof_rela; - if ((p->sec->output_section->flags & SEC_READONLY) != 0 - && (info->flags & DF_TEXTREL) == 0) - { - info->flags |= DF_TEXTREL; - if (info->warn_shared_textrel && info->shared) - info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"), - p->sec->owner, p->sec); - } - } - } - } - - local_got = elf_local_got_refcounts (ibfd); - if (!local_got) - continue; - - symtab_hdr = &elf_symtab_hdr (ibfd); - locsymcount = symtab_hdr->sh_info; - end_local_got = local_got + locsymcount; - local_tls_type = elf_x86_64_local_got_tls_type (ibfd); - local_tlsdesc_gotent = elf_x86_64_local_tlsdesc_gotent (ibfd); - s = htab->elf.sgot; - srel = htab->elf.srelgot; - for (; local_got < end_local_got; - ++local_got, ++local_tls_type, ++local_tlsdesc_gotent) - { - *local_tlsdesc_gotent = (bfd_vma) -1; - if (*local_got > 0) - { - if (GOT_TLS_GDESC_P (*local_tls_type)) - { - *local_tlsdesc_gotent = htab->elf.sgotplt->size - - elf_x86_64_compute_jump_table_size (htab); - htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE; - *local_got = (bfd_vma) -2; - } - if (! GOT_TLS_GDESC_P (*local_tls_type) - || GOT_TLS_GD_P (*local_tls_type)) - { - *local_got = s->size; - s->size += GOT_ENTRY_SIZE; - if (GOT_TLS_GD_P (*local_tls_type)) - s->size += GOT_ENTRY_SIZE; - } - if (info->shared - || GOT_TLS_GD_ANY_P (*local_tls_type) - || *local_tls_type == GOT_TLS_IE) - { - if (GOT_TLS_GDESC_P (*local_tls_type)) - { - htab->elf.srelplt->size - += bed->s->sizeof_rela; - htab->tlsdesc_plt = (bfd_vma) -1; - } - if (! GOT_TLS_GDESC_P (*local_tls_type) - || GOT_TLS_GD_P (*local_tls_type)) - srel->size += bed->s->sizeof_rela; - } - } - else - *local_got = (bfd_vma) -1; - } - } - - if (htab->tls_ld_got.refcount > 0) - { - /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD - relocs. */ - htab->tls_ld_got.offset = htab->elf.sgot->size; - htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE; - htab->elf.srelgot->size += bed->s->sizeof_rela; - } - else - htab->tls_ld_got.offset = -1; - - /* Allocate global sym .plt and .got entries, and space for global - sym dynamic relocs. */ - elf_link_hash_traverse (&htab->elf, elf_x86_64_allocate_dynrelocs, - info); - - /* Allocate .plt and .got entries, and space for local symbols. */ - htab_traverse (htab->loc_hash_table, - elf_x86_64_allocate_local_dynrelocs, - info); - - /* For every jump slot reserved in the sgotplt, reloc_count is - incremented. However, when we reserve space for TLS descriptors, - it's not incremented, so in order to compute the space reserved - for them, it suffices to multiply the reloc count by the jump - slot size. */ - if (htab->elf.srelplt) - htab->sgotplt_jump_table_size - = elf_x86_64_compute_jump_table_size (htab); - - if (htab->tlsdesc_plt) - { - /* If we're not using lazy TLS relocations, don't generate the - PLT and GOT entries they require. */ - if ((info->flags & DF_BIND_NOW)) - htab->tlsdesc_plt = 0; - else - { - htab->tlsdesc_got = htab->elf.sgot->size; - htab->elf.sgot->size += GOT_ENTRY_SIZE; - /* Reserve room for the initial entry. - FIXME: we could probably do away with it in this case. */ - if (htab->elf.splt->size == 0) - htab->elf.splt->size += PLT_ENTRY_SIZE; - htab->tlsdesc_plt = htab->elf.splt->size; - htab->elf.splt->size += PLT_ENTRY_SIZE; - } - } - - if (htab->elf.sgotplt) - { - struct elf_link_hash_entry *got; - got = elf_link_hash_lookup (elf_hash_table (info), - "_GLOBAL_OFFSET_TABLE_", - FALSE, FALSE, FALSE); - - /* Don't allocate .got.plt section if there are no GOT nor PLT - entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */ - if ((got == NULL - || !got->ref_regular_nonweak) - && (htab->elf.sgotplt->size - == get_elf_backend_data (output_bfd)->got_header_size) - && (htab->elf.splt == NULL - || htab->elf.splt->size == 0) - && (htab->elf.sgot == NULL - || htab->elf.sgot->size == 0) - && (htab->elf.iplt == NULL - || htab->elf.iplt->size == 0) - && (htab->elf.igotplt == NULL - || htab->elf.igotplt->size == 0)) - htab->elf.sgotplt->size = 0; - } - - /* We now have determined the sizes of the various dynamic sections. - Allocate memory for them. */ - relocs = FALSE; - for (s = dynobj->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_LINKER_CREATED) == 0) - continue; - - if (s == htab->elf.splt - || s == htab->elf.sgot - || s == htab->elf.sgotplt - || s == htab->elf.iplt - || s == htab->elf.igotplt - || s == htab->sdynbss) - { - /* Strip this section if we don't need it; see the - comment below. */ - } - else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) - { - if (s->size != 0 && s != htab->elf.srelplt) - relocs = TRUE; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - if (s != htab->elf.srelplt) - s->reloc_count = 0; - } - else - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (s->size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - - s->flags |= SEC_EXCLUDE; - continue; - } - - if ((s->flags & SEC_HAS_CONTENTS) == 0) - continue; - - /* Allocate memory for the section contents. We use bfd_zalloc - here in case unused entries are not reclaimed before the - section's contents are written out. This should not happen, - but this way if it does, we get a R_X86_64_NONE reloc instead - of garbage. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); - if (s->contents == NULL) - return FALSE; - } - - if (htab->plt_eh_frame != NULL - && htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && (htab->elf.splt->flags & SEC_EXCLUDE) == 0) - bfd_put_32 (dynobj, htab->elf.splt->size, - htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET); - - if (htab->elf.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_x86_64_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ -#define add_dynamic_entry(TAG, VAL) \ - _bfd_elf_add_dynamic_entry (info, TAG, VAL) - - if (info->executable) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - - if (htab->tlsdesc_plt - && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) - || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, bed->s->sizeof_rela)) - return FALSE; - - /* If any dynamic relocs apply to a read-only section, - then we need a DT_TEXTREL entry. */ - if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, - elf_x86_64_readonly_dynrelocs, - info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; -} - -static bfd_boolean -elf_x86_64_always_size_sections (bfd *output_bfd, - struct bfd_link_info *info) -{ - asection *tls_sec = elf_hash_table (info)->tls_sec; - - if (tls_sec) - { - struct elf_link_hash_entry *tlsbase; - - tlsbase = elf_link_hash_lookup (elf_hash_table (info), - "_TLS_MODULE_BASE_", - FALSE, FALSE, FALSE); - - if (tlsbase && tlsbase->type == STT_TLS) - { - struct elf_x86_64_link_hash_table *htab; - struct bfd_link_hash_entry *bh = NULL; - const struct elf_backend_data *bed - = get_elf_backend_data (output_bfd); - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL, - tls_sec, 0, NULL, FALSE, - bed->collect, &bh))) - return FALSE; - - htab->tls_module_base = bh; - - tlsbase = (struct elf_link_hash_entry *)bh; - tlsbase->def_regular = 1; - tlsbase->other = STV_HIDDEN; - (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE); - } - } - - return TRUE; -} - -/* _TLS_MODULE_BASE_ needs to be treated especially when linking - executables. Rather than setting it to the beginning of the TLS - section, we have to set it to the end. This function may be called - multiple times, it is idempotent. */ - -static void -elf_x86_64_set_tls_module_base (struct bfd_link_info *info) -{ - struct elf_x86_64_link_hash_table *htab; - struct bfd_link_hash_entry *base; - - if (!info->executable) - return; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return; - - base = htab->tls_module_base; - if (base == NULL) - return; - - base->u.def.value = htab->elf.tls_size; -} - -/* Return the base VMA address which should be subtracted from real addresses - when resolving @dtpoff relocation. - This is PT_TLS segment p_vaddr. */ - -static bfd_vma -elf_x86_64_dtpoff_base (struct bfd_link_info *info) -{ - /* If tls_sec is NULL, we should have signalled an error already. */ - if (elf_hash_table (info)->tls_sec == NULL) - return 0; - return elf_hash_table (info)->tls_sec->vma; -} - -/* Return the relocation value for @tpoff relocation - if STT_TLS virtual address is ADDRESS. */ - -static bfd_vma -elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address) -{ - struct elf_link_hash_table *htab = elf_hash_table (info); - const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd); - bfd_vma static_tls_size; - - /* If tls_segment is NULL, we should have signalled an error already. */ - if (htab->tls_sec == NULL) - return 0; - - /* Consider special static TLS alignment requirements. */ - static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment); - return address - static_tls_size - htab->tls_sec->vma; -} - -/* Is the instruction before OFFSET in CONTENTS a 32bit relative - branch? */ - -static bfd_boolean -is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset) -{ - /* Opcode Instruction - 0xe8 call - 0xe9 jump - 0x0f 0x8x conditional jump */ - return ((offset > 0 - && (contents [offset - 1] == 0xe8 - || contents [offset - 1] == 0xe9)) - || (offset > 1 - && contents [offset - 2] == 0x0f - && (contents [offset - 1] & 0xf0) == 0x80)); -} - -/* Relocate an x86_64 ELF section. */ - -static bfd_boolean -elf_x86_64_relocate_section (bfd *output_bfd, - struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, - asection **local_sections) -{ - struct elf_x86_64_link_hash_table *htab; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - bfd_vma *local_tlsdesc_gotents; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - BFD_ASSERT (is_x86_64_elf (input_bfd)); - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - symtab_hdr = &elf_symtab_hdr (input_bfd); - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - local_tlsdesc_gotents = elf_x86_64_local_tlsdesc_gotent (input_bfd); - - elf_x86_64_set_tls_module_base (info); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - unsigned int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma off, offplt; - bfd_vma relocation; - bfd_boolean unresolved_reloc; - bfd_reloc_status_type r; - int tls_type; - asection *base_got; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type == (int) R_X86_64_GNU_VTINHERIT - || r_type == (int) R_X86_64_GNU_VTENTRY) - continue; - - if (r_type >= R_X86_64_max) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - if (r_type != (int) R_X86_64_32 - || ABI_64_P (output_bfd)) - howto = x86_64_elf_howto_table + r_type; - else - howto = (x86_64_elf_howto_table - + ARRAY_SIZE (x86_64_elf_howto_table) - 1); - r_symndx = htab->r_sym (rel->r_info); - h = NULL; - sym = NULL; - sec = NULL; - unresolved_reloc = FALSE; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, - &sec, rel); - - /* Relocate against local STT_GNU_IFUNC symbol. */ - if (!info->relocatable - && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) - { - h = elf_x86_64_get_local_sym_hash (htab, input_bfd, - rel, FALSE); - if (h == NULL) - abort (); - - /* Set STT_GNU_IFUNC symbol value. */ - h->root.u.def.value = sym->st_value; - h->root.u.def.section = sec; - } - } - else - { - bfd_boolean warned ATTRIBUTE_UNUSED; - - RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, - r_symndx, symtab_hdr, sym_hashes, - h, sec, relocation, - unresolved_reloc, warned); - } - - if (sec != NULL && elf_discarded_section (sec)) - RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, relend, howto, contents); - - if (info->relocatable) - continue; - - if (rel->r_addend == 0 - && r_type == R_X86_64_64 - && !ABI_64_P (output_bfd)) - { - /* For x32, treat R_X86_64_64 like R_X86_64_32 and zero-extend - it to 64bit if addend is zero. */ - r_type = R_X86_64_32; - memset (contents + rel->r_offset + 4, 0, 4); - } - - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle - it here if it is defined in a non-shared object. */ - if (h != NULL - && h->type == STT_GNU_IFUNC - && h->def_regular) - { - asection *plt; - bfd_vma plt_index; - const char *name; - - if ((input_section->flags & SEC_ALLOC) == 0 - || h->plt.offset == (bfd_vma) -1) - abort (); - - /* STT_GNU_IFUNC symbol must go through PLT. */ - plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; - relocation = (plt->output_section->vma - + plt->output_offset + h->plt.offset); - - switch (r_type) - { - default: - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, - NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' isn't handled by %s"), input_bfd, - x86_64_elf_howto_table[r_type].name, - name, __FUNCTION__); - bfd_set_error (bfd_error_bad_value); - return FALSE; - - case R_X86_64_32S: - if (info->shared) - abort (); - goto do_relocation; - - case R_X86_64_32: - if (ABI_64_P (output_bfd)) - goto do_relocation; - /* FALLTHROUGH */ - case R_X86_64_64: - if (rel->r_addend != 0) - { - if (h->root.root.string) - name = h->root.root.string; - else - name = bfd_elf_sym_name (input_bfd, symtab_hdr, - sym, NULL); - (*_bfd_error_handler) - (_("%B: relocation %s against STT_GNU_IFUNC " - "symbol `%s' has non-zero addend: %d"), - input_bfd, x86_64_elf_howto_table[r_type].name, - name, rel->r_addend); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* Generate dynamic relcoation only when there is a - non-GOF reference in a shared object. */ - if (info->shared && h->non_got_ref) - { - Elf_Internal_Rela outrel; - asection *sreloc; - - /* Need a dynamic relocation to get the real function - address. */ - outrel.r_offset = _bfd_elf_section_offset (output_bfd, - info, - input_section, - rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1 - || outrel.r_offset == (bfd_vma) -2) - abort (); - - outrel.r_offset += (input_section->output_section->vma - + input_section->output_offset); - - if (h->dynindx == -1 - || h->forced_local - || info->executable) - { - /* This symbol is resolved locally. */ - outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE); - outrel.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - outrel.r_info = htab->r_info (h->dynindx, r_type); - outrel.r_addend = 0; - } - - sreloc = htab->elf.irelifunc; - elf_append_rela (output_bfd, sreloc, &outrel); - - /* If this reloc is against an external symbol, we - do not want to fiddle with the addend. Otherwise, - we need to include the symbol value so that it - becomes an addend for the dynamic reloc. For an - internal symbol, we have updated addend. */ - continue; - } - /* FALLTHROUGH */ - case R_X86_64_PC32: - case R_X86_64_PC64: - case R_X86_64_PLT32: - goto do_relocation; - - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCREL64: - base_got = htab->elf.sgot; - off = h->got.offset; - - if (base_got == NULL) - abort (); - - if (off == (bfd_vma) -1) - { - /* We can't use h->got.offset here to save state, or - even just remember the offset, as finish_dynamic_symbol - would use that as offset into .got. */ - - if (htab->elf.splt != NULL) - { - plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; - off = (plt_index + 3) * GOT_ENTRY_SIZE; - base_got = htab->elf.sgotplt; - } - else - { - plt_index = h->plt.offset / PLT_ENTRY_SIZE; - off = plt_index * GOT_ENTRY_SIZE; - base_got = htab->elf.igotplt; - } - - if (h->dynindx == -1 - || h->forced_local - || info->symbolic) - { - /* This references the local defitionion. We must - initialize this entry in the global offset table. - Since the offset must always be a multiple of 8, - we use the least significant bit to record - whether we have initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_64 (output_bfd, relocation, - base_got->contents + off); - /* Note that this is harmless for the GOTPLT64 - case, as -1 | 1 still is -1. */ - h->got.offset |= 1; - } - } - } - - relocation = (base_got->output_section->vma - + base_got->output_offset + off); - - goto do_relocation; - } - } - - /* When generating a shared object, the relocations handled here are - copied into the output file to be resolved at run time. */ - switch (r_type) - { - case R_X86_64_GOT32: - case R_X86_64_GOT64: - /* Relocation is to the entry for this symbol in the global - offset table. */ - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCREL64: - /* Use global offset table entry as symbol value. */ - case R_X86_64_GOTPLT64: - /* This is the same as GOT64 for relocation purposes, but - indicates the existence of a PLT entry. The difficulty is, - that we must calculate the GOT slot offset from the PLT - offset, if this symbol got a PLT entry (it was global). - Additionally if it's computed from the PLT entry, then that - GOT offset is relative to .got.plt, not to .got. */ - base_got = htab->elf.sgot; - - if (htab->elf.sgot == NULL) - abort (); - - if (h != NULL) - { - bfd_boolean dyn; - - off = h->got.offset; - if (h->needs_plt - && h->plt.offset != (bfd_vma)-1 - && off == (bfd_vma)-1) - { - /* We can't use h->got.offset here to save - state, or even just remember the offset, as - finish_dynamic_symbol would use that as offset into - .got. */ - bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; - off = (plt_index + 3) * GOT_ENTRY_SIZE; - base_got = htab->elf.sgotplt; - } - - dyn = htab->elf.dynamic_sections_created; - - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) - || (info->shared - && SYMBOL_REFERENCES_LOCAL (info, h)) - || (ELF_ST_VISIBILITY (h->other) - && h->root.type == bfd_link_hash_undefweak)) - { - /* This is actually a static link, or it is a -Bsymbolic - link and the symbol is defined locally, or the symbol - was forced to be local because of a version file. We - must initialize this entry in the global offset table. - Since the offset must always be a multiple of 8, we - use the least significant bit to record whether we - have initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This is - done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_64 (output_bfd, relocation, - base_got->contents + off); - /* Note that this is harmless for the GOTPLT64 case, - as -1 | 1 still is -1. */ - h->got.offset |= 1; - } - } - else - unresolved_reloc = FALSE; - } - else - { - if (local_got_offsets == NULL) - abort (); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 8. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_64 (output_bfd, relocation, - base_got->contents + off); - - if (info->shared) - { - asection *s; - Elf_Internal_Rela outrel; - - /* We need to generate a R_X86_64_RELATIVE reloc - for the dynamic linker. */ - s = htab->elf.srelgot; - if (s == NULL) - abort (); - - outrel.r_offset = (base_got->output_section->vma - + base_got->output_offset - + off); - outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); - outrel.r_addend = relocation; - elf_append_rela (output_bfd, s, &outrel); - } - - local_got_offsets[r_symndx] |= 1; - } - } - - if (off >= (bfd_vma) -2) - abort (); - - relocation = base_got->output_section->vma - + base_got->output_offset + off; - if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64) - relocation -= htab->elf.sgotplt->output_section->vma - - htab->elf.sgotplt->output_offset; - - break; - - case R_X86_64_GOTOFF64: - /* Relocation is relative to the start of the global offset - table. */ - - /* Check to make sure it isn't a protected function symbol - for shared library since it may not be local when used - as function address. */ - if (info->shared - && h - && h->def_regular - && h->type == STT_FUNC - && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) - { - (*_bfd_error_handler) - (_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"), - input_bfd, h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* Note that sgot is not involved in this - calculation. We always want the start of .got.plt. If we - defined _GLOBAL_OFFSET_TABLE_ in a different way, as is - permitted by the ABI, we might have to change this - calculation. */ - relocation -= htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - break; - - case R_X86_64_GOTPC32: - case R_X86_64_GOTPC64: - /* Use global offset table as symbol value. */ - relocation = htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - unresolved_reloc = FALSE; - break; - - case R_X86_64_PLTOFF64: - /* Relocation is PLT entry relative to GOT. For local - symbols it's the symbol itself relative to GOT. */ - if (h != NULL - /* See PLT32 handling. */ - && h->plt.offset != (bfd_vma) -1 - && htab->elf.splt != NULL) - { - relocation = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + h->plt.offset); - unresolved_reloc = FALSE; - } - - relocation -= htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset; - break; - - case R_X86_64_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLT32 reloc against a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt.offset == (bfd_vma) -1 - || htab->elf.splt == NULL) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - relocation = (htab->elf.splt->output_section->vma - + htab->elf.splt->output_offset - + h->plt.offset); - unresolved_reloc = FALSE; - break; - - case R_X86_64_PC8: - case R_X86_64_PC16: - case R_X86_64_PC32: - if (info->shared - && ABI_64_P (output_bfd) - && (input_section->flags & SEC_ALLOC) != 0 - && (input_section->flags & SEC_READONLY) != 0 - && h != NULL) - { - bfd_boolean fail = FALSE; - bfd_boolean branch - = (r_type == R_X86_64_PC32 - && is_32bit_relative_branch (contents, rel->r_offset)); - - if (SYMBOL_REFERENCES_LOCAL (info, h)) - { - /* Symbol is referenced locally. Make sure it is - defined locally or for a branch. */ - fail = !h->def_regular && !branch; - } - else - { - /* Symbol isn't referenced locally. We only allow - branch to symbol with non-default visibility. */ - fail = (!branch - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT); - } - - if (fail) - { - const char *fmt; - const char *v; - const char *pic = ""; - - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_HIDDEN: - v = _("hidden symbol"); - break; - case STV_INTERNAL: - v = _("internal symbol"); - break; - case STV_PROTECTED: - v = _("protected symbol"); - break; - default: - v = _("symbol"); - pic = _("; recompile with -fPIC"); - break; - } - - if (h->def_regular) - fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s"); - else - fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"); - - (*_bfd_error_handler) (fmt, input_bfd, - x86_64_elf_howto_table[r_type].name, - v, h->root.root.string, pic); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - } - /* Fall through. */ - - case R_X86_64_8: - case R_X86_64_16: - case R_X86_64_32: - case R_X86_64_PC64: - case R_X86_64_64: - /* FIXME: The ABI says the linker should make sure the value is - the same when it's zeroextended to 64 bit. */ - - if ((input_section->flags & SEC_ALLOC) == 0) - break; - - if ((info->shared - && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak) - && (! IS_X86_64_PCREL_TYPE (r_type) - || ! SYMBOL_CALLS_LOCAL (info, h))) - || (ELIMINATE_COPY_RELOCS - && !info->shared - && h != NULL - && h->dynindx != -1 - && !h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_undefined))) - { - Elf_Internal_Rela outrel; - bfd_boolean skip, relocate; - asection *sreloc; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - skip = FALSE; - relocate = FALSE; - - outrel.r_offset = - _bfd_elf_section_offset (output_bfd, info, input_section, - rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1) - skip = TRUE; - else if (outrel.r_offset == (bfd_vma) -2) - skip = TRUE, relocate = TRUE; - - outrel.r_offset += (input_section->output_section->vma - + input_section->output_offset); - - if (skip) - memset (&outrel, 0, sizeof outrel); - - /* h->dynindx may be -1 if this symbol was marked to - become local. */ - else if (h != NULL - && h->dynindx != -1 - && (IS_X86_64_PCREL_TYPE (r_type) - || ! info->shared - || ! SYMBOLIC_BIND (info, h) - || ! h->def_regular)) - { - outrel.r_info = htab->r_info (h->dynindx, r_type); - outrel.r_addend = rel->r_addend; - } - else - { - /* This symbol is local, or marked to become local. */ - if (r_type == htab->pointer_r_type) - { - relocate = TRUE; - outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - } - else if (r_type == R_X86_64_64 - && !ABI_64_P (output_bfd)) - { - relocate = TRUE; - outrel.r_info = htab->r_info (0, - R_X86_64_RELATIVE64); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - long sindx; - - if (bfd_is_abs_section (sec)) - sindx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - else - { - asection *osec; - - /* We are turning this relocation into one - against a section symbol. It would be - proper to subtract the symbol's value, - osec->vma, from the emitted reloc addend, - but ld.so expects buggy relocs. */ - osec = sec->output_section; - sindx = elf_section_data (osec)->dynindx; - if (sindx == 0) - { - asection *oi = htab->elf.text_index_section; - sindx = elf_section_data (oi)->dynindx; - } - BFD_ASSERT (sindx != 0); - } - - outrel.r_info = htab->r_info (sindx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - } - - sreloc = elf_section_data (input_section)->sreloc; - - if (sreloc == NULL || sreloc->contents == NULL) - { - r = bfd_reloc_notsupported; - goto check_relocation_error; - } - - elf_append_rela (output_bfd, sreloc, &outrel); - - /* If this reloc is against an external symbol, we do - not want to fiddle with the addend. Otherwise, we - need to include the symbol value so that it becomes - an addend for the dynamic reloc. */ - if (! relocate) - continue; - } - - break; - - case R_X86_64_TLSGD: - case R_X86_64_GOTPC32_TLSDESC: - case R_X86_64_TLSDESC_CALL: - case R_X86_64_GOTTPOFF: - tls_type = GOT_UNKNOWN; - if (h == NULL && local_got_offsets) - tls_type = elf_x86_64_local_got_tls_type (input_bfd) [r_symndx]; - else if (h != NULL) - tls_type = elf_x86_64_hash_entry (h)->tls_type; - - if (! elf_x86_64_tls_transition (info, input_bfd, - input_section, contents, - symtab_hdr, sym_hashes, - &r_type, tls_type, rel, - relend, h, r_symndx)) - return FALSE; - - if (r_type == R_X86_64_TPOFF32) - { - bfd_vma roff = rel->r_offset; - - BFD_ASSERT (! unresolved_reloc); - - if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD) - { - /* GD->LE transition. For 64bit, change - .byte 0x66; leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr - into: - movq %fs:0, %rax - leaq foo@tpoff(%rax), %rax - For 32bit, change - leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr - into: - movl %fs:0, %eax - leaq foo@tpoff(%rax), %rax */ - if (ABI_64_P (output_bfd)) - memcpy (contents + roff - 4, - "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0", - 16); - else - memcpy (contents + roff - 3, - "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0", - 15); - bfd_put_32 (output_bfd, - elf_x86_64_tpoff (info, relocation), - contents + roff + 8); - /* Skip R_X86_64_PC32/R_X86_64_PLT32. */ - rel++; - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC) - { - /* GDesc -> LE transition. - It's originally something like: - leaq x@tlsdesc(%rip), %rax - - Change it to: - movl $x@tpoff, %rax. */ - - unsigned int val, type; - - type = bfd_get_8 (input_bfd, contents + roff - 3); - val = bfd_get_8 (input_bfd, contents + roff - 1); - bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1), - contents + roff - 3); - bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); - bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), - contents + roff - 1); - bfd_put_32 (output_bfd, - elf_x86_64_tpoff (info, relocation), - contents + roff); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL) - { - /* GDesc -> LE transition. - It's originally: - call *(%rax) - Turn it into: - xchg %ax,%ax. */ - bfd_put_8 (output_bfd, 0x66, contents + roff); - bfd_put_8 (output_bfd, 0x90, contents + roff + 1); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF) - { - /* IE->LE transition: - Originally it can be one of: - movq foo@gottpoff(%rip), %reg - addq foo@gottpoff(%rip), %reg - We change it into: - movq $foo, %reg - leaq foo(%reg), %reg - addq $foo, %reg. */ - - unsigned int val, type, reg; - - val = bfd_get_8 (input_bfd, contents + roff - 3); - type = bfd_get_8 (input_bfd, contents + roff - 2); - reg = bfd_get_8 (input_bfd, contents + roff - 1); - reg >>= 3; - if (type == 0x8b) - { - /* movq */ - if (val == 0x4c) - bfd_put_8 (output_bfd, 0x49, - contents + roff - 3); - else if (!ABI_64_P (output_bfd) && val == 0x44) - bfd_put_8 (output_bfd, 0x41, - contents + roff - 3); - bfd_put_8 (output_bfd, 0xc7, - contents + roff - 2); - bfd_put_8 (output_bfd, 0xc0 | reg, - contents + roff - 1); - } - else if (reg == 4) - { - /* addq -> addq - addressing with %rsp/%r12 is - special */ - if (val == 0x4c) - bfd_put_8 (output_bfd, 0x49, - contents + roff - 3); - else if (!ABI_64_P (output_bfd) && val == 0x44) - bfd_put_8 (output_bfd, 0x41, - contents + roff - 3); - bfd_put_8 (output_bfd, 0x81, - contents + roff - 2); - bfd_put_8 (output_bfd, 0xc0 | reg, - contents + roff - 1); - } - else - { - /* addq -> leaq */ - if (val == 0x4c) - bfd_put_8 (output_bfd, 0x4d, - contents + roff - 3); - else if (!ABI_64_P (output_bfd) && val == 0x44) - bfd_put_8 (output_bfd, 0x45, - contents + roff - 3); - bfd_put_8 (output_bfd, 0x8d, - contents + roff - 2); - bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3), - contents + roff - 1); - } - bfd_put_32 (output_bfd, - elf_x86_64_tpoff (info, relocation), - contents + roff); - continue; - } - else - BFD_ASSERT (FALSE); - } - - if (htab->elf.sgot == NULL) - abort (); - - if (h != NULL) - { - off = h->got.offset; - offplt = elf_x86_64_hash_entry (h)->tlsdesc_got; - } - else - { - if (local_got_offsets == NULL) - abort (); - - off = local_got_offsets[r_symndx]; - offplt = local_tlsdesc_gotents[r_symndx]; - } - - if ((off & 1) != 0) - off &= ~1; - else - { - Elf_Internal_Rela outrel; - int dr_type, indx; - asection *sreloc; - - if (htab->elf.srelgot == NULL) - abort (); - - indx = h && h->dynindx != -1 ? h->dynindx : 0; - - if (GOT_TLS_GDESC_P (tls_type)) - { - outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC); - BFD_ASSERT (htab->sgotplt_jump_table_size + offplt - + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size); - outrel.r_offset = (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + offplt - + htab->sgotplt_jump_table_size); - sreloc = htab->elf.srelplt; - if (indx == 0) - outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info); - else - outrel.r_addend = 0; - elf_append_rela (output_bfd, sreloc, &outrel); - } - - sreloc = htab->elf.srelgot; - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off); - - if (GOT_TLS_GD_P (tls_type)) - dr_type = R_X86_64_DTPMOD64; - else if (GOT_TLS_GDESC_P (tls_type)) - goto dr_done; - else - dr_type = R_X86_64_TPOFF64; - - bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off); - outrel.r_addend = 0; - if ((dr_type == R_X86_64_TPOFF64 - || dr_type == R_X86_64_TLSDESC) && indx == 0) - outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info); - outrel.r_info = htab->r_info (indx, dr_type); - - elf_append_rela (output_bfd, sreloc, &outrel); - - if (GOT_TLS_GD_P (tls_type)) - { - if (indx == 0) - { - BFD_ASSERT (! unresolved_reloc); - bfd_put_64 (output_bfd, - relocation - elf_x86_64_dtpoff_base (info), - htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); - } - else - { - bfd_put_64 (output_bfd, 0, - htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); - outrel.r_info = htab->r_info (indx, - R_X86_64_DTPOFF64); - outrel.r_offset += GOT_ENTRY_SIZE; - elf_append_rela (output_bfd, sreloc, - &outrel); - } - } - - dr_done: - if (h != NULL) - h->got.offset |= 1; - else - local_got_offsets[r_symndx] |= 1; - } - - if (off >= (bfd_vma) -2 - && ! GOT_TLS_GDESC_P (tls_type)) - abort (); - if (r_type == ELF32_R_TYPE (rel->r_info)) - { - if (r_type == R_X86_64_GOTPC32_TLSDESC - || r_type == R_X86_64_TLSDESC_CALL) - relocation = htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + offplt + htab->sgotplt_jump_table_size; - else - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off; - unresolved_reloc = FALSE; - } - else - { - bfd_vma roff = rel->r_offset; - - if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD) - { - /* GD->IE transition. For 64bit, change - .byte 0x66; leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr@plt - into: - movq %fs:0, %rax - addq foo@gottpoff(%rip), %rax - For 32bit, change - leaq foo@tlsgd(%rip), %rdi - .word 0x6666; rex64; call __tls_get_addr@plt - into: - movl %fs:0, %eax - addq foo@gottpoff(%rip), %rax */ - if (ABI_64_P (output_bfd)) - memcpy (contents + roff - 4, - "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0", - 16); - else - memcpy (contents + roff - 3, - "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0", - 15); - - relocation = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - roff - - input_section->output_section->vma - - input_section->output_offset - - 12); - bfd_put_32 (output_bfd, relocation, - contents + roff + 8); - /* Skip R_X86_64_PLT32. */ - rel++; - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC) - { - /* GDesc -> IE transition. - It's originally something like: - leaq x@tlsdesc(%rip), %rax - - Change it to: - movq x@gottpoff(%rip), %rax # before xchg %ax,%ax. */ - - /* Now modify the instruction as appropriate. To - turn a leaq into a movq in the form we use it, it - suffices to change the second byte from 0x8d to - 0x8b. */ - bfd_put_8 (output_bfd, 0x8b, contents + roff - 2); - - bfd_put_32 (output_bfd, - htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off - - rel->r_offset - - input_section->output_section->vma - - input_section->output_offset - - 4, - contents + roff); - continue; - } - else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL) - { - /* GDesc -> IE transition. - It's originally: - call *(%rax) - - Change it to: - xchg %ax, %ax. */ - - bfd_put_8 (output_bfd, 0x66, contents + roff); - bfd_put_8 (output_bfd, 0x90, contents + roff + 1); - continue; - } - else - BFD_ASSERT (FALSE); - } - break; - - case R_X86_64_TLSLD: - if (! elf_x86_64_tls_transition (info, input_bfd, - input_section, contents, - symtab_hdr, sym_hashes, - &r_type, GOT_UNKNOWN, - rel, relend, h, r_symndx)) - return FALSE; - - if (r_type != R_X86_64_TLSLD) - { - /* LD->LE transition: - leaq foo@tlsld(%rip), %rdi; call __tls_get_addr. - For 64bit, we change it into: - .word 0x6666; .byte 0x66; movq %fs:0, %rax. - For 32bit, we change it into: - nopl 0x0(%rax); movl %fs:0, %eax. */ - - BFD_ASSERT (r_type == R_X86_64_TPOFF32); - if (ABI_64_P (output_bfd)) - memcpy (contents + rel->r_offset - 3, - "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12); - else - memcpy (contents + rel->r_offset - 3, - "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12); - /* Skip R_X86_64_PC32/R_X86_64_PLT32. */ - rel++; - continue; - } - - if (htab->elf.sgot == NULL) - abort (); - - off = htab->tls_ld_got.offset; - if (off & 1) - off &= ~1; - else - { - Elf_Internal_Rela outrel; - - if (htab->elf.srelgot == NULL) - abort (); - - outrel.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off); - - bfd_put_64 (output_bfd, 0, - htab->elf.sgot->contents + off); - bfd_put_64 (output_bfd, 0, - htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); - outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64); - outrel.r_addend = 0; - elf_append_rela (output_bfd, htab->elf.srelgot, - &outrel); - htab->tls_ld_got.offset |= 1; - } - relocation = htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset + off; - unresolved_reloc = FALSE; - break; - - case R_X86_64_DTPOFF32: - if (!info->executable|| (input_section->flags & SEC_CODE) == 0) - relocation -= elf_x86_64_dtpoff_base (info); - else - relocation = elf_x86_64_tpoff (info, relocation); - break; - - case R_X86_64_TPOFF32: - case R_X86_64_TPOFF64: - BFD_ASSERT (info->executable); - relocation = elf_x86_64_tpoff (info, relocation); - break; - - default: - break; - } - - /* Dynamic relocs are not propagated for SEC_DEBUGGING sections - because such sections are not SEC_ALLOC and thus ld.so will - not process them. */ - if (unresolved_reloc - && !((input_section->flags & SEC_DEBUGGING) != 0 - && h->def_dynamic)) - (*_bfd_error_handler) - (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), - input_bfd, - input_section, - (long) rel->r_offset, - howto->name, - h->root.root.string); - -do_relocation: - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - -check_relocation_error: - if (r != bfd_reloc_ok) - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return FALSE; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - - if (r == bfd_reloc_overflow) - { - if (! ((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, howto->name, - (bfd_vma) 0, input_bfd, input_section, - rel->r_offset))) - return FALSE; - } - else - { - (*_bfd_error_handler) - (_("%B(%A+0x%lx): reloc against `%s': error %d"), - input_bfd, input_section, - (long) rel->r_offset, name, (int) r); - return FALSE; - } - } - } - - return TRUE; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static bfd_boolean -elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, - struct bfd_link_info *info, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - struct elf_x86_64_link_hash_table *htab; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - if (h->plt.offset != (bfd_vma) -1) - { - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rela rela; - bfd_byte *loc; - asection *plt, *gotplt, *relplt; - const struct elf_backend_data *bed; - - /* When building a static executable, use .iplt, .igot.plt and - .rela.iplt sections for STT_GNU_IFUNC symbols. */ - if (htab->elf.splt != NULL) - { - plt = htab->elf.splt; - gotplt = htab->elf.sgotplt; - relplt = htab->elf.srelplt; - } - else - { - plt = htab->elf.iplt; - gotplt = htab->elf.igotplt; - relplt = htab->elf.irelplt; - } - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - if ((h->dynindx == -1 - && !((h->forced_local || info->executable) - && h->def_regular - && h->type == STT_GNU_IFUNC)) - || plt == NULL - || gotplt == NULL - || relplt == NULL) - return FALSE; - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. - - Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is GOT_ENTRY_SIZE - bytes. The first three are reserved for the dynamic linker. - - For static executables, we don't reserve anything. */ - - if (plt == htab->elf.splt) - { - plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; - got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; - } - else - { - plt_index = h->plt.offset / PLT_ENTRY_SIZE; - got_offset = plt_index * GOT_ENTRY_SIZE; - } - - /* Fill in the entry in the procedure linkage table. */ - memcpy (plt->contents + h->plt.offset, elf_x86_64_plt_entry, - PLT_ENTRY_SIZE); - - /* Insert the relocation positions of the plt section. The magic - numbers at the end of the statements are the positions of the - relocations in the plt section. */ - /* Put offset for jmp *name@GOTPCREL(%rip), since the - instruction uses 6 bytes, subtract this value. */ - bfd_put_32 (output_bfd, - (gotplt->output_section->vma - + gotplt->output_offset - + got_offset - - plt->output_section->vma - - plt->output_offset - - h->plt.offset - - 6), - plt->contents + h->plt.offset + 2); - - /* Don't fill PLT entry for static executables. */ - if (plt == htab->elf.splt) - { - /* Put relocation index. */ - bfd_put_32 (output_bfd, plt_index, - plt->contents + h->plt.offset + 7); - /* Put offset for jmp .PLT0. */ - bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE), - plt->contents + h->plt.offset + 12); - } - - /* Fill in the entry in the global offset table, initially this - points to the pushq instruction in the PLT which is at offset 6. */ - bfd_put_64 (output_bfd, (plt->output_section->vma - + plt->output_offset - + h->plt.offset + 6), - gotplt->contents + got_offset); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (gotplt->output_section->vma - + gotplt->output_offset - + got_offset); - if (h->dynindx == -1 - || ((info->executable - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular - && h->type == STT_GNU_IFUNC)) - { - /* If an STT_GNU_IFUNC symbol is locally defined, generate - R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */ - rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE); - rela.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT); - rela.r_addend = 0; - } - - bed = get_elf_backend_data (output_bfd); - loc = relplt->contents + plt_index * bed->s->sizeof_rela; - bed->s->swap_reloca_out (output_bfd, &rela, loc); - - if (!h->def_regular) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value if there were any - relocations where pointer equality matters (this is a clue - for the dynamic linker, to make function pointer - comparisons work between an application and shared - library), otherwise set it to zero. If a function is only - called from a binary, there is no need to slow down - shared libraries because of that. */ - sym->st_shndx = SHN_UNDEF; - if (!h->pointer_equality_needed) - sym->st_value = 0; - } - } - - if (h->got.offset != (bfd_vma) -1 - && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type) - && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE) - { - Elf_Internal_Rela rela; - - /* This symbol has an entry in the global offset table. Set it - up. */ - if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL) - abort (); - - rela.r_offset = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + (h->got.offset &~ (bfd_vma) 1)); - - /* If this is a static link, or it is a -Bsymbolic link and the - symbol is defined locally or was forced to be local because - of a version file, we just want to emit a RELATIVE reloc. - The entry in the global offset table will already have been - initialized in the relocate_section function. */ - if (h->def_regular - && h->type == STT_GNU_IFUNC) - { - if (info->shared) - { - /* Generate R_X86_64_GLOB_DAT. */ - goto do_glob_dat; - } - else - { - asection *plt; - - if (!h->pointer_equality_needed) - abort (); - - /* For non-shared object, we can't use .got.plt, which - contains the real function addres if we need pointer - equality. We load the GOT entry with the PLT entry. */ - plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; - bfd_put_64 (output_bfd, (plt->output_section->vma - + plt->output_offset - + h->plt.offset), - htab->elf.sgot->contents + h->got.offset); - return TRUE; - } - } - else if (info->shared - && SYMBOL_REFERENCES_LOCAL (info, h)) - { - if (!h->def_regular) - return FALSE; - BFD_ASSERT((h->got.offset & 1) != 0); - rela.r_info = htab->r_info (0, R_X86_64_RELATIVE); - rela.r_addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - BFD_ASSERT((h->got.offset & 1) == 0); -do_glob_dat: - bfd_put_64 (output_bfd, (bfd_vma) 0, - htab->elf.sgot->contents + h->got.offset); - rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT); - rela.r_addend = 0; - } - - elf_append_rela (output_bfd, htab->elf.srelgot, &rela); - } - - if (h->needs_copy) - { - Elf_Internal_Rela rela; - - /* This symbol needs a copy reloc. Set it up. */ - - if (h->dynindx == -1 - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - || htab->srelbss == NULL) - abort (); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY); - rela.r_addend = 0; - elf_append_rela (output_bfd, htab->srelbss, &rela); - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may - be NULL for local symbols. */ - if (sym != NULL - && (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || h == htab->elf.hgot)) - sym->st_shndx = SHN_ABS; - - return TRUE; -} - -/* Finish up local dynamic symbol handling. We set the contents of - various dynamic sections here. */ - -static bfd_boolean -elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf) -{ - struct elf_link_hash_entry *h - = (struct elf_link_hash_entry *) *slot; - struct bfd_link_info *info - = (struct bfd_link_info *) inf; - - return elf_x86_64_finish_dynamic_symbol (info->output_bfd, - info, h, NULL); -} - -/* Used to decide how to sort relocs in an optimal manner for the - dynamic linker, before writing them out. */ - -static enum elf_reloc_type_class -elf_x86_64_reloc_type_class (const Elf_Internal_Rela *rela) -{ - switch ((int) ELF32_R_TYPE (rela->r_info)) - { - case R_X86_64_RELATIVE: - return reloc_class_relative; - case R_X86_64_JUMP_SLOT: - return reloc_class_plt; - case R_X86_64_COPY: - return reloc_class_copy; - default: - return reloc_class_normal; - } -} - -/* Finish up the dynamic sections. */ - -static bfd_boolean -elf_x86_64_finish_dynamic_sections (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_x86_64_link_hash_table *htab; - bfd *dynobj; - asection *sdyn; - - htab = elf_x86_64_hash_table (info); - if (htab == NULL) - return FALSE; - - dynobj = htab->elf.dynobj; - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (htab->elf.dynamic_sections_created) - { - bfd_byte *dyncon, *dynconend; - const struct elf_backend_data *bed; - bfd_size_type sizeof_dyn; - - if (sdyn == NULL || htab->elf.sgot == NULL) - abort (); - - bed = get_elf_backend_data (dynobj); - sizeof_dyn = bed->s->sizeof_dyn; - dyncon = sdyn->contents; - dynconend = sdyn->contents + sdyn->size; - for (; dyncon < dynconend; dyncon += sizeof_dyn) - { - Elf_Internal_Dyn dyn; - asection *s; - - (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - continue; - - case DT_PLTGOT: - s = htab->elf.sgotplt; - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; - break; - - case DT_JMPREL: - dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma; - break; - - case DT_PLTRELSZ: - s = htab->elf.srelplt->output_section; - dyn.d_un.d_val = s->size; - break; - - case DT_RELASZ: - /* The procedure linkage table relocs (DT_JMPREL) should - not be included in the overall relocs (DT_RELA). - Therefore, we override the DT_RELASZ entry here to - make it not include the JMPREL relocs. Since the - linker script arranges for .rela.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_RELA entry. */ - if (htab->elf.srelplt != NULL) - { - s = htab->elf.srelplt->output_section; - dyn.d_un.d_val -= s->size; - } - break; - - case DT_TLSDESC_PLT: - s = htab->elf.splt; - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset - + htab->tlsdesc_plt; - break; - - case DT_TLSDESC_GOT: - s = htab->elf.sgot; - dyn.d_un.d_ptr = s->output_section->vma + s->output_offset - + htab->tlsdesc_got; - break; - } - - (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon); - } - - /* Fill in the special first entry in the procedure linkage table. */ - if (htab->elf.splt && htab->elf.splt->size > 0) - { - /* Fill in the first entry in the procedure linkage table. */ - memcpy (htab->elf.splt->contents, elf_x86_64_plt0_entry, - PLT_ENTRY_SIZE); - /* Add offset for pushq GOT+8(%rip), since the instruction - uses 6 bytes subtract this value. */ - bfd_put_32 (output_bfd, - (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + 8 - - htab->elf.splt->output_section->vma - - htab->elf.splt->output_offset - - 6), - htab->elf.splt->contents + 2); - /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to - the end of the instruction. */ - bfd_put_32 (output_bfd, - (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + 16 - - htab->elf.splt->output_section->vma - - htab->elf.splt->output_offset - - 12), - htab->elf.splt->contents + 8); - - elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize = - PLT_ENTRY_SIZE; - - if (htab->tlsdesc_plt) - { - bfd_put_64 (output_bfd, (bfd_vma) 0, - htab->elf.sgot->contents + htab->tlsdesc_got); - - memcpy (htab->elf.splt->contents + htab->tlsdesc_plt, - elf_x86_64_plt0_entry, - PLT_ENTRY_SIZE); - - /* Add offset for pushq GOT+8(%rip), since the - instruction uses 6 bytes subtract this value. */ - bfd_put_32 (output_bfd, - (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset - + 8 - - htab->elf.splt->output_section->vma - - htab->elf.splt->output_offset - - htab->tlsdesc_plt - - 6), - htab->elf.splt->contents + htab->tlsdesc_plt + 2); - /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for - htab->tlsdesc_got. The 12 is the offset to the end of - the instruction. */ - bfd_put_32 (output_bfd, - (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + htab->tlsdesc_got - - htab->elf.splt->output_section->vma - - htab->elf.splt->output_offset - - htab->tlsdesc_plt - - 12), - htab->elf.splt->contents + htab->tlsdesc_plt + 8); - } - } - } - - if (htab->elf.sgotplt) - { - if (bfd_is_abs_section (htab->elf.sgotplt->output_section)) - { - (*_bfd_error_handler) - (_("discarded output section: `%A'"), htab->elf.sgotplt); - return FALSE; - } - - /* Fill in the first three entries in the global offset table. */ - if (htab->elf.sgotplt->size > 0) - { - /* Set the first entry in the global offset table to the address of - the dynamic section. */ - if (sdyn == NULL) - bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents); - else - bfd_put_64 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - htab->elf.sgotplt->contents); - /* Write GOT[1] and GOT[2], needed for the dynamic linker. */ - bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE); - bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2); - } - - elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = - GOT_ENTRY_SIZE; - } - - /* Adjust .eh_frame for .plt section. */ - if (htab->plt_eh_frame != NULL) - { - if (htab->elf.splt != NULL - && htab->elf.splt->size != 0 - && (htab->elf.splt->flags & SEC_EXCLUDE) == 0 - && htab->elf.splt->output_section != NULL - && htab->plt_eh_frame->output_section != NULL) - { - bfd_vma plt_start = htab->elf.splt->output_section->vma; - bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma - + htab->plt_eh_frame->output_offset - + PLT_FDE_START_OFFSET; - bfd_put_signed_32 (dynobj, plt_start - eh_frame_start, - htab->plt_eh_frame->contents - + PLT_FDE_START_OFFSET); - } - if (htab->plt_eh_frame->sec_info_type - == ELF_INFO_TYPE_EH_FRAME) - { - if (! _bfd_elf_write_section_eh_frame (output_bfd, info, - htab->plt_eh_frame, - htab->plt_eh_frame->contents)) - return FALSE; - } - } - - if (htab->elf.sgot && htab->elf.sgot->size > 0) - elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize - = GOT_ENTRY_SIZE; - - /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ - htab_traverse (htab->loc_hash_table, - elf_x86_64_finish_local_dynamic_symbol, - info); - - return TRUE; -} - -/* Return address for Ith PLT stub in section PLT, for relocation REL - or (bfd_vma) -1 if it should not be included. */ - -static bfd_vma -elf_x86_64_plt_sym_val (bfd_vma i, const asection *plt, - const arelent *rel ATTRIBUTE_UNUSED) -{ - return plt->vma + (i + 1) * PLT_ENTRY_SIZE; -} - -/* Handle an x86-64 specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. */ - -static bfd_boolean -elf_x86_64_section_from_shdr (bfd *abfd, - Elf_Internal_Shdr *hdr, - const char *name, - int shindex) -{ - if (hdr->sh_type != SHT_X86_64_UNWIND) - return FALSE; - - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) - return FALSE; - - return TRUE; -} - -/* Hook called by the linker routine which adds symbols from an object - file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead - of .bss. */ - -static bfd_boolean -elf_x86_64_add_symbol_hook (bfd *abfd, - struct bfd_link_info *info, - Elf_Internal_Sym *sym, - const char **namep ATTRIBUTE_UNUSED, - flagword *flagsp ATTRIBUTE_UNUSED, - asection **secp, - bfd_vma *valp) -{ - asection *lcomm; - - switch (sym->st_shndx) - { - case SHN_X86_64_LCOMMON: - lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON"); - if (lcomm == NULL) - { - lcomm = bfd_make_section_with_flags (abfd, - "LARGE_COMMON", - (SEC_ALLOC - | SEC_IS_COMMON - | SEC_LINKER_CREATED)); - if (lcomm == NULL) - return FALSE; - elf_section_flags (lcomm) |= SHF_X86_64_LARGE; - } - *secp = lcomm; - *valp = sym->st_size; - return TRUE; - } - - if ((abfd->flags & DYNAMIC) == 0 - && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC - || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)) - elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE; - - return TRUE; -} - - -/* Given a BFD section, try to locate the corresponding ELF section - index. */ - -static bfd_boolean -elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec, int *index_return) -{ - if (sec == &_bfd_elf_large_com_section) - { - *index_return = SHN_X86_64_LCOMMON; - return TRUE; - } - return FALSE; -} - -/* Process a symbol. */ - -static void -elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, - asymbol *asym) -{ - elf_symbol_type *elfsym = (elf_symbol_type *) asym; - - switch (elfsym->internal_elf_sym.st_shndx) - { - case SHN_X86_64_LCOMMON: - asym->section = &_bfd_elf_large_com_section; - asym->value = elfsym->internal_elf_sym.st_size; - /* Common symbol doesn't set BSF_GLOBAL. */ - asym->flags &= ~BSF_GLOBAL; - break; - } -} - -static bfd_boolean -elf_x86_64_common_definition (Elf_Internal_Sym *sym) -{ - return (sym->st_shndx == SHN_COMMON - || sym->st_shndx == SHN_X86_64_LCOMMON); -} - -static unsigned int -elf_x86_64_common_section_index (asection *sec) -{ - if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) - return SHN_COMMON; - else - return SHN_X86_64_LCOMMON; -} - -static asection * -elf_x86_64_common_section (asection *sec) -{ - if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) - return bfd_com_section_ptr; - else - return &_bfd_elf_large_com_section; -} - -static bfd_boolean -elf_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, - struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym, - asection **psec, - bfd_vma *pvalue ATTRIBUTE_UNUSED, - unsigned int *pold_alignment ATTRIBUTE_UNUSED, - bfd_boolean *skip ATTRIBUTE_UNUSED, - bfd_boolean *override ATTRIBUTE_UNUSED, - bfd_boolean *type_change_ok ATTRIBUTE_UNUSED, - bfd_boolean *size_change_ok ATTRIBUTE_UNUSED, - bfd_boolean *newdyn ATTRIBUTE_UNUSED, - bfd_boolean *newdef, - bfd_boolean *newdyncommon ATTRIBUTE_UNUSED, - bfd_boolean *newweak ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection **sec, - bfd_boolean *olddyn ATTRIBUTE_UNUSED, - bfd_boolean *olddef, - bfd_boolean *olddyncommon ATTRIBUTE_UNUSED, - bfd_boolean *oldweak ATTRIBUTE_UNUSED, - bfd *oldbfd, - asection **oldsec) -{ - /* A normal common symbol and a large common symbol result in a - normal common symbol. We turn the large common symbol into a - normal one. */ - if (!*olddef - && h->root.type == bfd_link_hash_common - && !*newdef - && bfd_is_com_section (*sec) - && *oldsec != *sec) - { - if (sym->st_shndx == SHN_COMMON - && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0) - { - h->root.u.c.p->section - = bfd_make_section_old_way (oldbfd, "COMMON"); - h->root.u.c.p->section->flags = SEC_ALLOC; - } - else if (sym->st_shndx == SHN_X86_64_LCOMMON - && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) == 0) - *psec = *sec = bfd_com_section_ptr; - } - - return TRUE; -} - -static int -elf_x86_64_additional_program_headers (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - asection *s; - int count = 0; - - /* Check to see if we need a large readonly segment. */ - s = bfd_get_section_by_name (abfd, ".lrodata"); - if (s && (s->flags & SEC_LOAD)) - count++; - - /* Check to see if we need a large data segment. Since .lbss sections - is placed right after the .bss section, there should be no need for - a large data segment just because of .lbss. */ - s = bfd_get_section_by_name (abfd, ".ldata"); - if (s && (s->flags & SEC_LOAD)) - count++; - - return count; -} - -/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ - -static bfd_boolean -elf_x86_64_hash_symbol (struct elf_link_hash_entry *h) -{ - if (h->plt.offset != (bfd_vma) -1 - && !h->def_regular - && !h->pointer_equality_needed) - return FALSE; - - return _bfd_elf_hash_symbol (h); -} - -/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */ - -static bfd_boolean -elf_x86_64_relocs_compatible (const bfd_target *input, - const bfd_target *output) -{ - return ((xvec_get_elf_backend_data (input)->s->elfclass - == xvec_get_elf_backend_data (output)->s->elfclass) - && _bfd_elf_relocs_compatible (input, output)); -} - -static const struct bfd_elf_special_section - elf_x86_64_special_sections[]= -{ - { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, - { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, - { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE}, - { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, - { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, - { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, - { NULL, 0, 0, 0, 0 } -}; - -#define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec -#define TARGET_LITTLE_NAME "elf64-x86-64" -#define ELF_ARCH bfd_arch_i386 -#define ELF_TARGET_ID X86_64_ELF_DATA -#define ELF_MACHINE_CODE EM_X86_64 -#define ELF_MAXPAGESIZE 0x200000 -#define ELF_MINPAGESIZE 0x1000 -#define ELF_COMMONPAGESIZE 0x1000 - -#define elf_backend_can_gc_sections 1 -#define elf_backend_can_refcount 1 -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 -#define elf_backend_got_header_size (GOT_ENTRY_SIZE*3) -#define elf_backend_rela_normal 1 -#define elf_backend_plt_alignment 4 - -#define elf_info_to_howto elf_x86_64_info_to_howto - -#define bfd_elf64_bfd_link_hash_table_create \ - elf_x86_64_link_hash_table_create -#define bfd_elf64_bfd_link_hash_table_free \ - elf_x86_64_link_hash_table_free -#define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup -#define bfd_elf64_bfd_reloc_name_lookup \ - elf_x86_64_reloc_name_lookup - -#define elf_backend_adjust_dynamic_symbol elf_x86_64_adjust_dynamic_symbol -#define elf_backend_relocs_compatible elf_x86_64_relocs_compatible -#define elf_backend_check_relocs elf_x86_64_check_relocs -#define elf_backend_copy_indirect_symbol elf_x86_64_copy_indirect_symbol -#define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections -#define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections -#define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol -#define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook -#define elf_backend_gc_sweep_hook elf_x86_64_gc_sweep_hook -#define elf_backend_grok_prstatus elf_x86_64_grok_prstatus -#define elf_backend_grok_psinfo elf_x86_64_grok_psinfo -#ifdef CORE_HEADER -#define elf_backend_write_core_note elf_x86_64_write_core_note -#endif -#define elf_backend_reloc_type_class elf_x86_64_reloc_type_class -#define elf_backend_relocate_section elf_x86_64_relocate_section -#define elf_backend_size_dynamic_sections elf_x86_64_size_dynamic_sections -#define elf_backend_always_size_sections elf_x86_64_always_size_sections -#define elf_backend_init_index_section _bfd_elf_init_1_index_section -#define elf_backend_plt_sym_val elf_x86_64_plt_sym_val -#define elf_backend_object_p elf64_x86_64_elf_object_p -#define bfd_elf64_mkobject elf_x86_64_mkobject - -#define elf_backend_section_from_shdr \ - elf_x86_64_section_from_shdr - -#define elf_backend_section_from_bfd_section \ - elf_x86_64_elf_section_from_bfd_section -#define elf_backend_add_symbol_hook \ - elf_x86_64_add_symbol_hook -#define elf_backend_symbol_processing \ - elf_x86_64_symbol_processing -#define elf_backend_common_section_index \ - elf_x86_64_common_section_index -#define elf_backend_common_section \ - elf_x86_64_common_section -#define elf_backend_common_definition \ - elf_x86_64_common_definition -#define elf_backend_merge_symbol \ - elf_x86_64_merge_symbol -#define elf_backend_special_sections \ - elf_x86_64_special_sections -#define elf_backend_additional_program_headers \ - elf_x86_64_additional_program_headers -#define elf_backend_hash_symbol \ - elf_x86_64_hash_symbol - -#define elf_backend_post_process_headers _bfd_elf_set_osabi - -#include "elf64-target.h" - -/* FreeBSD support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_x86_64_freebsd_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-x86-64-freebsd" - -#undef ELF_OSABI -#define ELF_OSABI ELFOSABI_FREEBSD - -#undef elf64_bed -#define elf64_bed elf64_x86_64_fbsd_bed - -#include "elf64-target.h" - -/* Solaris 2 support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_x86_64_sol2_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-x86-64-sol2" - -/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE - objects won't be recognized. */ -#undef ELF_OSABI - -#undef elf64_bed -#define elf64_bed elf64_x86_64_sol2_bed - -/* The 64-bit static TLS arena size is rounded to the nearest 16-byte - boundary. */ -#undef elf_backend_static_tls_alignment -#define elf_backend_static_tls_alignment 16 - -/* The Solaris 2 ABI requires a plt symbol on all platforms. - - Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output - File, p.63. */ -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 1 - -#include "elf64-target.h" - -/* Intel L1OM support. */ - -static bfd_boolean -elf64_l1om_elf_object_p (bfd *abfd) -{ - /* Set the right machine number for an L1OM elf64 file. */ - bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om); - return TRUE; -} - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_l1om_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-l1om" -#undef ELF_ARCH -#define ELF_ARCH bfd_arch_l1om - -#undef ELF_MACHINE_CODE -#define ELF_MACHINE_CODE EM_L1OM - -#undef ELF_OSABI - -#undef elf64_bed -#define elf64_bed elf64_l1om_bed - -#undef elf_backend_object_p -#define elf_backend_object_p elf64_l1om_elf_object_p - -#undef elf_backend_static_tls_alignment - -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 - -#include "elf64-target.h" - -/* FreeBSD L1OM support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_l1om_freebsd_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-l1om-freebsd" - -#undef ELF_OSABI -#define ELF_OSABI ELFOSABI_FREEBSD - -#undef elf64_bed -#define elf64_bed elf64_l1om_fbsd_bed - -#include "elf64-target.h" - -/* Intel K1OM support. */ - -static bfd_boolean -elf64_k1om_elf_object_p (bfd *abfd) -{ - /* Set the right machine number for an K1OM elf64 file. */ - bfd_default_set_arch_mach (abfd, bfd_arch_k1om, bfd_mach_k1om); - return TRUE; -} - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_k1om_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-k1om" -#undef ELF_ARCH -#define ELF_ARCH bfd_arch_k1om - -#undef ELF_MACHINE_CODE -#define ELF_MACHINE_CODE EM_K1OM - -#undef ELF_OSABI - -#undef elf64_bed -#define elf64_bed elf64_k1om_bed - -#undef elf_backend_object_p -#define elf_backend_object_p elf64_k1om_elf_object_p - -#undef elf_backend_static_tls_alignment - -#undef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 - -#include "elf64-target.h" - -/* FreeBSD K1OM support. */ - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf64_k1om_freebsd_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf64-k1om-freebsd" - -#undef ELF_OSABI -#define ELF_OSABI ELFOSABI_FREEBSD - -#undef elf64_bed -#define elf64_bed elf64_k1om_fbsd_bed - -#include "elf64-target.h" - -/* 32bit x86-64 support. */ - -static bfd_boolean -elf32_x86_64_elf_object_p (bfd *abfd) -{ - /* Set the right machine number for an x86-64 elf32 file. */ - bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32); - return TRUE; -} - -#undef TARGET_LITTLE_SYM -#define TARGET_LITTLE_SYM bfd_elf32_x86_64_vec -#undef TARGET_LITTLE_NAME -#define TARGET_LITTLE_NAME "elf32-x86-64" - -#undef ELF_ARCH -#define ELF_ARCH bfd_arch_i386 - -#undef ELF_MACHINE_CODE -#define ELF_MACHINE_CODE EM_X86_64 - -#define bfd_elf32_bfd_link_hash_table_create \ - elf_x86_64_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free \ - elf_x86_64_link_hash_table_free -#define bfd_elf32_bfd_reloc_type_lookup \ - elf_x86_64_reloc_type_lookup -#define bfd_elf32_bfd_reloc_name_lookup \ - elf_x86_64_reloc_name_lookup -#define bfd_elf32_mkobject \ - elf_x86_64_mkobject - -#undef ELF_OSABI - -#undef elf_backend_object_p -#define elf_backend_object_p \ - elf32_x86_64_elf_object_p - -#undef elf_backend_bfd_from_remote_memory -#define elf_backend_bfd_from_remote_memory \ - _bfd_elf32_bfd_from_remote_memory - -#undef elf_backend_size_info -#define elf_backend_size_info \ - _bfd_elf32_size_info - -#include "elf32-target.h" diff --git a/contrib/binutils-2.22/bfd/elf64.c b/contrib/binutils-2.22/bfd/elf64.c deleted file mode 100644 index 04fd3f0b41..0000000000 --- a/contrib/binutils-2.22/bfd/elf64.c +++ /dev/null @@ -1,23 +0,0 @@ -/* ELF 64-bit executable support for BFD. - Copyright 1993, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#define ARCH_SIZE 64 - -#include "elfcode.h" diff --git a/contrib/binutils-2.22/bfd/elfcode.h b/contrib/binutils-2.22/bfd/elfcode.h deleted file mode 100644 index b7e022614c..0000000000 --- a/contrib/binutils-2.22/bfd/elfcode.h +++ /dev/null @@ -1,1860 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". Sufficient support for gdb. - - Rewritten by Mark Eichin @ Cygnus Support, from information - published in "System V Application Binary Interface", chapters 4 - and 5, as well as the various "Processor Supplement" documents - derived from it. Added support for assembler and other object file - utilities. Further work done by Ken Raeburn (Cygnus Support), Michael - Meissner (Open Software Foundation), and Peter Hoogenboom (University - of Utah) to finish and extend this. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Problems and other issues to resolve. - - (1) BFD expects there to be some fixed number of "sections" in - the object file. I.E. there is a "section_count" variable in the - bfd structure which contains the number of sections. However, ELF - supports multiple "views" of a file. In particular, with current - implementations, executable files typically have two tables, a - program header table and a section header table, both of which - partition the executable. - - In ELF-speak, the "linking view" of the file uses the section header - table to access "sections" within the file, and the "execution view" - uses the program header table to access "segments" within the file. - "Segments" typically may contain all the data from one or more - "sections". - - Note that the section header table is optional in ELF executables, - but it is this information that is most useful to gdb. If the - section header table is missing, then gdb should probably try - to make do with the program header table. (FIXME) - - (2) The code in this file is compiled twice, once in 32-bit mode and - once in 64-bit mode. More of it should be made size-independent - and moved into elf.c. - - (3) ELF section symbols are handled rather sloppily now. This should - be cleaned up, and ELF section symbols reconciled with BFD section - symbols. - - (4) We need a published spec for 64-bit ELF. We've got some stuff here - that we're using for SPARC V9 64-bit chips, but don't assume that - it's cast in stone. - */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* Renaming structures, typedefs, macros and functions to be size-specific. */ -#define Elf_External_Ehdr NAME(Elf,External_Ehdr) -#define Elf_External_Sym NAME(Elf,External_Sym) -#define Elf_External_Shdr NAME(Elf,External_Shdr) -#define Elf_External_Phdr NAME(Elf,External_Phdr) -#define Elf_External_Rel NAME(Elf,External_Rel) -#define Elf_External_Rela NAME(Elf,External_Rela) -#define Elf_External_Dyn NAME(Elf,External_Dyn) - -#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) -#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) -#define elf_core_file_matches_executable_p \ - NAME(bfd_elf,core_file_matches_executable_p) -#define elf_core_file_pid NAME(bfd_elf,core_file_pid) -#define elf_object_p NAME(bfd_elf,object_p) -#define elf_core_file_p NAME(bfd_elf,core_file_p) -#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) -#define elf_get_dynamic_symtab_upper_bound \ - NAME(bfd_elf,get_dynamic_symtab_upper_bound) -#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in) -#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in) -#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out) -#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out) -#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in) -#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out) -#define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in) -#define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out) -#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in) -#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) -#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) -#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) -#define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table) -#define elf_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab) -#define elf_canonicalize_dynamic_symtab \ - NAME(bfd_elf,canonicalize_dynamic_symtab) -#define elf_get_synthetic_symtab \ - NAME(bfd_elf,get_synthetic_symtab) -#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) -#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) -#define elf_get_lineno NAME(bfd_elf,get_lineno) -#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach) -#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line) -#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers) -#define elf_set_section_contents NAME(bfd_elf,set_section_contents) -#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) -#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) -#define elf_find_section NAME(bfd_elf,find_section) -#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr) -#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs) -#define elf_checksum_contents NAME(bfd_elf,checksum_contents) -#define elf_write_relocs NAME(bfd_elf,write_relocs) -#define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table) - -#if ARCH_SIZE == 64 -#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF64_R_SYM(X) -#define ELF_R_TYPE(X) ELF64_R_TYPE(X) -#define ELFCLASS ELFCLASS64 -#define FILE_ALIGN 8 -#define LOG_FILE_ALIGN 3 -#endif -#if ARCH_SIZE == 32 -#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF32_R_SYM(X) -#define ELF_R_TYPE(X) ELF32_R_TYPE(X) -#define ELFCLASS ELFCLASS32 -#define FILE_ALIGN 4 -#define LOG_FILE_ALIGN 2 -#endif - -#if DEBUG & 2 -static void elf_debug_section (int, Elf_Internal_Shdr *); -#endif -#if DEBUG & 1 -static void elf_debug_file (Elf_Internal_Ehdr *); -#endif - -/* Structure swapping routines */ - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define H_PUT_WORD H_PUT_64 -#define H_PUT_SIGNED_WORD H_PUT_S64 -#define H_GET_WORD H_GET_64 -#define H_GET_SIGNED_WORD H_GET_S64 -#endif -#if ARCH_SIZE == 32 -#define H_PUT_WORD H_PUT_32 -#define H_PUT_SIGNED_WORD H_PUT_S32 -#define H_GET_WORD H_GET_32 -#define H_GET_SIGNED_WORD H_GET_S32 -#endif - -/* Translate an ELF symbol in external format into an ELF symbol in internal - format. */ - -bfd_boolean -elf_swap_symbol_in (bfd *abfd, - const void *psrc, - const void *pshn, - Elf_Internal_Sym *dst) -{ - const Elf_External_Sym *src = (const Elf_External_Sym *) psrc; - const Elf_External_Sym_Shndx *shndx = (const Elf_External_Sym_Shndx *) pshn; - int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; - - dst->st_name = H_GET_32 (abfd, src->st_name); - if (signed_vma) - dst->st_value = H_GET_SIGNED_WORD (abfd, src->st_value); - else - dst->st_value = H_GET_WORD (abfd, src->st_value); - dst->st_size = H_GET_WORD (abfd, src->st_size); - dst->st_info = H_GET_8 (abfd, src->st_info); - dst->st_other = H_GET_8 (abfd, src->st_other); - dst->st_shndx = H_GET_16 (abfd, src->st_shndx); - if (dst->st_shndx == (SHN_XINDEX & 0xffff)) - { - if (shndx == NULL) - return FALSE; - dst->st_shndx = H_GET_32 (abfd, shndx->est_shndx); - } - else if (dst->st_shndx >= (SHN_LORESERVE & 0xffff)) - dst->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); - dst->st_target_internal = 0; - return TRUE; -} - -/* Translate an ELF symbol in internal format into an ELF symbol in external - format. */ - -void -elf_swap_symbol_out (bfd *abfd, - const Elf_Internal_Sym *src, - void *cdst, - void *shndx) -{ - unsigned int tmp; - Elf_External_Sym *dst = (Elf_External_Sym *) cdst; - H_PUT_32 (abfd, src->st_name, dst->st_name); - H_PUT_WORD (abfd, src->st_value, dst->st_value); - H_PUT_WORD (abfd, src->st_size, dst->st_size); - H_PUT_8 (abfd, src->st_info, dst->st_info); - H_PUT_8 (abfd, src->st_other, dst->st_other); - tmp = src->st_shndx; - if (tmp >= (SHN_LORESERVE & 0xffff) && tmp < SHN_LORESERVE) - { - if (shndx == NULL) - abort (); - H_PUT_32 (abfd, tmp, shndx); - tmp = SHN_XINDEX & 0xffff; - } - H_PUT_16 (abfd, tmp, dst->st_shndx); -} - -/* Translate an ELF file header in external format into an ELF file header in - internal format. */ - -static void -elf_swap_ehdr_in (bfd *abfd, - const Elf_External_Ehdr *src, - Elf_Internal_Ehdr *dst) -{ - int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - dst->e_type = H_GET_16 (abfd, src->e_type); - dst->e_machine = H_GET_16 (abfd, src->e_machine); - dst->e_version = H_GET_32 (abfd, src->e_version); - if (signed_vma) - dst->e_entry = H_GET_SIGNED_WORD (abfd, src->e_entry); - else - dst->e_entry = H_GET_WORD (abfd, src->e_entry); - dst->e_phoff = H_GET_WORD (abfd, src->e_phoff); - dst->e_shoff = H_GET_WORD (abfd, src->e_shoff); - dst->e_flags = H_GET_32 (abfd, src->e_flags); - dst->e_ehsize = H_GET_16 (abfd, src->e_ehsize); - dst->e_phentsize = H_GET_16 (abfd, src->e_phentsize); - dst->e_phnum = H_GET_16 (abfd, src->e_phnum); - dst->e_shentsize = H_GET_16 (abfd, src->e_shentsize); - dst->e_shnum = H_GET_16 (abfd, src->e_shnum); - dst->e_shstrndx = H_GET_16 (abfd, src->e_shstrndx); -} - -/* Translate an ELF file header in internal format into an ELF file header in - external format. */ - -static void -elf_swap_ehdr_out (bfd *abfd, - const Elf_Internal_Ehdr *src, - Elf_External_Ehdr *dst) -{ - unsigned int tmp; - int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - /* note that all elements of dst are *arrays of unsigned char* already... */ - H_PUT_16 (abfd, src->e_type, dst->e_type); - H_PUT_16 (abfd, src->e_machine, dst->e_machine); - H_PUT_32 (abfd, src->e_version, dst->e_version); - if (signed_vma) - H_PUT_SIGNED_WORD (abfd, src->e_entry, dst->e_entry); - else - H_PUT_WORD (abfd, src->e_entry, dst->e_entry); - H_PUT_WORD (abfd, src->e_phoff, dst->e_phoff); - H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff); - H_PUT_32 (abfd, src->e_flags, dst->e_flags); - H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize); - H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize); - tmp = src->e_phnum; - if (tmp > PN_XNUM) - tmp = PN_XNUM; - H_PUT_16 (abfd, tmp, dst->e_phnum); - H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize); - tmp = src->e_shnum; - if (tmp >= (SHN_LORESERVE & 0xffff)) - tmp = SHN_UNDEF; - H_PUT_16 (abfd, tmp, dst->e_shnum); - tmp = src->e_shstrndx; - if (tmp >= (SHN_LORESERVE & 0xffff)) - tmp = SHN_XINDEX & 0xffff; - H_PUT_16 (abfd, tmp, dst->e_shstrndx); -} - -/* Translate an ELF section header table entry in external format into an - ELF section header table entry in internal format. */ - -static void -elf_swap_shdr_in (bfd *abfd, - const Elf_External_Shdr *src, - Elf_Internal_Shdr *dst) -{ - int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; - - dst->sh_name = H_GET_32 (abfd, src->sh_name); - dst->sh_type = H_GET_32 (abfd, src->sh_type); - dst->sh_flags = H_GET_WORD (abfd, src->sh_flags); - if (signed_vma) - dst->sh_addr = H_GET_SIGNED_WORD (abfd, src->sh_addr); - else - dst->sh_addr = H_GET_WORD (abfd, src->sh_addr); - dst->sh_offset = H_GET_WORD (abfd, src->sh_offset); - dst->sh_size = H_GET_WORD (abfd, src->sh_size); - dst->sh_link = H_GET_32 (abfd, src->sh_link); - dst->sh_info = H_GET_32 (abfd, src->sh_info); - dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign); - dst->sh_entsize = H_GET_WORD (abfd, src->sh_entsize); - dst->bfd_section = NULL; - dst->contents = NULL; -} - -/* Translate an ELF section header table entry in internal format into an - ELF section header table entry in external format. */ - -static void -elf_swap_shdr_out (bfd *abfd, - const Elf_Internal_Shdr *src, - Elf_External_Shdr *dst) -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - H_PUT_32 (abfd, src->sh_name, dst->sh_name); - H_PUT_32 (abfd, src->sh_type, dst->sh_type); - H_PUT_WORD (abfd, src->sh_flags, dst->sh_flags); - H_PUT_WORD (abfd, src->sh_addr, dst->sh_addr); - H_PUT_WORD (abfd, src->sh_offset, dst->sh_offset); - H_PUT_WORD (abfd, src->sh_size, dst->sh_size); - H_PUT_32 (abfd, src->sh_link, dst->sh_link); - H_PUT_32 (abfd, src->sh_info, dst->sh_info); - H_PUT_WORD (abfd, src->sh_addralign, dst->sh_addralign); - H_PUT_WORD (abfd, src->sh_entsize, dst->sh_entsize); -} - -/* Translate an ELF program header table entry in external format into an - ELF program header table entry in internal format. */ - -void -elf_swap_phdr_in (bfd *abfd, - const Elf_External_Phdr *src, - Elf_Internal_Phdr *dst) -{ - int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; - - dst->p_type = H_GET_32 (abfd, src->p_type); - dst->p_flags = H_GET_32 (abfd, src->p_flags); - dst->p_offset = H_GET_WORD (abfd, src->p_offset); - if (signed_vma) - { - dst->p_vaddr = H_GET_SIGNED_WORD (abfd, src->p_vaddr); - dst->p_paddr = H_GET_SIGNED_WORD (abfd, src->p_paddr); - } - else - { - dst->p_vaddr = H_GET_WORD (abfd, src->p_vaddr); - dst->p_paddr = H_GET_WORD (abfd, src->p_paddr); - } - dst->p_filesz = H_GET_WORD (abfd, src->p_filesz); - dst->p_memsz = H_GET_WORD (abfd, src->p_memsz); - dst->p_align = H_GET_WORD (abfd, src->p_align); -} - -void -elf_swap_phdr_out (bfd *abfd, - const Elf_Internal_Phdr *src, - Elf_External_Phdr *dst) -{ - const struct elf_backend_data *bed; - bfd_vma p_paddr; - - bed = get_elf_backend_data (abfd); - p_paddr = bed->want_p_paddr_set_to_zero ? 0 : src->p_paddr; - - /* note that all elements of dst are *arrays of unsigned char* already... */ - H_PUT_32 (abfd, src->p_type, dst->p_type); - H_PUT_WORD (abfd, src->p_offset, dst->p_offset); - H_PUT_WORD (abfd, src->p_vaddr, dst->p_vaddr); - H_PUT_WORD (abfd, p_paddr, dst->p_paddr); - H_PUT_WORD (abfd, src->p_filesz, dst->p_filesz); - H_PUT_WORD (abfd, src->p_memsz, dst->p_memsz); - H_PUT_32 (abfd, src->p_flags, dst->p_flags); - H_PUT_WORD (abfd, src->p_align, dst->p_align); -} - -/* Translate an ELF reloc from external format to internal format. */ -void -elf_swap_reloc_in (bfd *abfd, - const bfd_byte *s, - Elf_Internal_Rela *dst) -{ - const Elf_External_Rel *src = (const Elf_External_Rel *) s; - dst->r_offset = H_GET_WORD (abfd, src->r_offset); - dst->r_info = H_GET_WORD (abfd, src->r_info); - dst->r_addend = 0; -} - -void -elf_swap_reloca_in (bfd *abfd, - const bfd_byte *s, - Elf_Internal_Rela *dst) -{ - const Elf_External_Rela *src = (const Elf_External_Rela *) s; - dst->r_offset = H_GET_WORD (abfd, src->r_offset); - dst->r_info = H_GET_WORD (abfd, src->r_info); - dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend); -} - -/* Translate an ELF reloc from internal format to external format. */ -void -elf_swap_reloc_out (bfd *abfd, - const Elf_Internal_Rela *src, - bfd_byte *d) -{ - Elf_External_Rel *dst = (Elf_External_Rel *) d; - H_PUT_WORD (abfd, src->r_offset, dst->r_offset); - H_PUT_WORD (abfd, src->r_info, dst->r_info); -} - -void -elf_swap_reloca_out (bfd *abfd, - const Elf_Internal_Rela *src, - bfd_byte *d) -{ - Elf_External_Rela *dst = (Elf_External_Rela *) d; - H_PUT_WORD (abfd, src->r_offset, dst->r_offset); - H_PUT_WORD (abfd, src->r_info, dst->r_info); - H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend); -} - -void -elf_swap_dyn_in (bfd *abfd, - const void *p, - Elf_Internal_Dyn *dst) -{ - const Elf_External_Dyn *src = (const Elf_External_Dyn *) p; - - dst->d_tag = H_GET_WORD (abfd, src->d_tag); - dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val); -} - -void -elf_swap_dyn_out (bfd *abfd, - const Elf_Internal_Dyn *src, - void *p) -{ - Elf_External_Dyn *dst = (Elf_External_Dyn *) p; - - H_PUT_WORD (abfd, src->d_tag, dst->d_tag); - H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val); -} - -/* ELF .o/exec file reading */ - -/* Begin processing a given object. - - First we validate the file by reading in the ELF header and checking - the magic number. */ - -static inline bfd_boolean -elf_file_p (Elf_External_Ehdr *x_ehdrp) -{ - return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) - && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) - && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2) - && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); -} - -/* Check to see if the file associated with ABFD matches the target vector - that ABFD points to. - - Note that we may be called several times with the same ABFD, but different - target vectors, most of which will not match. We have to avoid leaving - any side effects in ABFD, or any data it points to (like tdata), if the - file does not match the target vector. */ - -const bfd_target * -elf_object_p (bfd *abfd) -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr x_shdr; /* Section header table entry, external form */ - Elf_Internal_Shdr i_shdr; - Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ - unsigned int shindex; - const struct elf_backend_data *ebd; - struct bfd_preserve preserve; - asection *s; - bfd_size_type amt; - const bfd_target *target; - - preserve.marker = NULL; - - /* Read in the ELF header in external format. */ - - if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - section header table (FIXME: See comments re sections at top of this - file). */ - - if (! elf_file_p (&x_ehdr) - || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT - || x_ehdr.e_ident[EI_CLASS] != ELFCLASS) - goto got_wrong_format_error; - - /* Check that file's byte order matches xvec's */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_header_big_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_header_little_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto got_wrong_format_error; - } - - if (!bfd_preserve_save (abfd, &preserve)) - goto got_no_match; - - target = abfd->xvec; - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - if (! (*target->_bfd_set_format[bfd_object]) (abfd)) - goto got_no_match; - preserve.marker = elf_tdata (abfd); - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - /* Reject ET_CORE (header indicates core file, not object file) */ - if (i_ehdrp->e_type == ET_CORE) - goto got_wrong_format_error; - - /* If this is a relocatable file and there is no section header - table, then we're hosed. */ - if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL) - goto got_wrong_format_error; - - /* As a simple sanity check, verify that what BFD thinks is the - size of each section header table entry actually matches the size - recorded in the file, but only if there are any sections. */ - if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0) - goto got_wrong_format_error; - - /* Further sanity check. */ - if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_shnum != 0) - goto got_wrong_format_error; - - ebd = get_elf_backend_data (abfd); - if (ebd->s->arch_size != ARCH_SIZE) - goto got_wrong_format_error; - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 - || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 - || i_ehdrp->e_machine != ebd->elf_machine_alt2) - && ebd->elf_machine_code != EM_NONE) - goto got_wrong_format_error; - - if (i_ehdrp->e_type == ET_EXEC) - abfd->flags |= EXEC_P; - else if (i_ehdrp->e_type == ET_DYN) - abfd->flags |= DYNAMIC; - - if (i_ehdrp->e_phnum > 0) - abfd->flags |= D_PAGED; - - if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)) - { - /* It's OK if this fails for the generic target. */ - if (ebd->elf_machine_code != EM_NONE) - goto got_no_match; - } - - if (ebd->elf_machine_code != EM_NONE - && i_ehdrp->e_ident[EI_OSABI] != ebd->elf_osabi - && ebd->elf_osabi != ELFOSABI_NONE) - goto got_wrong_format_error; - - if (i_ehdrp->e_shoff != 0) - { - bfd_signed_vma where = i_ehdrp->e_shoff; - - if (where != (file_ptr) where) - goto got_wrong_format_error; - - /* Seek to the section header table in the file. */ - if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) - goto got_no_match; - - /* Read the first section header at index 0, and convert to internal - form. */ - if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) - goto got_no_match; - elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); - - /* If the section count is zero, the actual count is in the first - section header. */ - if (i_ehdrp->e_shnum == SHN_UNDEF) - { - i_ehdrp->e_shnum = i_shdr.sh_size; - if (i_ehdrp->e_shnum != i_shdr.sh_size - || i_ehdrp->e_shnum == 0) - goto got_wrong_format_error; - } - - /* And similarly for the string table index. */ - if (i_ehdrp->e_shstrndx == (SHN_XINDEX & 0xffff)) - { - i_ehdrp->e_shstrndx = i_shdr.sh_link; - if (i_ehdrp->e_shstrndx != i_shdr.sh_link) - goto got_wrong_format_error; - } - - /* And program headers. */ - if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0) - { - i_ehdrp->e_phnum = i_shdr.sh_info; - if (i_ehdrp->e_phnum != i_shdr.sh_info) - goto got_wrong_format_error; - } - - /* Sanity check that we can read all of the section headers. - It ought to be good enough to just read the last one. */ - if (i_ehdrp->e_shnum != 1) - { - /* Check that we don't have a totally silly number of sections. */ - if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr) - || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr)) - goto got_wrong_format_error; - - where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr); - if (where != (file_ptr) where) - goto got_wrong_format_error; - if ((bfd_size_type) where <= i_ehdrp->e_shoff) - goto got_wrong_format_error; - - if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) - goto got_no_match; - if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) - goto got_no_match; - - /* Back to where we were. */ - where = i_ehdrp->e_shoff + sizeof (x_shdr); - if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) - goto got_no_match; - } - } - - /* Allocate space for a copy of the section header table in - internal form. */ - if (i_ehdrp->e_shnum != 0) - { - Elf_Internal_Shdr *shdrp; - unsigned int num_sec; - - amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum; - i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); - if (!i_shdrp) - goto got_no_match; - num_sec = i_ehdrp->e_shnum; - elf_numsections (abfd) = num_sec; - amt = sizeof (i_shdrp) * num_sec; - elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt); - if (!elf_elfsections (abfd)) - goto got_no_match; - - memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp)); - for (shdrp = i_shdrp, shindex = 0; shindex < num_sec; shindex++) - elf_elfsections (abfd)[shindex] = shdrp++; - - /* Read in the rest of the section header table and convert it - to internal form. */ - for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) - { - if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) - goto got_no_match; - elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); - - /* Sanity check sh_link and sh_info. */ - if (i_shdrp[shindex].sh_link >= num_sec) - { - /* PR 10478: Accept Solaris binaries with a sh_link - field set to SHN_BEFORE or SHN_AFTER. */ - switch (ebd->elf_machine_code) - { - case EM_386: - case EM_486: - case EM_X86_64: - case EM_OLD_SPARCV9: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - if (i_shdrp[shindex].sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */ - || i_shdrp[shindex].sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */) - break; - /* Otherwise fall through. */ - default: - goto got_wrong_format_error; - } - } - - if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK) - || i_shdrp[shindex].sh_type == SHT_RELA - || i_shdrp[shindex].sh_type == SHT_REL) - && i_shdrp[shindex].sh_info >= num_sec) - goto got_wrong_format_error; - - /* If the section is loaded, but not page aligned, clear - D_PAGED. */ - if (i_shdrp[shindex].sh_size != 0 - && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0 - && i_shdrp[shindex].sh_type != SHT_NOBITS - && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset) - % ebd->minpagesize) - != 0)) - abfd->flags &= ~D_PAGED; - } - } - - /* A further sanity check. */ - if (i_ehdrp->e_shnum != 0) - { - if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)) - { - /* PR 2257: - We used to just goto got_wrong_format_error here - but there are binaries in existance for which this test - will prevent the binutils from working with them at all. - So we are kind, and reset the string index value to 0 - so that at least some processing can be done. */ - i_ehdrp->e_shstrndx = SHN_UNDEF; - _bfd_error_handler (_("warning: %s has a corrupt string table index - ignoring"), abfd->filename); - } - } - else if (i_ehdrp->e_shstrndx != SHN_UNDEF) - goto got_wrong_format_error; - - /* Read in the program headers. */ - if (i_ehdrp->e_phnum == 0) - elf_tdata (abfd)->phdr = NULL; - else - { - Elf_Internal_Phdr *i_phdr; - unsigned int i; - - amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr); - elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); - if (elf_tdata (abfd)->phdr == NULL) - goto got_no_match; - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) - goto got_no_match; - i_phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++) - { - Elf_External_Phdr x_phdr; - - if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr) - goto got_no_match; - elf_swap_phdr_in (abfd, &x_phdr, i_phdr); - } - } - - if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0) - { - unsigned int num_sec; - - /* Once all of the section headers have been read and converted, we - can start processing them. Note that the first section header is - a dummy placeholder entry, so we ignore it. */ - num_sec = elf_numsections (abfd); - for (shindex = 1; shindex < num_sec; shindex++) - if (!bfd_section_from_shdr (abfd, shindex)) - goto got_no_match; - - /* Set up ELF sections for SHF_GROUP and SHF_LINK_ORDER. */ - if (! _bfd_elf_setup_sections (abfd)) - goto got_wrong_format_error; - } - - /* Let the backend double check the format and override global - information. */ - if (ebd->elf_backend_object_p) - { - if (! (*ebd->elf_backend_object_p) (abfd)) - goto got_wrong_format_error; - } - - /* Remember the entry point specified in the ELF file header. */ - bfd_set_start_address (abfd, i_ehdrp->e_entry); - - /* If we have created any reloc sections that are associated with - debugging sections, mark the reloc sections as debugging as well. */ - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL - || elf_section_data (s)->this_hdr.sh_type == SHT_RELA) - && elf_section_data (s)->this_hdr.sh_info > 0) - { - unsigned long targ_index; - asection *targ_sec; - - targ_index = elf_section_data (s)->this_hdr.sh_info; - targ_sec = bfd_section_from_elf_index (abfd, targ_index); - if (targ_sec != NULL - && (targ_sec->flags & SEC_DEBUGGING) != 0) - s->flags |= SEC_DEBUGGING; - } - } - - bfd_preserve_finish (abfd, &preserve); - return target; - - got_wrong_format_error: - /* There is way too much undoing of half-known state here. The caller, - bfd_check_format_matches, really shouldn't iterate on live bfd's to - check match/no-match like it does. We have to rely on that a call to - bfd_default_set_arch_mach with the previously known mach, undoes what - was done by the first bfd_default_set_arch_mach (with mach 0) here. - For this to work, only elf-data and the mach may be changed by the - target-specific elf_backend_object_p function. Note that saving the - whole bfd here and restoring it would be even worse; the first thing - you notice is that the cached bfd file position gets out of sync. */ - bfd_set_error (bfd_error_wrong_format); - - got_no_match: - if (preserve.marker != NULL) - bfd_preserve_restore (abfd, &preserve); - return NULL; -} - -/* ELF .o/exec file writing */ - -/* Write out the relocs. */ - -void -elf_write_relocs (bfd *abfd, asection *sec, void *data) -{ - bfd_boolean *failedp = (bfd_boolean *) data; - Elf_Internal_Shdr *rela_hdr; - bfd_vma addr_offset; - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - size_t extsize; - bfd_byte *dst_rela; - unsigned int idx; - asymbol *last_sym; - int last_sym_idx; - - /* If we have already failed, don't do anything. */ - if (*failedp) - return; - - if ((sec->flags & SEC_RELOC) == 0) - return; - - /* The linker backend writes the relocs out itself, and sets the - reloc_count field to zero to inhibit writing them here. Also, - sometimes the SEC_RELOC flag gets set even when there aren't any - relocs. */ - if (sec->reloc_count == 0) - return; - - /* If we have opened an existing file for update, reloc_count may be - set even though we are not linking. In that case we have nothing - to do. */ - if (sec->orelocation == NULL) - return; - - rela_hdr = elf_section_data (sec)->rela.hdr; - if (rela_hdr == NULL) - rela_hdr = elf_section_data (sec)->rel.hdr; - - rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; - rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size); - if (rela_hdr->contents == NULL) - { - *failedp = TRUE; - return; - } - - /* Figure out whether the relocations are RELA or REL relocations. */ - if (rela_hdr->sh_type == SHT_RELA) - { - swap_out = elf_swap_reloca_out; - extsize = sizeof (Elf_External_Rela); - } - else if (rela_hdr->sh_type == SHT_REL) - { - swap_out = elf_swap_reloc_out; - extsize = sizeof (Elf_External_Rel); - } - else - /* Every relocation section should be either an SHT_RELA or an - SHT_REL section. */ - abort (); - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a BFD reloc is always section relative. */ - addr_offset = 0; - if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) - addr_offset = sec->vma; - - /* orelocation has the data, reloc_count has the count... */ - last_sym = 0; - last_sym_idx = 0; - dst_rela = rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize) - { - Elf_Internal_Rela src_rela; - arelent *ptr; - asymbol *sym; - int n; - - ptr = sec->orelocation[idx]; - sym = *ptr->sym_ptr_ptr; - if (sym == last_sym) - n = last_sym_idx; - else if (bfd_is_abs_section (sym->section) && sym->value == 0) - n = STN_UNDEF; - else - { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); - if (n < 0) - { - *failedp = TRUE; - return; - } - last_sym_idx = n; - } - - if ((*ptr->sym_ptr_ptr)->the_bfd != NULL - && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! _bfd_elf_validate_reloc (abfd, ptr)) - { - *failedp = TRUE; - return; - } - - src_rela.r_offset = ptr->address + addr_offset; - src_rela.r_info = ELF_R_INFO (n, ptr->howto->type); - src_rela.r_addend = ptr->addend; - (*swap_out) (abfd, &src_rela, dst_rela); - } -} - -/* Write out the program headers. */ - -int -elf_write_out_phdrs (bfd *abfd, - const Elf_Internal_Phdr *phdr, - unsigned int count) -{ - while (count--) - { - Elf_External_Phdr extphdr; - elf_swap_phdr_out (abfd, phdr, &extphdr); - if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd) - != sizeof (Elf_External_Phdr)) - return -1; - phdr++; - } - return 0; -} - -/* Write out the section headers and the ELF file header. */ - -bfd_boolean -elf_write_shdrs_and_ehdr (bfd *abfd) -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr *x_shdrp; /* Section header table, external form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - unsigned int count; - bfd_size_type amt; - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - - /* swap the header before spitting it out... */ - -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); - amt = sizeof (x_ehdr); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_bwrite (&x_ehdr, amt, abfd) != amt) - return FALSE; - - /* Some fields in the first section header handle overflow of ehdr - fields. */ - if (i_ehdrp->e_phnum >= PN_XNUM) - i_shdrp[0]->sh_info = i_ehdrp->e_phnum; - if (i_ehdrp->e_shnum >= (SHN_LORESERVE & 0xffff)) - i_shdrp[0]->sh_size = i_ehdrp->e_shnum; - if (i_ehdrp->e_shstrndx >= (SHN_LORESERVE & 0xffff)) - i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx; - - /* at this point we've concocted all the ELF sections... */ - amt = i_ehdrp->e_shnum; - amt *= sizeof (*x_shdrp); - x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt); - if (!x_shdrp) - return FALSE; - - for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++) - { -#if DEBUG & 2 - elf_debug_section (count, *i_shdrp); -#endif - elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count); - } - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 - || bfd_bwrite (x_shdrp, amt, abfd) != amt) - return FALSE; - - /* need to dump the string table too... */ - - return TRUE; -} - -bfd_boolean -elf_checksum_contents (bfd *abfd, - void (*process) (const void *, size_t, void *), - void *arg) -{ - Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd); - Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd); - Elf_Internal_Phdr *i_phdrp = elf_tdata (abfd)->phdr; - unsigned int count, num; - - { - Elf_External_Ehdr x_ehdr; - Elf_Internal_Ehdr i_ehdr; - - i_ehdr = *i_ehdrp; - i_ehdr.e_phoff = i_ehdr.e_shoff = 0; - elf_swap_ehdr_out (abfd, &i_ehdr, &x_ehdr); - (*process) (&x_ehdr, sizeof x_ehdr, arg); - } - - num = i_ehdrp->e_phnum; - for (count = 0; count < num; count++) - { - Elf_External_Phdr x_phdr; - elf_swap_phdr_out (abfd, &i_phdrp[count], &x_phdr); - (*process) (&x_phdr, sizeof x_phdr, arg); - } - - num = elf_numsections (abfd); - for (count = 0; count < num; count++) - { - Elf_Internal_Shdr i_shdr; - Elf_External_Shdr x_shdr; - - i_shdr = *i_shdrp[count]; - i_shdr.sh_offset = 0; - - elf_swap_shdr_out (abfd, &i_shdr, &x_shdr); - (*process) (&x_shdr, sizeof x_shdr, arg); - - if (i_shdr.contents) - (*process) (i_shdr.contents, i_shdr.sh_size, arg); - } - - return TRUE; -} - -long -elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) -{ - Elf_Internal_Shdr *hdr; - Elf_Internal_Shdr *verhdr; - unsigned long symcount; /* Number of external ELF symbols */ - elf_symbol_type *sym; /* Pointer to current bfd symbol */ - elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - Elf_Internal_Sym *isymbuf = NULL; - Elf_External_Versym *xver; - Elf_External_Versym *xverbuf = NULL; - const struct elf_backend_data *ebd; - bfd_size_type amt; - - /* Read each raw ELF symbol, converting from external ELF form to - internal ELF form, and then using the information to create a - canonical bfd symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer - based on a one-to-one mapping of the ELF symbols to canonical - symbols. We actually use all the ELF symbols, so there will be no - space left over at the end. When we have all the symbols, we - build the caller's pointer vector. */ - - if (! dynamic) - { - hdr = &elf_tdata (abfd)->symtab_hdr; - verhdr = NULL; - } - else - { - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - if (elf_dynversym (abfd) == 0) - verhdr = NULL; - else - verhdr = &elf_tdata (abfd)->dynversym_hdr; - if ((elf_tdata (abfd)->dynverdef_section != 0 - && elf_tdata (abfd)->verdef == NULL) - || (elf_tdata (abfd)->dynverref_section != 0 - && elf_tdata (abfd)->verref == NULL)) - { - if (!_bfd_elf_slurp_version_tables (abfd, FALSE)) - return -1; - } - } - - ebd = get_elf_backend_data (abfd); - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - if (symcount == 0) - sym = symbase = NULL; - else - { - isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0, - NULL, NULL, NULL); - if (isymbuf == NULL) - return -1; - - amt = symcount; - amt *= sizeof (elf_symbol_type); - symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt); - if (symbase == (elf_symbol_type *) NULL) - goto error_return; - - /* Read the raw ELF version symbol information. */ - if (verhdr != NULL - && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount) - { - (*_bfd_error_handler) - (_("%s: version count (%ld) does not match symbol count (%ld)"), - abfd->filename, - (long) (verhdr->sh_size / sizeof (Elf_External_Versym)), - symcount); - - /* Slurp in the symbols without the version information, - since that is more helpful than just quitting. */ - verhdr = NULL; - } - - if (verhdr != NULL) - { - if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0) - goto error_return; - - xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size); - if (xverbuf == NULL && verhdr->sh_size != 0) - goto error_return; - - if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size) - goto error_return; - } - - /* Skip first symbol, which is a null dummy. */ - xver = xverbuf; - if (xver != NULL) - ++xver; - isymend = isymbuf + symcount; - for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++) - { - memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym)); - sym->symbol.the_bfd = abfd; - - sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL); - - sym->symbol.value = isym->st_value; - - if (isym->st_shndx == SHN_UNDEF) - { - sym->symbol.section = bfd_und_section_ptr; - } - else if (isym->st_shndx == SHN_ABS) - { - sym->symbol.section = bfd_abs_section_ptr; - } - else if (isym->st_shndx == SHN_COMMON) - { - sym->symbol.section = bfd_com_section_ptr; - if ((abfd->flags & BFD_PLUGIN) != 0) - { - asection *xc = bfd_get_section_by_name (abfd, "COMMON"); - - if (xc == NULL) - { - flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP - | SEC_EXCLUDE); - xc = bfd_make_section_with_flags (abfd, "COMMON", flags); - if (xc == NULL) - goto error_return; - } - sym->symbol.section = xc; - } - /* Elf puts the alignment into the `value' field, and - the size into the `size' field. BFD wants to see the - size in the value field, and doesn't care (at the - moment) about the alignment. */ - sym->symbol.value = isym->st_size; - } - else - { - sym->symbol.section - = bfd_section_from_elf_index (abfd, isym->st_shndx); - if (sym->symbol.section == NULL) - { - /* This symbol is in a section for which we did not - create a BFD section. Just use bfd_abs_section, - although it is wrong. FIXME. */ - sym->symbol.section = bfd_abs_section_ptr; - } - } - - /* If this is a relocatable file, then the symbol value is - already section relative. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) - sym->symbol.value -= sym->symbol.section->vma; - - switch (ELF_ST_BIND (isym->st_info)) - { - case STB_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - break; - case STB_GLOBAL: - if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON) - sym->symbol.flags |= BSF_GLOBAL; - break; - case STB_WEAK: - sym->symbol.flags |= BSF_WEAK; - break; - case STB_GNU_UNIQUE: - sym->symbol.flags |= BSF_GNU_UNIQUE; - break; - } - - switch (ELF_ST_TYPE (isym->st_info)) - { - case STT_SECTION: - sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING; - break; - case STT_FILE: - sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING; - break; - case STT_FUNC: - sym->symbol.flags |= BSF_FUNCTION; - break; - case STT_COMMON: - /* FIXME: Do we have to put the size field into the value field - as we do with symbols in SHN_COMMON sections (see above) ? */ - /* Fall through. */ - case STT_OBJECT: - sym->symbol.flags |= BSF_OBJECT; - break; - case STT_TLS: - sym->symbol.flags |= BSF_THREAD_LOCAL; - break; - case STT_RELC: - sym->symbol.flags |= BSF_RELC; - break; - case STT_SRELC: - sym->symbol.flags |= BSF_SRELC; - break; - case STT_GNU_IFUNC: - sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION; - break; - } - - if (dynamic) - sym->symbol.flags |= BSF_DYNAMIC; - - if (xver != NULL) - { - Elf_Internal_Versym iversym; - - _bfd_elf_swap_versym_in (abfd, xver, &iversym); - sym->version = iversym.vs_vers; - xver++; - } - - /* Do some backend-specific processing on this symbol. */ - if (ebd->elf_backend_symbol_processing) - (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol); - } - } - - /* Do some backend-specific processing on this symbol table. */ - if (ebd->elf_backend_symbol_table_processing) - (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount); - - /* We rely on the zalloc to clear out the final symbol entry. */ - - symcount = sym - symbase; - - /* Fill in the user's symbol pointer vector if needed. */ - if (symptrs) - { - long l = symcount; - - sym = symbase; - while (l-- > 0) - { - *symptrs++ = &sym->symbol; - sym++; - } - *symptrs = 0; /* Final null pointer */ - } - - if (xverbuf != NULL) - free (xverbuf); - if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf) - free (isymbuf); - return symcount; - -error_return: - if (xverbuf != NULL) - free (xverbuf); - if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf) - free (isymbuf); - return -1; -} - -/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of - them. */ - -static bfd_boolean -elf_slurp_reloc_table_from_section (bfd *abfd, - asection *asect, - Elf_Internal_Shdr *rel_hdr, - bfd_size_type reloc_count, - arelent *relents, - asymbol **symbols, - bfd_boolean dynamic) -{ - const struct elf_backend_data * const ebd = get_elf_backend_data (abfd); - void *allocated = NULL; - bfd_byte *native_relocs; - arelent *relent; - unsigned int i; - int entsize; - unsigned int symcount; - - allocated = bfd_malloc (rel_hdr->sh_size); - if (allocated == NULL) - goto error_return; - - if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_bread (allocated, rel_hdr->sh_size, abfd) - != rel_hdr->sh_size)) - goto error_return; - - native_relocs = (bfd_byte *) allocated; - - entsize = rel_hdr->sh_entsize; - BFD_ASSERT (entsize == sizeof (Elf_External_Rel) - || entsize == sizeof (Elf_External_Rela)); - - if (dynamic) - symcount = bfd_get_dynamic_symcount (abfd); - else - symcount = bfd_get_symcount (abfd); - - for (i = 0, relent = relents; - i < reloc_count; - i++, relent++, native_relocs += entsize) - { - Elf_Internal_Rela rela; - - if (entsize == sizeof (Elf_External_Rela)) - elf_swap_reloca_in (abfd, native_relocs, &rela); - else - elf_swap_reloc_in (abfd, native_relocs, &rela); - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a normal BFD reloc is always section relative, - and the address of a dynamic reloc is absolute.. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic) - relent->address = rela.r_offset; - else - relent->address = rela.r_offset - asect->vma; - - if (ELF_R_SYM (rela.r_info) == STN_UNDEF) - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - else if (ELF_R_SYM (rela.r_info) > symcount) - { - (*_bfd_error_handler) - (_("%s(%s): relocation %d has invalid symbol index %ld"), - abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info)); - relent->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; - } - else - { - asymbol **ps; - - ps = symbols + ELF_R_SYM (rela.r_info) - 1; - - relent->sym_ptr_ptr = ps; - } - - relent->addend = rela.r_addend; - - if ((entsize == sizeof (Elf_External_Rela) - && ebd->elf_info_to_howto != NULL) - || ebd->elf_info_to_howto_rel == NULL) - (*ebd->elf_info_to_howto) (abfd, relent, &rela); - else - (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela); - } - - if (allocated != NULL) - free (allocated); - - return TRUE; - - error_return: - if (allocated != NULL) - free (allocated); - return FALSE; -} - -/* Read in and swap the external relocs. */ - -bfd_boolean -elf_slurp_reloc_table (bfd *abfd, - asection *asect, - asymbol **symbols, - bfd_boolean dynamic) -{ - struct bfd_elf_section_data * const d = elf_section_data (asect); - Elf_Internal_Shdr *rel_hdr; - Elf_Internal_Shdr *rel_hdr2; - bfd_size_type reloc_count; - bfd_size_type reloc_count2; - arelent *relents; - bfd_size_type amt; - - if (asect->relocation != NULL) - return TRUE; - - if (! dynamic) - { - if ((asect->flags & SEC_RELOC) == 0 - || asect->reloc_count == 0) - return TRUE; - - rel_hdr = d->rel.hdr; - reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0; - rel_hdr2 = d->rela.hdr; - reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0; - - BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2); - BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset) - || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset)); - - } - else - { - /* Note that ASECT->RELOC_COUNT tends not to be accurate in this - case because relocations against this section may use the - dynamic symbol table, and in that case bfd_section_from_shdr - in elf.c does not update the RELOC_COUNT. */ - if (asect->size == 0) - return TRUE; - - rel_hdr = &d->this_hdr; - reloc_count = NUM_SHDR_ENTRIES (rel_hdr); - rel_hdr2 = NULL; - reloc_count2 = 0; - } - - amt = (reloc_count + reloc_count2) * sizeof (arelent); - relents = (arelent *) bfd_alloc (abfd, amt); - if (relents == NULL) - return FALSE; - - if (rel_hdr - && !elf_slurp_reloc_table_from_section (abfd, asect, - rel_hdr, reloc_count, - relents, - symbols, dynamic)) - return FALSE; - - if (rel_hdr2 - && !elf_slurp_reloc_table_from_section (abfd, asect, - rel_hdr2, reloc_count2, - relents + reloc_count, - symbols, dynamic)) - return FALSE; - - asect->relocation = relents; - return TRUE; -} - -#if DEBUG & 2 -static void -elf_debug_section (int num, Elf_Internal_Shdr *hdr) -{ - fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, - hdr->bfd_section != NULL ? hdr->bfd_section->name : "", - (long) hdr); - fprintf (stderr, - "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", - (long) hdr->sh_name, - (long) hdr->sh_type, - (long) hdr->sh_flags); - fprintf (stderr, - "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n", - (long) hdr->sh_addr, - (long) hdr->sh_offset, - (long) hdr->sh_size); - fprintf (stderr, - "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n", - (long) hdr->sh_link, - (long) hdr->sh_info, - (long) hdr->sh_addralign); - fprintf (stderr, "sh_entsize = %ld\n", - (long) hdr->sh_entsize); - fflush (stderr); -} -#endif - -#if DEBUG & 1 -static void -elf_debug_file (Elf_Internal_Ehdr *ehdrp) -{ - fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); - fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); - fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum); - fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize); - fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff); - fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); - fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); -} -#endif - -/* Create a new BFD as if by bfd_openr. Rather than opening a file, - reconstruct an ELF file by reading the segments out of remote memory - based on the ELF file header at EHDR_VMA and the ELF program headers it - points to. If not null, *LOADBASEP is filled in with the difference - between the VMAs from which the segments were read, and the VMAs the - file headers (and hence BFD's idea of each section's VMA) put them at. - - The function TARGET_READ_MEMORY is called to copy LEN bytes from the - remote memory at target address VMA into the local buffer at MYADDR; it - should return zero on success or an `errno' code on failure. TEMPL must - be a BFD for a target with the word size and byte order found in the - remote memory. */ - -bfd * -NAME(_bfd_elf,bfd_from_remote_memory) - (bfd *templ, - bfd_vma ehdr_vma, - bfd_vma *loadbasep, - int (*target_read_memory) (bfd_vma, bfd_byte *, int)) -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ - Elf_External_Phdr *x_phdrs; - Elf_Internal_Phdr *i_phdrs, *last_phdr; - bfd *nbfd; - struct bfd_in_memory *bim; - int contents_size; - bfd_byte *contents; - int err; - unsigned int i; - bfd_vma loadbase; - bfd_boolean loadbase_set; - - /* Read in the ELF header in external format. */ - err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); - if (err) - { - bfd_set_error (bfd_error_system_call); - errno = err; - return NULL; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry. */ - - if (! elf_file_p (&x_ehdr) - || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT - || x_ehdr.e_ident[EI_CLASS] != ELFCLASS) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Check that file's byte order matches xvec's */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_header_big_endian (templ)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_header_little_endian (templ)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr); - - /* The file header tells where to find the program headers. - These are what we use to actually choose what to read. */ - - if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - x_phdrs = (Elf_External_Phdr *) - bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs)); - if (x_phdrs == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, - i_ehdr.e_phnum * sizeof x_phdrs[0]); - if (err) - { - free (x_phdrs); - bfd_set_error (bfd_error_system_call); - errno = err; - return NULL; - } - i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum]; - - contents_size = 0; - last_phdr = NULL; - loadbase = ehdr_vma; - loadbase_set = FALSE; - for (i = 0; i < i_ehdr.e_phnum; ++i) - { - elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]); - if (i_phdrs[i].p_type == PT_LOAD) - { - bfd_vma segment_end; - segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz - + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; - if (segment_end > (bfd_vma) contents_size) - contents_size = segment_end; - - /* LOADADDR is the `Base address' from the gELF specification: - `lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the - first PT_LOAD as PT_LOADs are ordered by P_VADDR. */ - if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0) - { - loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align); - loadbase_set = TRUE; - } - - last_phdr = &i_phdrs[i]; - } - } - if (last_phdr == NULL) - { - /* There were no PT_LOAD segments, so we don't have anything to read. */ - free (x_phdrs); - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Trim the last segment so we don't bother with zeros in the last page - that are off the end of the file. However, if the extra bit in that - page includes the section headers, keep them. */ - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz - && (bfd_vma) contents_size >= (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - { - contents_size = last_phdr->p_offset + last_phdr->p_filesz; - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; - } - else - contents_size = last_phdr->p_offset + last_phdr->p_filesz; - - /* Now we know the size of the whole image we want read in. */ - contents = (bfd_byte *) bfd_zmalloc (contents_size); - if (contents == NULL) - { - free (x_phdrs); - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - for (i = 0; i < i_ehdr.e_phnum; ++i) - if (i_phdrs[i].p_type == PT_LOAD) - { - bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align; - bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz - + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align; - if (end > (bfd_vma) contents_size) - end = contents_size; - err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr) - & -i_phdrs[i].p_align, - contents + start, end - start); - if (err) - { - free (x_phdrs); - free (contents); - bfd_set_error (bfd_error_system_call); - errno = err; - return NULL; - } - } - free (x_phdrs); - - /* If the segments visible in memory didn't include the section headers, - then clear them from the file header. */ - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - { - memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff); - memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum); - memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx); - } - - /* This will normally have been in the first PT_LOAD segment. But it - conceivably could be missing, and we might have just changed it. */ - memcpy (contents, &x_ehdr, sizeof x_ehdr); - - /* Now we have a memory image of the ELF file contents. Make a BFD. */ - bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); - if (bim == NULL) - { - free (contents); - bfd_set_error (bfd_error_no_memory); - return NULL; - } - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - { - free (bim); - free (contents); - bfd_set_error (bfd_error_no_memory); - return NULL; - } - nbfd->filename = ""; - nbfd->xvec = templ->xvec; - bim->size = contents_size; - bim->buffer = contents; - nbfd->iostream = bim; - nbfd->flags = BFD_IN_MEMORY; - nbfd->iovec = &_bfd_memory_iovec; - nbfd->origin = 0; - nbfd->direction = read_direction; - nbfd->mtime = time (NULL); - nbfd->mtime_set = TRUE; - - if (loadbasep) - *loadbasep = loadbase; - return nbfd; -} - -/* Function for ELF_R_INFO. */ - -bfd_vma -NAME(elf,r_info) (bfd_vma sym, bfd_vma type) -{ - return ELF_R_INFO (sym, type); -} - -/* Function for ELF_R_SYM. */ - -bfd_vma -NAME(elf,r_sym) (bfd_vma r_info) -{ - return ELF_R_SYM (r_info); -} - -#include "elfcore.h" - -/* Size-dependent data and functions. */ -const struct elf_size_info NAME(_bfd_elf,size_info) = { - sizeof (Elf_External_Ehdr), - sizeof (Elf_External_Phdr), - sizeof (Elf_External_Shdr), - sizeof (Elf_External_Rel), - sizeof (Elf_External_Rela), - sizeof (Elf_External_Sym), - sizeof (Elf_External_Dyn), - sizeof (Elf_External_Note), - 4, - 1, - ARCH_SIZE, LOG_FILE_ALIGN, - ELFCLASS, EV_CURRENT, - elf_write_out_phdrs, - elf_write_shdrs_and_ehdr, - elf_checksum_contents, - elf_write_relocs, - elf_swap_symbol_in, - elf_swap_symbol_out, - elf_slurp_reloc_table, - elf_slurp_symbol_table, - elf_swap_dyn_in, - elf_swap_dyn_out, - elf_swap_reloc_in, - elf_swap_reloc_out, - elf_swap_reloca_in, - elf_swap_reloca_out -}; diff --git a/contrib/binutils-2.22/bfd/elfcore.h b/contrib/binutils-2.22/bfd/elfcore.h deleted file mode 100644 index 81980c0fec..0000000000 --- a/contrib/binutils-2.22/bfd/elfcore.h +++ /dev/null @@ -1,341 +0,0 @@ -/* ELF core file support for BFD. - Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007, - 2008, 2010 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -char* -elf_core_file_failing_command (bfd *abfd) -{ - return elf_tdata (abfd)->core_command; -} - -int -elf_core_file_failing_signal (bfd *abfd) -{ - return elf_tdata (abfd)->core_signal; -} - -int -elf_core_file_pid (bfd *abfd) -{ - return elf_tdata (abfd)->core_pid; -} - -bfd_boolean -elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd) -{ - char* corename; - - /* xvecs must match if both are ELF files for the same target. */ - - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return FALSE; - } - - /* See if the name in the corefile matches the executable name. */ - corename = elf_tdata (core_bfd)->core_program; - if (corename != NULL) - { - const char* execname = strrchr (exec_bfd->filename, '/'); - - execname = execname ? execname + 1 : exec_bfd->filename; - - if (strcmp (execname, corename) != 0) - return FALSE; - } - - return TRUE; -} - -/* Core files are simply standard ELF formatted files that partition - the file using the execution view of the file (program header table) - rather than the linking view. In fact, there is no section header - table in a core file. - - The process status information (including the contents of the general - register set) and the floating point register set are stored in a - segment of type PT_NOTE. We handcraft a couple of extra bfd sections - that allow standard bfd access to the general registers (.reg) and the - floating point registers (.reg2). */ - -const bfd_target * -elf_core_file_p (bfd *abfd) -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form. */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */ - Elf_Internal_Phdr *i_phdrp; /* Elf program header, internal form. */ - unsigned int phindex; - const struct elf_backend_data *ebd; - struct bfd_preserve preserve; - bfd_size_type amt; - - preserve.marker = NULL; - - /* Read in the ELF header in external format. */ - if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - goto wrong; - else - goto fail; - } - - /* Check the magic number. */ - if (! elf_file_p (&x_ehdr)) - goto wrong; - - /* FIXME: Check EI_VERSION here ! */ - - /* Check the address size ("class"). */ - if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS) - goto wrong; - - /* Check the byteorder. */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian. */ - if (! bfd_big_endian (abfd)) - goto wrong; - break; - case ELFDATA2LSB: /* Little-endian. */ - if (! bfd_little_endian (abfd)) - goto wrong; - break; - default: - goto wrong; - } - - if (!bfd_preserve_save (abfd, &preserve)) - goto fail; - - /* Give abfd an elf_obj_tdata. */ - if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd)) - goto fail; - preserve.marker = elf_tdata (abfd); - - /* Swap in the rest of the header, now that we have the byte order. */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); - -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 - || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 - || i_ehdrp->e_machine != ebd->elf_machine_alt2)) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto wrong; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - const struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = xvec_get_elf_backend_data (*target_ptr); - if (back->s->arch_size != ARCH_SIZE) - continue; - if (back->elf_machine_code == i_ehdrp->e_machine - || (back->elf_machine_alt1 != 0 - && i_ehdrp->e_machine == back->elf_machine_alt1) - || (back->elf_machine_alt2 != 0 - && i_ehdrp->e_machine == back->elf_machine_alt2)) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto wrong; - } - } - } - - /* If there is no program header, or the type is not a core file, then - we are hosed. */ - if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) - goto wrong; - - /* Does BFD's idea of the phdr size match the size - recorded in the file? */ - if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr)) - goto wrong; - - /* If the program header count is PN_XNUM(0xffff), the actual - count is in the first section header. */ - if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM) - { - Elf_External_Shdr x_shdr; - Elf_Internal_Shdr i_shdr; - bfd_signed_vma where = i_ehdrp->e_shoff; - - if (where != (file_ptr) where) - goto wrong; - - /* Seek to the section header table in the file. */ - if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) - goto fail; - - /* Read the first section header at index 0, and convert to internal - form. */ - if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr)) - goto fail; - elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); - - if (i_shdr.sh_info != 0) - { - i_ehdrp->e_phnum = i_shdr.sh_info; - if (i_ehdrp->e_phnum != i_shdr.sh_info) - goto wrong; - } - } - - /* Sanity check that we can read all of the program headers. - It ought to be good enough to just read the last one. */ - if (i_ehdrp->e_phnum > 1) - { - Elf_External_Phdr x_phdr; - Elf_Internal_Phdr i_phdr; - bfd_signed_vma where; - - /* Check that we don't have a totally silly number of - program headers. */ - if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr) - || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr)) - goto wrong; - - where = i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr); - if (where != (file_ptr) where) - goto wrong; - if ((bfd_size_type) where <= i_ehdrp->e_phoff) - goto wrong; - - if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) - goto fail; - if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr)) - goto fail; - } - - /* Move to the start of the program headers. */ - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) - goto wrong; - - /* Allocate space for the program headers. */ - amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum; - i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); - if (!i_phdrp) - goto fail; - - elf_tdata (abfd)->phdr = i_phdrp; - - /* Read and convert to internal form. */ - for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex) - { - Elf_External_Phdr x_phdr; - - if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr)) - goto fail; - - elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); - } - - /* Set the machine architecture. Do this before processing the - program headers since we need to know the architecture type - when processing the notes of some systems' core files. */ - if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0) - /* It's OK if this fails for the generic target. */ - && ebd->elf_machine_code != EM_NONE) - goto fail; - - /* Let the backend double check the format and override global - information. We do this before processing the program headers - to allow the correct machine (as opposed to just the default - machine) to be set, making it possible for grok_prstatus and - grok_psinfo to rely on the mach setting. */ - if (ebd->elf_backend_object_p != NULL - && ! ebd->elf_backend_object_p (abfd)) - goto wrong; - - /* Process each program header. */ - for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex) - if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex)) - goto fail; - - /* Check for core truncation. */ - { - bfd_size_type high = 0; - struct stat statbuf; - for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex) - { - Elf_Internal_Phdr *p = i_phdrp + phindex; - if (p->p_filesz) - { - bfd_size_type current = p->p_offset + p->p_filesz; - if (high < current) - high = current; - } - } - if (bfd_stat (abfd, &statbuf) == 0) - { - if ((bfd_size_type) statbuf.st_size < high) - { - (*_bfd_error_handler) - (_("Warning: %B is truncated: expected core file " - "size >= %lu, found: %lu."), - abfd, (unsigned long) high, (unsigned long) statbuf.st_size); - } - } - } - - /* Save the entry point from the ELF header. */ - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - bfd_preserve_finish (abfd, &preserve); - return abfd->xvec; - -wrong: - /* There is way too much undoing of half-known state here. The caller, - bfd_check_format_matches, really shouldn't iterate on live bfd's to - check match/no-match like it does. We have to rely on that a call to - bfd_default_set_arch_mach with the previously known mach, undoes what - was done by the first bfd_default_set_arch_mach (with mach 0) here. - For this to work, only elf-data and the mach may be changed by the - target-specific elf_backend_object_p function. Note that saving the - whole bfd here and restoring it would be even worse; the first thing - you notice is that the cached bfd file position gets out of sync. */ - bfd_set_error (bfd_error_wrong_format); - -fail: - if (preserve.marker != NULL) - bfd_preserve_restore (abfd, &preserve); - return NULL; -} diff --git a/contrib/binutils-2.22/bfd/elflink.c b/contrib/binutils-2.22/bfd/elflink.c deleted file mode 100644 index fc4266b36d..0000000000 --- a/contrib/binutils-2.22/bfd/elflink.c +++ /dev/null @@ -1,12848 +0,0 @@ -/* ELF linking support for BFD. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" -#include "safe-ctype.h" -#include "libiberty.h" -#include "objalloc.h" - -/* This struct is used to pass information to routines called via - elf_link_hash_traverse which must return failure. */ - -struct elf_info_failed -{ - struct bfd_link_info *info; - bfd_boolean failed; -}; - -/* This structure is used to pass information to - _bfd_elf_link_find_version_dependencies. */ - -struct elf_find_verdep_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* The number of dependencies. */ - unsigned int vers; - /* Whether we had a failure. */ - bfd_boolean failed; -}; - -static bfd_boolean _bfd_elf_fix_symbol_flags - (struct elf_link_hash_entry *, struct elf_info_failed *); - -/* Define a symbol in a dynamic linkage section. */ - -struct elf_link_hash_entry * -_bfd_elf_define_linkage_sym (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const char *name) -{ - struct elf_link_hash_entry *h; - struct bfd_link_hash_entry *bh; - const struct elf_backend_data *bed; - - h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); - if (h != NULL) - { - /* Zap symbol defined in an as-needed lib that wasn't linked. - This is a symptom of a larger problem: Absolute symbols - defined in shared libraries can't be overridden, because we - lose the link to the bfd which is via the symbol section. */ - h->root.type = bfd_link_hash_new; - } - - bh = &h->root; - if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL, - sec, 0, NULL, FALSE, - get_elf_backend_data (abfd)->collect, - &bh)) - return NULL; - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->non_elf = 0; - h->type = STT_OBJECT; - h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; - - bed = get_elf_backend_data (abfd); - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - return h; -} - -bfd_boolean -_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) -{ - flagword flags; - asection *s; - struct elf_link_hash_entry *h; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_link_hash_table *htab = elf_hash_table (info); - - /* This function may be called more than once. */ - s = bfd_get_section_by_name (abfd, ".got"); - if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0) - return TRUE; - - flags = bed->dynamic_sec_flags; - - s = bfd_make_section_anyway_with_flags (abfd, - (bed->rela_plts_and_copies_p - ? ".rela.got" : ".rel.got"), - (bed->dynamic_sec_flags - | SEC_READONLY)); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - htab->srelgot = s; - - s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); - if (s == NULL - || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - htab->sgot = s; - - if (bed->want_got_plt) - { - s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); - if (s == NULL - || !bfd_set_section_alignment (abfd, s, - bed->s->log_file_align)) - return FALSE; - htab->sgotplt = s; - } - - /* The first bit of the global offset table is the header. */ - s->size += bed->got_header_size; - - if (bed->want_got_sym) - { - /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got - (or .got.plt) section. We don't do this in the linker script - because we don't want to define the symbol if we are not creating - a global offset table. */ - h = _bfd_elf_define_linkage_sym (abfd, info, s, - "_GLOBAL_OFFSET_TABLE_"); - elf_hash_table (info)->hgot = h; - if (h == NULL) - return FALSE; - } - - return TRUE; -} - -/* Create a strtab to hold the dynamic symbol names. */ -static bfd_boolean -_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info) -{ - struct elf_link_hash_table *hash_table; - - hash_table = elf_hash_table (info); - if (hash_table->dynobj == NULL) - hash_table->dynobj = abfd; - - if (hash_table->dynstr == NULL) - { - hash_table->dynstr = _bfd_elf_strtab_init (); - if (hash_table->dynstr == NULL) - return FALSE; - } - return TRUE; -} - -/* Create some sections which will be filled in with dynamic linking - information. ABFD is an input file which requires dynamic sections - to be created. The dynamic sections take up virtual memory space - when the final executable is run, so we need to create them before - addresses are assigned to the output sections. We work out the - actual contents and size of these sections later. */ - -bfd_boolean -_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) -{ - flagword flags; - asection *s; - const struct elf_backend_data *bed; - - if (! is_elf_hash_table (info->hash)) - return FALSE; - - if (elf_hash_table (info)->dynamic_sections_created) - return TRUE; - - if (!_bfd_elf_link_create_dynstrtab (abfd, info)) - return FALSE; - - abfd = elf_hash_table (info)->dynobj; - bed = get_elf_backend_data (abfd); - - flags = bed->dynamic_sec_flags; - - /* A dynamically linked executable has a .interp section, but a - shared library does not. */ - if (info->executable) - { - s = bfd_make_section_anyway_with_flags (abfd, ".interp", - flags | SEC_READONLY); - if (s == NULL) - return FALSE; - } - - /* Create sections to hold version informations. These are removed - if they are not needed. */ - s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_d", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - - s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, 1)) - return FALSE; - - s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_r", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - - s = bfd_make_section_anyway_with_flags (abfd, ".dynsym", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - - s = bfd_make_section_anyway_with_flags (abfd, ".dynstr", - flags | SEC_READONLY); - if (s == NULL) - return FALSE; - - s = bfd_make_section_anyway_with_flags (abfd, ".dynamic", flags); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - - /* The special symbol _DYNAMIC is always set to the start of the - .dynamic section. We could set _DYNAMIC in a linker script, but we - only want to define it if we are, in fact, creating a .dynamic - section. We don't want to define it if there is no .dynamic - section, since on some ELF platforms the start up code examines it - to decide how to initialize the process. */ - if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC")) - return FALSE; - - if (info->emit_hash) - { - s = bfd_make_section_anyway_with_flags (abfd, ".hash", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; - } - - if (info->emit_gnu_hash) - { - s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash", - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section: - 4 32-bit words followed by variable count of 64-bit words, then - variable count of 32-bit words. */ - if (bed->s->arch_size == 64) - elf_section_data (s)->this_hdr.sh_entsize = 0; - else - elf_section_data (s)->this_hdr.sh_entsize = 4; - } - - /* Let the backend create the rest of the sections. This lets the - backend set the right flags. The backend will normally create - the .got and .plt sections. */ - if (bed->elf_backend_create_dynamic_sections == NULL - || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) - return FALSE; - - elf_hash_table (info)->dynamic_sections_created = TRUE; - - return TRUE; -} - -/* Create dynamic sections when linking against a dynamic object. */ - -bfd_boolean -_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) -{ - flagword flags, pltflags; - struct elf_link_hash_entry *h; - asection *s; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_link_hash_table *htab = elf_hash_table (info); - - /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and - .rel[a].bss sections. */ - flags = bed->dynamic_sec_flags; - - pltflags = flags; - if (bed->plt_not_loaded) - /* We do not clear SEC_ALLOC here because we still want the OS to - allocate space for the section; it's just that there's nothing - to read in from the object file. */ - pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); - else - pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; - if (bed->plt_readonly) - pltflags |= SEC_READONLY; - - s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) - return FALSE; - htab->splt = s; - - /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the - .plt section. */ - if (bed->want_plt_sym) - { - h = _bfd_elf_define_linkage_sym (abfd, info, s, - "_PROCEDURE_LINKAGE_TABLE_"); - elf_hash_table (info)->hplt = h; - if (h == NULL) - return FALSE; - } - - s = bfd_make_section_anyway_with_flags (abfd, - (bed->rela_plts_and_copies_p - ? ".rela.plt" : ".rel.plt"), - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - htab->srelplt = s; - - if (! _bfd_elf_create_got_section (abfd, info)) - return FALSE; - - if (bed->want_dynbss) - { - /* The .dynbss section is a place to put symbols which are defined - by dynamic objects, are referenced by regular objects, and are - not functions. We must allocate space for them in the process - image and use a R_*_COPY reloc to tell the dynamic linker to - initialize them at run time. The linker script puts the .dynbss - section into the .bss section of the final image. */ - s = bfd_make_section_anyway_with_flags (abfd, ".dynbss", - (SEC_ALLOC | SEC_LINKER_CREATED)); - if (s == NULL) - return FALSE; - - /* The .rel[a].bss section holds copy relocs. This section is not - normally needed. We need to create it here, though, so that the - linker will map it to an output section. We can't just create it - only if we need it, because we will not know whether we need it - until we have seen all the input files, and the first time the - main linker code calls BFD after examining all the input files - (size_dynamic_sections) the input sections have already been - mapped to the output sections. If the section turns out not to - be needed, we can discard it later. We will never need this - section when generating a shared object, since they do not use - copy relocs. */ - if (! info->shared) - { - s = bfd_make_section_anyway_with_flags (abfd, - (bed->rela_plts_and_copies_p - ? ".rela.bss" : ".rel.bss"), - flags | SEC_READONLY); - if (s == NULL - || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) - return FALSE; - } - } - - return TRUE; -} - -/* Record a new dynamic symbol. We record the dynamic symbols as we - read the input files, since we need to have a list of all of them - before we can determine the final sizes of the output sections. - Note that we may actually call this function even though we are not - going to output any dynamic symbols; in some cases we know that a - symbol should be in the dynamic symbol table, but only if there is - one. */ - -bfd_boolean -bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) -{ - if (h->dynindx == -1) - { - struct elf_strtab_hash *dynstr; - char *p; - const char *name; - bfd_size_type indx; - - /* XXX: The ABI draft says the linker must turn hidden and - internal symbols into STB_LOCAL symbols when producing the - DSO. However, if ld.so honors st_other in the dynamic table, - this would not be necessary. */ - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - if (h->root.type != bfd_link_hash_undefined - && h->root.type != bfd_link_hash_undefweak) - { - h->forced_local = 1; - if (!elf_hash_table (info)->is_relocatable_executable) - return TRUE; - } - - default: - break; - } - - h->dynindx = elf_hash_table (info)->dynsymcount; - ++elf_hash_table (info)->dynsymcount; - - dynstr = elf_hash_table (info)->dynstr; - if (dynstr == NULL) - { - /* Create a strtab to hold the dynamic symbol names. */ - elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); - if (dynstr == NULL) - return FALSE; - } - - /* We don't put any version information in the dynamic string - table. */ - name = h->root.root.string; - p = strchr (name, ELF_VER_CHR); - if (p != NULL) - /* We know that the p points into writable memory. In fact, - there are only a few symbols that have read-only names, being - those like _GLOBAL_OFFSET_TABLE_ that are created specially - by the backends. Most symbols will have names pointing into - an ELF string table read from a file, or to objalloc memory. */ - *p = 0; - - indx = _bfd_elf_strtab_add (dynstr, name, p != NULL); - - if (p != NULL) - *p = ELF_VER_CHR; - - if (indx == (bfd_size_type) -1) - return FALSE; - h->dynstr_index = indx; - } - - return TRUE; -} - -/* Mark a symbol dynamic. */ - -static void -bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - struct bfd_elf_dynamic_list *d = info->dynamic_list; - - /* It may be called more than once on the same H. */ - if(h->dynamic || info->relocatable) - return; - - if ((info->dynamic_data - && (h->type == STT_OBJECT - || (sym != NULL - && ELF_ST_TYPE (sym->st_info) == STT_OBJECT))) - || (d != NULL - && h->root.type == bfd_link_hash_new - && (*d->match) (&d->head, NULL, h->root.root.string))) - h->dynamic = 1; -} - -/* Record an assignment to a symbol made by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -bfd_boolean -bfd_elf_record_link_assignment (bfd *output_bfd, - struct bfd_link_info *info, - const char *name, - bfd_boolean provide, - bfd_boolean hidden) -{ - struct elf_link_hash_entry *h, *hv; - struct elf_link_hash_table *htab; - const struct elf_backend_data *bed; - - if (!is_elf_hash_table (info->hash)) - return TRUE; - - htab = elf_hash_table (info); - h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE); - if (h == NULL) - return provide; - - switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - case bfd_link_hash_common: - break; - case bfd_link_hash_undefweak: - case bfd_link_hash_undefined: - /* Since we're defining the symbol, don't let it seem to have not - been defined. record_dynamic_symbol and size_dynamic_sections - may depend on this. */ - h->root.type = bfd_link_hash_new; - if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root) - bfd_link_repair_undef_list (&htab->root); - break; - case bfd_link_hash_new: - bfd_elf_link_mark_dynamic_symbol (info, h, NULL); - h->non_elf = 0; - break; - case bfd_link_hash_indirect: - /* We had a versioned symbol in a dynamic library. We make the - the versioned symbol point to this one. */ - bed = get_elf_backend_data (output_bfd); - hv = h; - while (hv->root.type == bfd_link_hash_indirect - || hv->root.type == bfd_link_hash_warning) - hv = (struct elf_link_hash_entry *) hv->root.u.i.link; - /* We don't need to update h->root.u since linker will set them - later. */ - h->root.type = bfd_link_hash_undefined; - hv->root.type = bfd_link_hash_indirect; - hv->root.u.i.link = (struct bfd_link_hash_entry *) h; - (*bed->elf_backend_copy_indirect_symbol) (info, h, hv); - break; - case bfd_link_hash_warning: - abort (); - break; - } - - /* If this symbol is being provided by the linker script, and it is - currently defined by a dynamic object, but not by a regular - object, then mark it as undefined so that the generic linker will - force the correct value. */ - if (provide - && h->def_dynamic - && !h->def_regular) - h->root.type = bfd_link_hash_undefined; - - /* If this symbol is not being provided by the linker script, and it is - currently defined by a dynamic object, but not by a regular object, - then clear out any version information because the symbol will not be - associated with the dynamic object any more. */ - if (!provide - && h->def_dynamic - && !h->def_regular) - h->verinfo.verdef = NULL; - - h->def_regular = 1; - - if (provide && hidden) - { - bed = get_elf_backend_data (output_bfd); - h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - } - - /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects - and executables. */ - if (!info->relocatable - && h->dynindx != -1 - && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN - || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)) - h->forced_local = 1; - - if ((h->def_dynamic - || h->ref_dynamic - || info->shared - || (info->executable && elf_hash_table (info)->is_relocatable_executable)) - && h->dynindx == -1) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - - /* If this is a weak defined symbol, and we know a corresponding - real symbol from the same dynamic object, make sure the real - symbol is also made into a dynamic symbol. */ - if (h->u.weakdef != NULL - && h->u.weakdef->dynindx == -1) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef)) - return FALSE; - } - } - - return TRUE; -} - -/* Record a new local dynamic symbol. Returns 0 on failure, 1 on - success, and 2 on a failure caused by attempting to record a symbol - in a discarded section, eg. a discarded link-once section symbol. */ - -int -bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, - bfd *input_bfd, - long input_indx) -{ - bfd_size_type amt; - struct elf_link_local_dynamic_entry *entry; - struct elf_link_hash_table *eht; - struct elf_strtab_hash *dynstr; - unsigned long dynstr_index; - char *name; - Elf_External_Sym_Shndx eshndx; - char esym[sizeof (Elf64_External_Sym)]; - - if (! is_elf_hash_table (info->hash)) - return 0; - - /* See if the entry exists already. */ - for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) - if (entry->input_bfd == input_bfd && entry->input_indx == input_indx) - return 1; - - amt = sizeof (*entry); - entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt); - if (entry == NULL) - return 0; - - /* Go find the symbol, so that we can find it's name. */ - if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr, - 1, input_indx, &entry->isym, esym, &eshndx)) - { - bfd_release (input_bfd, entry); - return 0; - } - - if (entry->isym.st_shndx != SHN_UNDEF - && entry->isym.st_shndx < SHN_LORESERVE) - { - asection *s; - - s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx); - if (s == NULL || bfd_is_abs_section (s->output_section)) - { - /* We can still bfd_release here as nothing has done another - bfd_alloc. We can't do this later in this function. */ - bfd_release (input_bfd, entry); - return 2; - } - } - - name = (bfd_elf_string_from_elf_section - (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link, - entry->isym.st_name)); - - dynstr = elf_hash_table (info)->dynstr; - if (dynstr == NULL) - { - /* Create a strtab to hold the dynamic symbol names. */ - elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); - if (dynstr == NULL) - return 0; - } - - dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE); - if (dynstr_index == (unsigned long) -1) - return 0; - entry->isym.st_name = dynstr_index; - - eht = elf_hash_table (info); - - entry->next = eht->dynlocal; - eht->dynlocal = entry; - entry->input_bfd = input_bfd; - entry->input_indx = input_indx; - eht->dynsymcount++; - - /* Whatever binding the symbol had before, it's now local. */ - entry->isym.st_info - = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info)); - - /* The dynindx will be set at the end of size_dynamic_sections. */ - - return 1; -} - -/* Return the dynindex of a local dynamic symbol. */ - -long -_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info, - bfd *input_bfd, - long input_indx) -{ - struct elf_link_local_dynamic_entry *e; - - for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) - if (e->input_bfd == input_bfd && e->input_indx == input_indx) - return e->dynindx; - return -1; -} - -/* This function is used to renumber the dynamic symbols, if some of - them are removed because they are marked as local. This is called - via elf_link_hash_traverse. */ - -static bfd_boolean -elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h, - void *data) -{ - size_t *count = (size_t *) data; - - if (h->forced_local) - return TRUE; - - if (h->dynindx != -1) - h->dynindx = ++(*count); - - return TRUE; -} - - -/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with - STB_LOCAL binding. */ - -static bfd_boolean -elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h, - void *data) -{ - size_t *count = (size_t *) data; - - if (!h->forced_local) - return TRUE; - - if (h->dynindx != -1) - h->dynindx = ++(*count); - - return TRUE; -} - -/* Return true if the dynamic symbol for a given section should be - omitted when creating a shared library. */ -bfd_boolean -_bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info, - asection *p) -{ - struct elf_link_hash_table *htab; - - switch (elf_section_data (p)->this_hdr.sh_type) - { - case SHT_PROGBITS: - case SHT_NOBITS: - /* If sh_type is yet undecided, assume it could be - SHT_PROGBITS/SHT_NOBITS. */ - case SHT_NULL: - htab = elf_hash_table (info); - if (p == htab->tls_sec) - return FALSE; - - if (htab->text_index_section != NULL) - return p != htab->text_index_section && p != htab->data_index_section; - - if (strcmp (p->name, ".got") == 0 - || strcmp (p->name, ".got.plt") == 0 - || strcmp (p->name, ".plt") == 0) - { - asection *ip; - - if (htab->dynobj != NULL - && (ip = bfd_get_section_by_name (htab->dynobj, p->name)) != NULL - && (ip->flags & SEC_LINKER_CREATED) - && ip->output_section == p) - return TRUE; - } - return FALSE; - - /* There shouldn't be section relative relocations - against any other section. */ - default: - return TRUE; - } -} - -/* Assign dynsym indices. In a shared library we generate a section - symbol for each output section, which come first. Next come symbols - which have been forced to local binding. Then all of the back-end - allocated local dynamic syms, followed by the rest of the global - symbols. */ - -static unsigned long -_bfd_elf_link_renumber_dynsyms (bfd *output_bfd, - struct bfd_link_info *info, - unsigned long *section_sym_count) -{ - unsigned long dynsymcount = 0; - - if (info->shared || elf_hash_table (info)->is_relocatable_executable) - { - const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - asection *p; - for (p = output_bfd->sections; p ; p = p->next) - if ((p->flags & SEC_EXCLUDE) == 0 - && (p->flags & SEC_ALLOC) != 0 - && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) - elf_section_data (p)->dynindx = ++dynsymcount; - else - elf_section_data (p)->dynindx = 0; - } - *section_sym_count = dynsymcount; - - elf_link_hash_traverse (elf_hash_table (info), - elf_link_renumber_local_hash_table_dynsyms, - &dynsymcount); - - if (elf_hash_table (info)->dynlocal) - { - struct elf_link_local_dynamic_entry *p; - for (p = elf_hash_table (info)->dynlocal; p ; p = p->next) - p->dynindx = ++dynsymcount; - } - - elf_link_hash_traverse (elf_hash_table (info), - elf_link_renumber_hash_table_dynsyms, - &dynsymcount); - - /* There is an unused NULL entry at the head of the table which - we must account for in our count. Unless there weren't any - symbols, which means we'll have no table at all. */ - if (dynsymcount != 0) - ++dynsymcount; - - elf_hash_table (info)->dynsymcount = dynsymcount; - return dynsymcount; -} - -/* Merge st_other field. */ - -static void -elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, - Elf_Internal_Sym *isym, bfd_boolean definition, - bfd_boolean dynamic) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* If st_other has a processor-specific meaning, specific - code might be needed here. We never merge the visibility - attribute with the one from a dynamic object. */ - if (bed->elf_backend_merge_symbol_attribute) - (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition, - dynamic); - - /* If this symbol has default visibility and the user has requested - we not re-export it, then mark it as hidden. */ - if (definition - && !dynamic - && (abfd->no_export - || (abfd->my_archive && abfd->my_archive->no_export)) - && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL) - isym->st_other = (STV_HIDDEN - | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); - - if (!dynamic && ELF_ST_VISIBILITY (isym->st_other) != 0) - { - unsigned char hvis, symvis, other, nvis; - - /* Only merge the visibility. Leave the remainder of the - st_other field to elf_backend_merge_symbol_attribute. */ - other = h->other & ~ELF_ST_VISIBILITY (-1); - - /* Combine visibilities, using the most constraining one. */ - hvis = ELF_ST_VISIBILITY (h->other); - symvis = ELF_ST_VISIBILITY (isym->st_other); - if (! hvis) - nvis = symvis; - else if (! symvis) - nvis = hvis; - else - nvis = hvis < symvis ? hvis : symvis; - - h->other = other | nvis; - } -} - -/* This function is called when we want to define a new symbol. It - handles the various cases which arise when we find a definition in - a dynamic object, or when there is already a definition in a - dynamic object. The new symbol is described by NAME, SYM, PSEC, - and PVALUE. We set SYM_HASH to the hash table entry. We set - OVERRIDE if the old symbol is overriding a new definition. We set - TYPE_CHANGE_OK if it is OK for the type to change. We set - SIZE_CHANGE_OK if it is OK for the size to change. By OK to - change, we mean that we shouldn't warn if the type or size does - change. We set POLD_ALIGNMENT if an old common symbol in a dynamic - object is overridden by a regular object. */ - -bfd_boolean -_bfd_elf_merge_symbol (bfd *abfd, - struct bfd_link_info *info, - const char *name, - Elf_Internal_Sym *sym, - asection **psec, - bfd_vma *pvalue, - unsigned int *pold_alignment, - struct elf_link_hash_entry **sym_hash, - bfd_boolean *skip, - bfd_boolean *override, - bfd_boolean *type_change_ok, - bfd_boolean *size_change_ok) -{ - asection *sec, *oldsec; - struct elf_link_hash_entry *h; - struct elf_link_hash_entry *flip; - int bind; - bfd *oldbfd; - bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; - bfd_boolean newweak, oldweak, newfunc, oldfunc; - const struct elf_backend_data *bed; - - *skip = FALSE; - *override = FALSE; - - sec = *psec; - bind = ELF_ST_BIND (sym->st_info); - - /* Silently discard TLS symbols from --just-syms. There's no way to - combine a static TLS block with a new TLS block for this executable. */ - if (ELF_ST_TYPE (sym->st_info) == STT_TLS - && sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) - { - *skip = TRUE; - return TRUE; - } - - if (! bfd_is_und_section (sec)) - h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, FALSE, FALSE); - else - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, FALSE, FALSE)); - if (h == NULL) - return FALSE; - *sym_hash = h; - - bed = get_elf_backend_data (abfd); - - /* This code is for coping with dynamic objects, and is only useful - if we are doing an ELF link. */ - if (!(*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec)) - return TRUE; - - /* For merging, we only care about real symbols. */ - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* We have to check it for every instance since the first few may be - refereences and not all compilers emit symbol type for undefined - symbols. */ - bfd_elf_link_mark_dynamic_symbol (info, h, sym); - - /* If we just created the symbol, mark it as being an ELF symbol. - Other than that, there is nothing to do--there is no merge issue - with a newly defined symbol--so we just return. */ - - if (h->root.type == bfd_link_hash_new) - { - h->non_elf = 0; - return TRUE; - } - - /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the - existing symbol. */ - - switch (h->root.type) - { - default: - oldbfd = NULL; - oldsec = NULL; - break; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - oldbfd = h->root.u.undef.abfd; - oldsec = NULL; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - oldbfd = h->root.u.def.section->owner; - oldsec = h->root.u.def.section; - break; - - case bfd_link_hash_common: - oldbfd = h->root.u.c.p->section->owner; - oldsec = h->root.u.c.p->section; - break; - } - - /* Differentiate strong and weak symbols. */ - newweak = bind == STB_WEAK; - oldweak = (h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_undefweak); - - /* In cases involving weak versioned symbols, we may wind up trying - to merge a symbol with itself. Catch that here, to avoid the - confusion that results if we try to override a symbol with - itself. The additional tests catch cases like - _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a - dynamic object, which we do want to handle here. */ - if (abfd == oldbfd - && (newweak || oldweak) - && ((abfd->flags & DYNAMIC) == 0 - || !h->def_regular)) - return TRUE; - - /* NEWDYN and OLDDYN indicate whether the new or old symbol, - respectively, is from a dynamic object. */ - - newdyn = (abfd->flags & DYNAMIC) != 0; - - olddyn = FALSE; - if (oldbfd != NULL) - olddyn = (oldbfd->flags & DYNAMIC) != 0; - else if (oldsec != NULL) - { - /* This handles the special SHN_MIPS_{TEXT,DATA} section - indices used by MIPS ELF. */ - olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0; - } - - /* NEWDEF and OLDDEF indicate whether the new or old symbol, - respectively, appear to be a definition rather than reference. */ - - newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec); - - olddef = (h->root.type != bfd_link_hash_undefined - && h->root.type != bfd_link_hash_undefweak - && h->root.type != bfd_link_hash_common); - - /* NEWFUNC and OLDFUNC indicate whether the new or old symbol, - respectively, appear to be a function. */ - - newfunc = (ELF_ST_TYPE (sym->st_info) != STT_NOTYPE - && bed->is_function_type (ELF_ST_TYPE (sym->st_info))); - - oldfunc = (h->type != STT_NOTYPE - && bed->is_function_type (h->type)); - - /* When we try to create a default indirect symbol from the dynamic - definition with the default version, we skip it if its type and - the type of existing regular definition mismatch. We only do it - if the existing regular definition won't be dynamic. */ - if (pold_alignment == NULL - && !info->shared - && !info->export_dynamic - && !h->ref_dynamic - && newdyn - && newdef - && !olddyn - && (olddef || h->root.type == bfd_link_hash_common) - && ELF_ST_TYPE (sym->st_info) != h->type - && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE - && h->type != STT_NOTYPE - && !(newfunc && oldfunc)) - { - *skip = TRUE; - return TRUE; - } - - /* Plugin symbol type isn't currently set. Stop bogus errors. */ - if (oldbfd != NULL && (oldbfd->flags & BFD_PLUGIN) != 0) - *type_change_ok = TRUE; - - /* Check TLS symbol. We don't check undefined symbol introduced by - "ld -u". */ - else if (oldbfd != NULL - && ELF_ST_TYPE (sym->st_info) != h->type - && (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)) - { - bfd *ntbfd, *tbfd; - bfd_boolean ntdef, tdef; - asection *ntsec, *tsec; - - if (h->type == STT_TLS) - { - ntbfd = abfd; - ntsec = sec; - ntdef = newdef; - tbfd = oldbfd; - tsec = oldsec; - tdef = olddef; - } - else - { - ntbfd = oldbfd; - ntsec = oldsec; - ntdef = olddef; - tbfd = abfd; - tsec = sec; - tdef = newdef; - } - - if (tdef && ntdef) - (*_bfd_error_handler) - (_("%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"), - tbfd, tsec, ntbfd, ntsec, h->root.root.string); - else if (!tdef && !ntdef) - (*_bfd_error_handler) - (_("%s: TLS reference in %B mismatches non-TLS reference in %B"), - tbfd, ntbfd, h->root.root.string); - else if (tdef) - (*_bfd_error_handler) - (_("%s: TLS definition in %B section %A mismatches non-TLS reference in %B"), - tbfd, tsec, ntbfd, h->root.root.string); - else - (*_bfd_error_handler) - (_("%s: TLS reference in %B mismatches non-TLS definition in %B section %A"), - tbfd, ntbfd, ntsec, h->root.root.string); - - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* We need to remember if a symbol has a definition in a dynamic - object or is weak in all dynamic objects. Internal and hidden - visibility will make it unavailable to dynamic objects. */ - if (newdyn && !h->dynamic_def) - { - if (!bfd_is_und_section (sec)) - h->dynamic_def = 1; - else - { - /* Check if this symbol is weak in all dynamic objects. If it - is the first time we see it in a dynamic object, we mark - if it is weak. Otherwise, we clear it. */ - if (!h->ref_dynamic) - { - if (bind == STB_WEAK) - h->dynamic_weak = 1; - } - else if (bind != STB_WEAK) - h->dynamic_weak = 0; - } - } - - /* If the old symbol has non-default visibility, we ignore the new - definition from a dynamic object. */ - if (newdyn - && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && !bfd_is_und_section (sec)) - { - *skip = TRUE; - /* Make sure this symbol is dynamic. */ - h->ref_dynamic = 1; - /* A protected symbol has external availability. Make sure it is - recorded as dynamic. - - FIXME: Should we check type and size for protected symbol? */ - if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) - return bfd_elf_link_record_dynamic_symbol (info, h); - else - return TRUE; - } - else if (!newdyn - && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT - && h->def_dynamic) - { - /* If the new symbol with non-default visibility comes from a - relocatable file and the old definition comes from a dynamic - object, we remove the old definition. */ - if ((*sym_hash)->root.type == bfd_link_hash_indirect) - { - /* Handle the case where the old dynamic definition is - default versioned. We need to copy the symbol info from - the symbol with default version to the normal one if it - was referenced before. */ - if (h->ref_regular) - { - struct elf_link_hash_entry *vh = *sym_hash; - - vh->root.type = h->root.type; - h->root.type = bfd_link_hash_indirect; - (*bed->elf_backend_copy_indirect_symbol) (info, vh, h); - /* Protected symbols will override the dynamic definition - with default version. */ - if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED) - { - h->root.u.i.link = (struct bfd_link_hash_entry *) vh; - vh->dynamic_def = 1; - vh->ref_dynamic = 1; - } - else - { - h->root.type = vh->root.type; - vh->ref_dynamic = 0; - /* We have to hide it here since it was made dynamic - global with extra bits when the symbol info was - copied from the old dynamic definition. */ - (*bed->elf_backend_hide_symbol) (info, vh, TRUE); - } - h = vh; - } - else - h = *sym_hash; - } - - if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root) - && bfd_is_und_section (sec)) - { - /* If the new symbol is undefined and the old symbol was - also undefined before, we need to make sure - _bfd_generic_link_add_one_symbol doesn't mess - up the linker hash table undefs list. Since the old - definition came from a dynamic object, it is still on the - undefs list. */ - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = abfd; - } - else - { - h->root.type = bfd_link_hash_new; - h->root.u.undef.abfd = NULL; - } - - if (h->def_dynamic) - { - h->def_dynamic = 0; - h->ref_dynamic = 1; - } - /* FIXME: Should we check type and size for protected symbol? */ - h->size = 0; - h->type = 0; - return TRUE; - } - - if (bind == STB_GNU_UNIQUE) - h->unique_global = 1; - - /* If a new weak symbol definition comes from a regular file and the - old symbol comes from a dynamic library, we treat the new one as - strong. Similarly, an old weak symbol definition from a regular - file is treated as strong when the new symbol comes from a dynamic - library. Further, an old weak symbol from a dynamic library is - treated as strong if the new symbol is from a dynamic library. - This reflects the way glibc's ld.so works. - - Do this before setting *type_change_ok or *size_change_ok so that - we warn properly when dynamic library symbols are overridden. */ - - if (newdef && !newdyn && olddyn) - newweak = FALSE; - if (olddef && newdyn) - oldweak = FALSE; - - /* Allow changes between different types of function symbol. */ - if (newfunc && oldfunc) - *type_change_ok = TRUE; - - /* It's OK to change the type if either the existing symbol or the - new symbol is weak. A type change is also OK if the old symbol - is undefined and the new symbol is defined. */ - - if (oldweak - || newweak - || (newdef - && h->root.type == bfd_link_hash_undefined)) - *type_change_ok = TRUE; - - /* It's OK to change the size if either the existing symbol or the - new symbol is weak, or if the old symbol is undefined. */ - - if (*type_change_ok - || h->root.type == bfd_link_hash_undefined) - *size_change_ok = TRUE; - - /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old - symbol, respectively, appears to be a common symbol in a dynamic - object. If a symbol appears in an uninitialized section, and is - not weak, and is not a function, then it may be a common symbol - which was resolved when the dynamic object was created. We want - to treat such symbols specially, because they raise special - considerations when setting the symbol size: if the symbol - appears as a common symbol in a regular object, and the size in - the regular object is larger, we must make sure that we use the - larger size. This problematic case can always be avoided in C, - but it must be handled correctly when using Fortran shared - libraries. - - Note that if NEWDYNCOMMON is set, NEWDEF will be set, and - likewise for OLDDYNCOMMON and OLDDEF. - - Note that this test is just a heuristic, and that it is quite - possible to have an uninitialized symbol in a shared object which - is really a definition, rather than a common symbol. This could - lead to some minor confusion when the symbol really is a common - symbol in some regular object. However, I think it will be - harmless. */ - - if (newdyn - && newdef - && !newweak - && (sec->flags & SEC_ALLOC) != 0 - && (sec->flags & SEC_LOAD) == 0 - && sym->st_size > 0 - && !newfunc) - newdyncommon = TRUE; - else - newdyncommon = FALSE; - - if (olddyn - && olddef - && h->root.type == bfd_link_hash_defined - && h->def_dynamic - && (h->root.u.def.section->flags & SEC_ALLOC) != 0 - && (h->root.u.def.section->flags & SEC_LOAD) == 0 - && h->size > 0 - && !oldfunc) - olddyncommon = TRUE; - else - olddyncommon = FALSE; - - /* We now know everything about the old and new symbols. We ask the - backend to check if we can merge them. */ - if (bed->merge_symbol - && !bed->merge_symbol (info, sym_hash, h, sym, psec, pvalue, - pold_alignment, skip, override, - type_change_ok, size_change_ok, - &newdyn, &newdef, &newdyncommon, &newweak, - abfd, &sec, - &olddyn, &olddef, &olddyncommon, &oldweak, - oldbfd, &oldsec)) - return FALSE; - - /* If both the old and the new symbols look like common symbols in a - dynamic object, set the size of the symbol to the larger of the - two. */ - - if (olddyncommon - && newdyncommon - && sym->st_size != h->size) - { - /* Since we think we have two common symbols, issue a multiple - common warning if desired. Note that we only warn if the - size is different. If the size is the same, we simply let - the old symbol override the new one as normally happens with - symbols defined in dynamic objects. */ - - if (! ((*info->callbacks->multiple_common) - (info, &h->root, abfd, bfd_link_hash_common, sym->st_size))) - return FALSE; - - if (sym->st_size > h->size) - h->size = sym->st_size; - - *size_change_ok = TRUE; - } - - /* If we are looking at a dynamic object, and we have found a - definition, we need to see if the symbol was already defined by - some other object. If so, we want to use the existing - definition, and we do not want to report a multiple symbol - definition error; we do this by clobbering *PSEC to be - bfd_und_section_ptr. - - We treat a common symbol as a definition if the symbol in the - shared library is a function, since common symbols always - represent variables; this can cause confusion in principle, but - any such confusion would seem to indicate an erroneous program or - shared library. We also permit a common symbol in a regular - object to override a weak symbol in a shared object. */ - - if (newdyn - && newdef - && (olddef - || (h->root.type == bfd_link_hash_common - && (newweak || newfunc)))) - { - *override = TRUE; - newdef = FALSE; - newdyncommon = FALSE; - - *psec = sec = bfd_und_section_ptr; - *size_change_ok = TRUE; - - /* If we get here when the old symbol is a common symbol, then - we are explicitly letting it override a weak symbol or - function in a dynamic object, and we don't want to warn about - a type change. If the old symbol is a defined symbol, a type - change warning may still be appropriate. */ - - if (h->root.type == bfd_link_hash_common) - *type_change_ok = TRUE; - } - - /* Handle the special case of an old common symbol merging with a - new symbol which looks like a common symbol in a shared object. - We change *PSEC and *PVALUE to make the new symbol look like a - common symbol, and let _bfd_generic_link_add_one_symbol do the - right thing. */ - - if (newdyncommon - && h->root.type == bfd_link_hash_common) - { - *override = TRUE; - newdef = FALSE; - newdyncommon = FALSE; - *pvalue = sym->st_size; - *psec = sec = bed->common_section (oldsec); - *size_change_ok = TRUE; - } - - /* Skip weak definitions of symbols that are already defined. */ - if (newdef && olddef && newweak) - { - /* Don't skip new non-IR weak syms. */ - if (!(oldbfd != NULL - && (oldbfd->flags & BFD_PLUGIN) != 0 - && (abfd->flags & BFD_PLUGIN) == 0)) - *skip = TRUE; - - /* Merge st_other. If the symbol already has a dynamic index, - but visibility says it should not be visible, turn it into a - local symbol. */ - elf_merge_st_other (abfd, h, sym, newdef, newdyn); - if (h->dynindx != -1) - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - break; - } - } - - /* If the old symbol is from a dynamic object, and the new symbol is - a definition which is not from a dynamic object, then the new - symbol overrides the old symbol. Symbols from regular files - always take precedence over symbols from dynamic objects, even if - they are defined after the dynamic object in the link. - - As above, we again permit a common symbol in a regular object to - override a definition in a shared object if the shared object - symbol is a function or is weak. */ - - flip = NULL; - if (!newdyn - && (newdef - || (bfd_is_com_section (sec) - && (oldweak || oldfunc))) - && olddyn - && olddef - && h->def_dynamic) - { - /* Change the hash table entry to undefined, and let - _bfd_generic_link_add_one_symbol do the right thing with the - new definition. */ - - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = h->root.u.def.section->owner; - *size_change_ok = TRUE; - - olddef = FALSE; - olddyncommon = FALSE; - - /* We again permit a type change when a common symbol may be - overriding a function. */ - - if (bfd_is_com_section (sec)) - { - if (oldfunc) - { - /* If a common symbol overrides a function, make sure - that it isn't defined dynamically nor has type - function. */ - h->def_dynamic = 0; - h->type = STT_NOTYPE; - } - *type_change_ok = TRUE; - } - - if ((*sym_hash)->root.type == bfd_link_hash_indirect) - flip = *sym_hash; - else - /* This union may have been set to be non-NULL when this symbol - was seen in a dynamic object. We must force the union to be - NULL, so that it is correct for a regular symbol. */ - h->verinfo.vertree = NULL; - } - - /* Handle the special case of a new common symbol merging with an - old symbol that looks like it might be a common symbol defined in - a shared object. Note that we have already handled the case in - which a new common symbol should simply override the definition - in the shared library. */ - - if (! newdyn - && bfd_is_com_section (sec) - && olddyncommon) - { - /* It would be best if we could set the hash table entry to a - common symbol, but we don't know what to use for the section - or the alignment. */ - if (! ((*info->callbacks->multiple_common) - (info, &h->root, abfd, bfd_link_hash_common, sym->st_size))) - return FALSE; - - /* If the presumed common symbol in the dynamic object is - larger, pretend that the new symbol has its size. */ - - if (h->size > *pvalue) - *pvalue = h->size; - - /* We need to remember the alignment required by the symbol - in the dynamic object. */ - BFD_ASSERT (pold_alignment); - *pold_alignment = h->root.u.def.section->alignment_power; - - olddef = FALSE; - olddyncommon = FALSE; - - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = h->root.u.def.section->owner; - - *size_change_ok = TRUE; - *type_change_ok = TRUE; - - if ((*sym_hash)->root.type == bfd_link_hash_indirect) - flip = *sym_hash; - else - h->verinfo.vertree = NULL; - } - - if (flip != NULL) - { - /* Handle the case where we had a versioned symbol in a dynamic - library and now find a definition in a normal object. In this - case, we make the versioned symbol point to the normal one. */ - flip->root.type = h->root.type; - flip->root.u.undef.abfd = h->root.u.undef.abfd; - h->root.type = bfd_link_hash_indirect; - h->root.u.i.link = (struct bfd_link_hash_entry *) flip; - (*bed->elf_backend_copy_indirect_symbol) (info, flip, h); - if (h->def_dynamic) - { - h->def_dynamic = 0; - flip->ref_dynamic = 1; - } - } - - return TRUE; -} - -/* This function is called to create an indirect symbol from the - default for the symbol with the default version if needed. The - symbol is described by H, NAME, SYM, PSEC, VALUE, and OVERRIDE. We - set DYNSYM if the new indirect symbol is dynamic. */ - -static bfd_boolean -_bfd_elf_add_default_symbol (bfd *abfd, - struct bfd_link_info *info, - struct elf_link_hash_entry *h, - const char *name, - Elf_Internal_Sym *sym, - asection **psec, - bfd_vma *value, - bfd_boolean *dynsym, - bfd_boolean override) -{ - bfd_boolean type_change_ok; - bfd_boolean size_change_ok; - bfd_boolean skip; - char *shortname; - struct elf_link_hash_entry *hi; - struct bfd_link_hash_entry *bh; - const struct elf_backend_data *bed; - bfd_boolean collect; - bfd_boolean dynamic; - char *p; - size_t len, shortlen; - asection *sec; - - /* If this symbol has a version, and it is the default version, we - create an indirect symbol from the default name to the fully - decorated name. This will cause external references which do not - specify a version to be bound to this version of the symbol. */ - p = strchr (name, ELF_VER_CHR); - if (p == NULL || p[1] != ELF_VER_CHR) - return TRUE; - - if (override) - { - /* We are overridden by an old definition. We need to check if we - need to create the indirect symbol from the default name. */ - hi = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, - FALSE, FALSE); - BFD_ASSERT (hi != NULL); - if (hi == h) - return TRUE; - while (hi->root.type == bfd_link_hash_indirect - || hi->root.type == bfd_link_hash_warning) - { - hi = (struct elf_link_hash_entry *) hi->root.u.i.link; - if (hi == h) - return TRUE; - } - } - - bed = get_elf_backend_data (abfd); - collect = bed->collect; - dynamic = (abfd->flags & DYNAMIC) != 0; - - shortlen = p - name; - shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1); - if (shortname == NULL) - return FALSE; - memcpy (shortname, name, shortlen); - shortname[shortlen] = '\0'; - - /* We are going to create a new symbol. Merge it with any existing - symbol with this name. For the purposes of the merge, act as - though we were defining the symbol we just defined, although we - actually going to define an indirect symbol. */ - type_change_ok = FALSE; - size_change_ok = FALSE; - sec = *psec; - if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value, - NULL, &hi, &skip, &override, - &type_change_ok, &size_change_ok)) - return FALSE; - - if (skip) - goto nondefault; - - if (! override) - { - bh = &hi->root; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr, - 0, name, FALSE, collect, &bh))) - return FALSE; - hi = (struct elf_link_hash_entry *) bh; - } - else - { - /* In this case the symbol named SHORTNAME is overriding the - indirect symbol we want to add. We were planning on making - SHORTNAME an indirect symbol referring to NAME. SHORTNAME - is the name without a version. NAME is the fully versioned - name, and it is the default version. - - Overriding means that we already saw a definition for the - symbol SHORTNAME in a regular object, and it is overriding - the symbol defined in the dynamic object. - - When this happens, we actually want to change NAME, the - symbol we just added, to refer to SHORTNAME. This will cause - references to NAME in the shared object to become references - to SHORTNAME in the regular object. This is what we expect - when we override a function in a shared object: that the - references in the shared object will be mapped to the - definition in the regular object. */ - - while (hi->root.type == bfd_link_hash_indirect - || hi->root.type == bfd_link_hash_warning) - hi = (struct elf_link_hash_entry *) hi->root.u.i.link; - - h->root.type = bfd_link_hash_indirect; - h->root.u.i.link = (struct bfd_link_hash_entry *) hi; - if (h->def_dynamic) - { - h->def_dynamic = 0; - hi->ref_dynamic = 1; - if (hi->ref_regular - || hi->def_regular) - { - if (! bfd_elf_link_record_dynamic_symbol (info, hi)) - return FALSE; - } - } - - /* Now set HI to H, so that the following code will set the - other fields correctly. */ - hi = h; - } - - /* Check if HI is a warning symbol. */ - if (hi->root.type == bfd_link_hash_warning) - hi = (struct elf_link_hash_entry *) hi->root.u.i.link; - - /* If there is a duplicate definition somewhere, then HI may not - point to an indirect symbol. We will have reported an error to - the user in that case. */ - - if (hi->root.type == bfd_link_hash_indirect) - { - struct elf_link_hash_entry *ht; - - ht = (struct elf_link_hash_entry *) hi->root.u.i.link; - (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi); - - /* See if the new flags lead us to realize that the symbol must - be dynamic. */ - if (! *dynsym) - { - if (! dynamic) - { - if (! info->executable - || hi->ref_dynamic) - *dynsym = TRUE; - } - else - { - if (hi->ref_regular) - *dynsym = TRUE; - } - } - } - - /* We also need to define an indirection from the nondefault version - of the symbol. */ - -nondefault: - len = strlen (name); - shortname = (char *) bfd_hash_allocate (&info->hash->table, len); - if (shortname == NULL) - return FALSE; - memcpy (shortname, name, shortlen); - memcpy (shortname + shortlen, p + 1, len - shortlen); - - /* Once again, merge with any existing symbol. */ - type_change_ok = FALSE; - size_change_ok = FALSE; - sec = *psec; - if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value, - NULL, &hi, &skip, &override, - &type_change_ok, &size_change_ok)) - return FALSE; - - if (skip) - return TRUE; - - if (override) - { - /* Here SHORTNAME is a versioned name, so we don't expect to see - the type of override we do in the case above unless it is - overridden by a versioned definition. */ - if (hi->root.type != bfd_link_hash_defined - && hi->root.type != bfd_link_hash_defweak) - (*_bfd_error_handler) - (_("%B: unexpected redefinition of indirect versioned symbol `%s'"), - abfd, shortname); - } - else - { - bh = &hi->root; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, shortname, BSF_INDIRECT, - bfd_ind_section_ptr, 0, name, FALSE, collect, &bh))) - return FALSE; - hi = (struct elf_link_hash_entry *) bh; - - /* If there is a duplicate definition somewhere, then HI may not - point to an indirect symbol. We will have reported an error - to the user in that case. */ - - if (hi->root.type == bfd_link_hash_indirect) - { - (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); - - /* See if the new flags lead us to realize that the symbol - must be dynamic. */ - if (! *dynsym) - { - if (! dynamic) - { - if (! info->executable - || hi->ref_dynamic) - *dynsym = TRUE; - } - else - { - if (hi->ref_regular) - *dynsym = TRUE; - } - } - } - } - - return TRUE; -} - -/* This routine is used to export all defined symbols into the dynamic - symbol table. It is called via elf_link_hash_traverse. */ - -static bfd_boolean -_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - - /* Ignore indirect symbols. These are added by the versioning code. */ - if (h->root.type == bfd_link_hash_indirect) - return TRUE; - - /* Ignore this if we won't export it. */ - if (!eif->info->export_dynamic && !h->dynamic) - return TRUE; - - if (h->dynindx == -1 - && (h->def_regular || h->ref_regular) - && ! bfd_hide_sym_by_version (eif->info->version_info, - h->root.root.string)) - { - if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = TRUE; - return FALSE; - } - } - - return TRUE; -} - -/* Look through the symbols which are defined in other shared - libraries and referenced here. Update the list of version - dependencies. This will be put into the .gnu.version_r section. - This function is called via elf_link_hash_traverse. */ - -static bfd_boolean -_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, - void *data) -{ - struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data; - Elf_Internal_Verneed *t; - Elf_Internal_Vernaux *a; - bfd_size_type amt; - - /* We only care about symbols defined in shared objects with version - information. */ - if (!h->def_dynamic - || h->def_regular - || h->dynindx == -1 - || h->verinfo.verdef == NULL) - return TRUE; - - /* See if we already know about this version. */ - for (t = elf_tdata (rinfo->info->output_bfd)->verref; - t != NULL; - t = t->vn_nextref) - { - if (t->vn_bfd != h->verinfo.verdef->vd_bfd) - continue; - - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - if (a->vna_nodename == h->verinfo.verdef->vd_nodename) - return TRUE; - - break; - } - - /* This is a new version. Add it to tree we are building. */ - - if (t == NULL) - { - amt = sizeof *t; - t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt); - if (t == NULL) - { - rinfo->failed = TRUE; - return FALSE; - } - - t->vn_bfd = h->verinfo.verdef->vd_bfd; - t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref; - elf_tdata (rinfo->info->output_bfd)->verref = t; - } - - amt = sizeof *a; - a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); - if (a == NULL) - { - rinfo->failed = TRUE; - return FALSE; - } - - /* Note that we are copying a string pointer here, and testing it - above. If bfd_elf_string_from_elf_section is ever changed to - discard the string data when low in memory, this will have to be - fixed. */ - a->vna_nodename = h->verinfo.verdef->vd_nodename; - - a->vna_flags = h->verinfo.verdef->vd_flags; - a->vna_nextptr = t->vn_auxptr; - - h->verinfo.verdef->vd_exp_refno = rinfo->vers; - ++rinfo->vers; - - a->vna_other = h->verinfo.verdef->vd_exp_refno + 1; - - t->vn_auxptr = a; - - return TRUE; -} - -/* Figure out appropriate versions for all the symbols. We may not - have the version number script until we have read all of the input - files, so until that point we don't know which symbols should be - local. This function is called via elf_link_hash_traverse. */ - -static bfd_boolean -_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) -{ - struct elf_info_failed *sinfo; - struct bfd_link_info *info; - const struct elf_backend_data *bed; - struct elf_info_failed eif; - char *p; - bfd_size_type amt; - - sinfo = (struct elf_info_failed *) data; - info = sinfo->info; - - /* Fix the symbol flags. */ - eif.failed = FALSE; - eif.info = info; - if (! _bfd_elf_fix_symbol_flags (h, &eif)) - { - if (eif.failed) - sinfo->failed = TRUE; - return FALSE; - } - - /* We only need version numbers for symbols defined in regular - objects. */ - if (!h->def_regular) - return TRUE; - - bed = get_elf_backend_data (info->output_bfd); - p = strchr (h->root.root.string, ELF_VER_CHR); - if (p != NULL && h->verinfo.vertree == NULL) - { - struct bfd_elf_version_tree *t; - bfd_boolean hidden; - - hidden = TRUE; - - /* There are two consecutive ELF_VER_CHR characters if this is - not a hidden symbol. */ - ++p; - if (*p == ELF_VER_CHR) - { - hidden = FALSE; - ++p; - } - - /* If there is no version string, we can just return out. */ - if (*p == '\0') - { - if (hidden) - h->hidden = 1; - return TRUE; - } - - /* Look for the version. If we find it, it is no longer weak. */ - for (t = sinfo->info->version_info; t != NULL; t = t->next) - { - if (strcmp (t->name, p) == 0) - { - size_t len; - char *alc; - struct bfd_elf_version_expr *d; - - len = p - h->root.root.string; - alc = (char *) bfd_malloc (len); - if (alc == NULL) - { - sinfo->failed = TRUE; - return FALSE; - } - memcpy (alc, h->root.root.string, len - 1); - alc[len - 1] = '\0'; - if (alc[len - 2] == ELF_VER_CHR) - alc[len - 2] = '\0'; - - h->verinfo.vertree = t; - t->used = TRUE; - d = NULL; - - if (t->globals.list != NULL) - d = (*t->match) (&t->globals, NULL, alc); - - /* See if there is anything to force this symbol to - local scope. */ - if (d == NULL && t->locals.list != NULL) - { - d = (*t->match) (&t->locals, NULL, alc); - if (d != NULL - && h->dynindx != -1 - && ! info->export_dynamic) - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - } - - free (alc); - break; - } - } - - /* If we are building an application, we need to create a - version node for this version. */ - if (t == NULL && info->executable) - { - struct bfd_elf_version_tree **pp; - int version_index; - - /* If we aren't going to export this symbol, we don't need - to worry about it. */ - if (h->dynindx == -1) - return TRUE; - - amt = sizeof *t; - t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, amt); - if (t == NULL) - { - sinfo->failed = TRUE; - return FALSE; - } - - t->name = p; - t->name_indx = (unsigned int) -1; - t->used = TRUE; - - version_index = 1; - /* Don't count anonymous version tag. */ - if (sinfo->info->version_info != NULL - && sinfo->info->version_info->vernum == 0) - version_index = 0; - for (pp = &sinfo->info->version_info; - *pp != NULL; - pp = &(*pp)->next) - ++version_index; - t->vernum = version_index; - - *pp = t; - - h->verinfo.vertree = t; - } - else if (t == NULL) - { - /* We could not find the version for a symbol when - generating a shared archive. Return an error. */ - (*_bfd_error_handler) - (_("%B: version node not found for symbol %s"), - info->output_bfd, h->root.root.string); - bfd_set_error (bfd_error_bad_value); - sinfo->failed = TRUE; - return FALSE; - } - - if (hidden) - h->hidden = 1; - } - - /* If we don't have a version for this symbol, see if we can find - something. */ - if (h->verinfo.vertree == NULL && sinfo->info->version_info != NULL) - { - bfd_boolean hide; - - h->verinfo.vertree - = bfd_find_version_for_sym (sinfo->info->version_info, - h->root.root.string, &hide); - if (h->verinfo.vertree != NULL && hide) - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - } - - return TRUE; -} - -/* Read and swap the relocs from the section indicated by SHDR. This - may be either a REL or a RELA section. The relocations are - translated into RELA relocations and stored in INTERNAL_RELOCS, - which should have already been allocated to contain enough space. - The EXTERNAL_RELOCS are a buffer where the external form of the - relocations should be stored. - - Returns FALSE if something goes wrong. */ - -static bfd_boolean -elf_link_read_relocs_from_section (bfd *abfd, - asection *sec, - Elf_Internal_Shdr *shdr, - void *external_relocs, - Elf_Internal_Rela *internal_relocs) -{ - const struct elf_backend_data *bed; - void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); - const bfd_byte *erela; - const bfd_byte *erelaend; - Elf_Internal_Rela *irela; - Elf_Internal_Shdr *symtab_hdr; - size_t nsyms; - - /* Position ourselves at the start of the section. */ - if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0) - return FALSE; - - /* Read the relocations. */ - if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size) - return FALSE; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - nsyms = NUM_SHDR_ENTRIES (symtab_hdr); - - bed = get_elf_backend_data (abfd); - - /* Convert the external relocations to the internal format. */ - if (shdr->sh_entsize == bed->s->sizeof_rel) - swap_in = bed->s->swap_reloc_in; - else if (shdr->sh_entsize == bed->s->sizeof_rela) - swap_in = bed->s->swap_reloca_in; - else - { - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - erela = (const bfd_byte *) external_relocs; - erelaend = erela + shdr->sh_size; - irela = internal_relocs; - while (erela < erelaend) - { - bfd_vma r_symndx; - - (*swap_in) (abfd, erela, irela); - r_symndx = ELF32_R_SYM (irela->r_info); - if (bed->s->arch_size == 64) - r_symndx >>= 24; - if (nsyms > 0) - { - if ((size_t) r_symndx >= nsyms) - { - (*_bfd_error_handler) - (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)" - " for offset 0x%lx in section `%A'"), - abfd, sec, - (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - } - else if (r_symndx != STN_UNDEF) - { - (*_bfd_error_handler) - (_("%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A'" - " when the object file has no symbol table"), - abfd, sec, - (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - irela += bed->s->int_rels_per_ext_rel; - erela += shdr->sh_entsize; - } - - return TRUE; -} - -/* Read and swap the relocs for a section O. They may have been - cached. If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are - not NULL, they are used as buffers to read into. They are known to - be large enough. If the INTERNAL_RELOCS relocs argument is NULL, - the return value is allocated using either malloc or bfd_alloc, - according to the KEEP_MEMORY argument. If O has two relocation - sections (both REL and RELA relocations), then the REL_HDR - relocations will appear first in INTERNAL_RELOCS, followed by the - RELA_HDR relocations. */ - -Elf_Internal_Rela * -_bfd_elf_link_read_relocs (bfd *abfd, - asection *o, - void *external_relocs, - Elf_Internal_Rela *internal_relocs, - bfd_boolean keep_memory) -{ - void *alloc1 = NULL; - Elf_Internal_Rela *alloc2 = NULL; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct bfd_elf_section_data *esdo = elf_section_data (o); - Elf_Internal_Rela *internal_rela_relocs; - - if (esdo->relocs != NULL) - return esdo->relocs; - - if (o->reloc_count == 0) - return NULL; - - if (internal_relocs == NULL) - { - bfd_size_type size; - - size = o->reloc_count; - size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); - if (keep_memory) - internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size); - else - internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); - if (internal_relocs == NULL) - goto error_return; - } - - if (external_relocs == NULL) - { - bfd_size_type size = 0; - - if (esdo->rel.hdr) - size += esdo->rel.hdr->sh_size; - if (esdo->rela.hdr) - size += esdo->rela.hdr->sh_size; - - alloc1 = bfd_malloc (size); - if (alloc1 == NULL) - goto error_return; - external_relocs = alloc1; - } - - internal_rela_relocs = internal_relocs; - if (esdo->rel.hdr) - { - if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr, - external_relocs, - internal_relocs)) - goto error_return; - external_relocs = (((bfd_byte *) external_relocs) - + esdo->rel.hdr->sh_size); - internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr) - * bed->s->int_rels_per_ext_rel); - } - - if (esdo->rela.hdr - && (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr, - external_relocs, - internal_rela_relocs))) - goto error_return; - - /* Cache the results for next time, if we can. */ - if (keep_memory) - esdo->relocs = internal_relocs; - - if (alloc1 != NULL) - free (alloc1); - - /* Don't free alloc2, since if it was allocated we are passing it - back (under the name of internal_relocs). */ - - return internal_relocs; - - error_return: - if (alloc1 != NULL) - free (alloc1); - if (alloc2 != NULL) - { - if (keep_memory) - bfd_release (abfd, alloc2); - else - free (alloc2); - } - return NULL; -} - -/* Compute the size of, and allocate space for, REL_HDR which is the - section header for a section containing relocations for O. */ - -static bfd_boolean -_bfd_elf_link_size_reloc_section (bfd *abfd, - struct bfd_elf_section_reloc_data *reldata) -{ - Elf_Internal_Shdr *rel_hdr = reldata->hdr; - - /* That allows us to calculate the size of the section. */ - rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count; - - /* The contents field must last into write_object_contents, so we - allocate it with bfd_alloc rather than malloc. Also since we - cannot be sure that the contents will actually be filled in, - we zero the allocated space. */ - rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size); - if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) - return FALSE; - - if (reldata->hashes == NULL && reldata->count) - { - struct elf_link_hash_entry **p; - - p = (struct elf_link_hash_entry **) - bfd_zmalloc (reldata->count * sizeof (struct elf_link_hash_entry *)); - if (p == NULL) - return FALSE; - - reldata->hashes = p; - } - - return TRUE; -} - -/* Copy the relocations indicated by the INTERNAL_RELOCS (which - originated from the section given by INPUT_REL_HDR) to the - OUTPUT_BFD. */ - -bfd_boolean -_bfd_elf_link_output_relocs (bfd *output_bfd, - asection *input_section, - Elf_Internal_Shdr *input_rel_hdr, - Elf_Internal_Rela *internal_relocs, - struct elf_link_hash_entry **rel_hash - ATTRIBUTE_UNUSED) -{ - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - bfd_byte *erel; - struct bfd_elf_section_reloc_data *output_reldata; - asection *output_section; - const struct elf_backend_data *bed; - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - struct bfd_elf_section_data *esdo; - - output_section = input_section->output_section; - - bed = get_elf_backend_data (output_bfd); - esdo = elf_section_data (output_section); - if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize) - { - output_reldata = &esdo->rel; - swap_out = bed->s->swap_reloc_out; - } - else if (esdo->rela.hdr - && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize) - { - output_reldata = &esdo->rela; - swap_out = bed->s->swap_reloca_out; - } - else - { - (*_bfd_error_handler) - (_("%B: relocation size mismatch in %B section %A"), - output_bfd, input_section->owner, input_section); - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - erel = output_reldata->hdr->contents; - erel += output_reldata->count * input_rel_hdr->sh_entsize; - irela = internal_relocs; - irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) - * bed->s->int_rels_per_ext_rel); - while (irela < irelaend) - { - (*swap_out) (output_bfd, irela, erel); - irela += bed->s->int_rels_per_ext_rel; - erel += input_rel_hdr->sh_entsize; - } - - /* Bump the counter, so that we know where to add the next set of - relocations. */ - output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr); - - return TRUE; -} - -/* Make weak undefined symbols in PIE dynamic. */ - -bfd_boolean -_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) -{ - if (info->pie - && h->dynindx == -1 - && h->root.type == bfd_link_hash_undefweak) - return bfd_elf_link_record_dynamic_symbol (info, h); - - return TRUE; -} - -/* Fix up the flags for a symbol. This handles various cases which - can only be fixed after all the input files are seen. This is - currently called by both adjust_dynamic_symbol and - assign_sym_version, which is unnecessary but perhaps more robust in - the face of future changes. */ - -static bfd_boolean -_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, - struct elf_info_failed *eif) -{ - const struct elf_backend_data *bed; - - /* If this symbol was mentioned in a non-ELF file, try to set - DEF_REGULAR and REF_REGULAR correctly. This is the only way to - permit a non-ELF file to correctly refer to a symbol defined in - an ELF dynamic object. */ - if (h->non_elf) - { - while (h->root.type == bfd_link_hash_indirect) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - { - h->ref_regular = 1; - h->ref_regular_nonweak = 1; - } - else - { - if (h->root.u.def.section->owner != NULL - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour)) - { - h->ref_regular = 1; - h->ref_regular_nonweak = 1; - } - else - h->def_regular = 1; - } - - if (h->dynindx == -1 - && (h->def_dynamic - || h->ref_dynamic)) - { - if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = TRUE; - return FALSE; - } - } - } - else - { - /* Unfortunately, NON_ELF is only correct if the symbol - was first seen in a non-ELF file. Fortunately, if the symbol - was first seen in an ELF file, we're probably OK unless the - symbol was defined in a non-ELF file. Catch that case here. - FIXME: We're still in trouble if the symbol was first seen in - a dynamic object, and then later in a non-ELF regular object. */ - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && !h->def_regular - && (h->root.u.def.section->owner != NULL - ? (bfd_get_flavour (h->root.u.def.section->owner) - != bfd_target_elf_flavour) - : (bfd_is_abs_section (h->root.u.def.section) - && !h->def_dynamic))) - h->def_regular = 1; - } - - /* Backend specific symbol fixup. */ - bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); - if (bed->elf_backend_fixup_symbol - && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) - return FALSE; - - /* If this is a final link, and the symbol was defined as a common - symbol in a regular object file, and there was no definition in - any dynamic object, then the linker will have allocated space for - the symbol in a common section but the DEF_REGULAR - flag will not have been set. */ - if (h->root.type == bfd_link_hash_defined - && !h->def_regular - && h->ref_regular - && !h->def_dynamic - && (h->root.u.def.section->owner->flags & DYNAMIC) == 0) - h->def_regular = 1; - - /* If -Bsymbolic was used (which means to bind references to global - symbols to the definition within the shared object), and this - symbol was defined in a regular object, then it actually doesn't - need a PLT entry. Likewise, if the symbol has non-default - visibility. If the symbol has hidden or internal visibility, we - will force it local. */ - if (h->needs_plt - && eif->info->shared - && is_elf_hash_table (eif->info->hash) - && (SYMBOLIC_BIND (eif->info, h) - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular) - { - bfd_boolean force_local; - - force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL - || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN); - (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); - } - - /* If a weak undefined symbol has non-default visibility, we also - hide it from the dynamic linker. */ - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak) - (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); - - /* If this is a weak defined symbol in a dynamic object, and we know - the real definition in the dynamic object, copy interesting flags - over to the real definition. */ - if (h->u.weakdef != NULL) - { - struct elf_link_hash_entry *weakdef; - - weakdef = h->u.weakdef; - while (h->root.type == bfd_link_hash_indirect) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - BFD_ASSERT (weakdef->def_dynamic); - - /* If the real definition is defined by a regular object file, - don't do anything special. See the longer description in - _bfd_elf_adjust_dynamic_symbol, below. */ - if (weakdef->def_regular) - h->u.weakdef = NULL; - else - { - BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined - || weakdef->root.type == bfd_link_hash_defweak); - (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h); - } - } - - return TRUE; -} - -/* Make the backend pick a good value for a dynamic symbol. This is - called via elf_link_hash_traverse, and also calls itself - recursively. */ - -static bfd_boolean -_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - bfd *dynobj; - const struct elf_backend_data *bed; - - if (! is_elf_hash_table (eif->info->hash)) - return FALSE; - - /* Ignore indirect symbols. These are added by the versioning code. */ - if (h->root.type == bfd_link_hash_indirect) - return TRUE; - - /* Fix the symbol flags. */ - if (! _bfd_elf_fix_symbol_flags (h, eif)) - return FALSE; - - /* If this symbol does not require a PLT entry, and it is not - defined by a dynamic object, or is not referenced by a regular - object, ignore it. We do have to handle a weak defined symbol, - even if no regular object refers to it, if we decided to add it - to the dynamic symbol table. FIXME: Do we normally need to worry - about symbols which are defined by one dynamic object and - referenced by another one? */ - if (!h->needs_plt - && h->type != STT_GNU_IFUNC - && (h->def_regular - || !h->def_dynamic - || (!h->ref_regular - && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1)))) - { - h->plt = elf_hash_table (eif->info)->init_plt_offset; - return TRUE; - } - - /* If we've already adjusted this symbol, don't do it again. This - can happen via a recursive call. */ - if (h->dynamic_adjusted) - return TRUE; - - /* Don't look at this symbol again. Note that we must set this - after checking the above conditions, because we may look at a - symbol once, decide not to do anything, and then get called - recursively later after REF_REGULAR is set below. */ - h->dynamic_adjusted = 1; - - /* If this is a weak definition, and we know a real definition, and - the real symbol is not itself defined by a regular object file, - then get a good value for the real definition. We handle the - real symbol first, for the convenience of the backend routine. - - Note that there is a confusing case here. If the real definition - is defined by a regular object file, we don't get the real symbol - from the dynamic object, but we do get the weak symbol. If the - processor backend uses a COPY reloc, then if some routine in the - dynamic object changes the real symbol, we will not see that - change in the corresponding weak symbol. This is the way other - ELF linkers work as well, and seems to be a result of the shared - library model. - - I will clarify this issue. Most SVR4 shared libraries define the - variable _timezone and define timezone as a weak synonym. The - tzset call changes _timezone. If you write - extern int timezone; - int _timezone = 5; - int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } - you might expect that, since timezone is a synonym for _timezone, - the same number will print both times. However, if the processor - backend uses a COPY reloc, then actually timezone will be copied - into your process image, and, since you define _timezone - yourself, _timezone will not. Thus timezone and _timezone will - wind up at different memory locations. The tzset call will set - _timezone, leaving timezone unchanged. */ - - if (h->u.weakdef != NULL) - { - /* If we get to this point, there is an implicit reference to - H->U.WEAKDEF by a regular object file via the weak symbol H. */ - h->u.weakdef->ref_regular = 1; - - /* Ensure that the backend adjust_dynamic_symbol function sees - H->U.WEAKDEF before H by recursively calling ourselves. */ - if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif)) - return FALSE; - } - - /* If a symbol has no type and no size and does not require a PLT - entry, then we are probably about to do the wrong thing here: we - are probably going to create a COPY reloc for an empty object. - This case can arise when a shared object is built with assembly - code, and the assembly code fails to set the symbol type. */ - if (h->size == 0 - && h->type == STT_NOTYPE - && !h->needs_plt) - (*_bfd_error_handler) - (_("warning: type and size of dynamic symbol `%s' are not defined"), - h->root.root.string); - - dynobj = elf_hash_table (eif->info)->dynobj; - bed = get_elf_backend_data (dynobj); - - if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) - { - eif->failed = TRUE; - return FALSE; - } - - return TRUE; -} - -/* Adjust the dynamic symbol, H, for copy in the dynamic bss section, - DYNBSS. */ - -bfd_boolean -_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h, - asection *dynbss) -{ - unsigned int power_of_two; - bfd_vma mask; - asection *sec = h->root.u.def.section; - - /* The section aligment of definition is the maximum alignment - requirement of symbols defined in the section. Since we don't - know the symbol alignment requirement, we start with the - maximum alignment and check low bits of the symbol address - for the minimum alignment. */ - power_of_two = bfd_get_section_alignment (sec->owner, sec); - mask = ((bfd_vma) 1 << power_of_two) - 1; - while ((h->root.u.def.value & mask) != 0) - { - mask >>= 1; - --power_of_two; - } - - if (power_of_two > bfd_get_section_alignment (dynbss->owner, - dynbss)) - { - /* Adjust the section alignment if needed. */ - if (! bfd_set_section_alignment (dynbss->owner, dynbss, - power_of_two)) - return FALSE; - } - - /* We make sure that the symbol will be aligned properly. */ - dynbss->size = BFD_ALIGN (dynbss->size, mask + 1); - - /* Define the symbol as being at this point in DYNBSS. */ - h->root.u.def.section = dynbss; - h->root.u.def.value = dynbss->size; - - /* Increment the size of DYNBSS to make room for the symbol. */ - dynbss->size += h->size; - - return TRUE; -} - -/* Adjust all external symbols pointing into SEC_MERGE sections - to reflect the object merging within the sections. */ - -static bfd_boolean -_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data) -{ - asection *sec; - - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && ((sec = h->root.u.def.section)->flags & SEC_MERGE) - && sec->sec_info_type == ELF_INFO_TYPE_MERGE) - { - bfd *output_bfd = (bfd *) data; - - h->root.u.def.value = - _bfd_merged_section_offset (output_bfd, - &h->root.u.def.section, - elf_section_data (sec)->sec_info, - h->root.u.def.value); - } - - return TRUE; -} - -/* Returns false if the symbol referred to by H should be considered - to resolve local to the current module, and true if it should be - considered to bind dynamically. */ - -bfd_boolean -_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, - struct bfd_link_info *info, - bfd_boolean not_local_protected) -{ - bfd_boolean binding_stays_local_p; - const struct elf_backend_data *bed; - struct elf_link_hash_table *hash_table; - - if (h == NULL) - return FALSE; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* If it was forced local, then clearly it's not dynamic. */ - if (h->dynindx == -1) - return FALSE; - if (h->forced_local) - return FALSE; - - /* Identify the cases where name binding rules say that a - visible symbol resolves locally. */ - binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h); - - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - return FALSE; - - case STV_PROTECTED: - hash_table = elf_hash_table (info); - if (!is_elf_hash_table (hash_table)) - return FALSE; - - bed = get_elf_backend_data (hash_table->dynobj); - - /* Proper resolution for function pointer equality may require - that these symbols perhaps be resolved dynamically, even though - we should be resolving them to the current module. */ - if (!not_local_protected || !bed->is_function_type (h->type)) - binding_stays_local_p = TRUE; - break; - - default: - break; - } - - /* If it isn't defined locally, then clearly it's dynamic. */ - if (!h->def_regular && !ELF_COMMON_DEF_P (h)) - return TRUE; - - /* Otherwise, the symbol is dynamic if binding rules don't tell - us that it remains local. */ - return !binding_stays_local_p; -} - -/* Return true if the symbol referred to by H should be considered - to resolve local to the current module, and false otherwise. Differs - from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of - undefined symbols. The two functions are virtually identical except - for the place where forced_local and dynindx == -1 are tested. If - either of those tests are true, _bfd_elf_dynamic_symbol_p will say - the symbol is local, while _bfd_elf_symbol_refs_local_p will say - the symbol is local only for defined symbols. - It might seem that _bfd_elf_dynamic_symbol_p could be rewritten as - !_bfd_elf_symbol_refs_local_p, except that targets differ in their - treatment of undefined weak symbols. For those that do not make - undefined weak symbols dynamic, both functions may return false. */ - -bfd_boolean -_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h, - struct bfd_link_info *info, - bfd_boolean local_protected) -{ - const struct elf_backend_data *bed; - struct elf_link_hash_table *hash_table; - - /* If it's a local sym, of course we resolve locally. */ - if (h == NULL) - return TRUE; - - /* STV_HIDDEN or STV_INTERNAL ones must be local. */ - if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN - || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL) - return TRUE; - - /* Common symbols that become definitions don't get the DEF_REGULAR - flag set, so test it first, and don't bail out. */ - if (ELF_COMMON_DEF_P (h)) - /* Do nothing. */; - /* If we don't have a definition in a regular file, then we can't - resolve locally. The sym is either undefined or dynamic. */ - else if (!h->def_regular) - return FALSE; - - /* Forced local symbols resolve locally. */ - if (h->forced_local) - return TRUE; - - /* As do non-dynamic symbols. */ - if (h->dynindx == -1) - return TRUE; - - /* At this point, we know the symbol is defined and dynamic. In an - executable it must resolve locally, likewise when building symbolic - shared libraries. */ - if (info->executable || SYMBOLIC_BIND (info, h)) - return TRUE; - - /* Now deal with defined dynamic symbols in shared libraries. Ones - with default visibility might not resolve locally. */ - if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - return FALSE; - - hash_table = elf_hash_table (info); - if (!is_elf_hash_table (hash_table)) - return TRUE; - - bed = get_elf_backend_data (hash_table->dynobj); - - /* STV_PROTECTED non-function symbols are local. */ - if (!bed->is_function_type (h->type)) - return TRUE; - - /* Function pointer equality tests may require that STV_PROTECTED - symbols be treated as dynamic symbols. If the address of a - function not defined in an executable is set to that function's - plt entry in the executable, then the address of the function in - a shared library must also be the plt entry in the executable. */ - return local_protected; -} - -/* Caches some TLS segment info, and ensures that the TLS segment vma is - aligned. Returns the first TLS output section. */ - -struct bfd_section * -_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) -{ - struct bfd_section *sec, *tls; - unsigned int align = 0; - - for (sec = obfd->sections; sec != NULL; sec = sec->next) - if ((sec->flags & SEC_THREAD_LOCAL) != 0) - break; - tls = sec; - - for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next) - if (sec->alignment_power > align) - align = sec->alignment_power; - - elf_hash_table (info)->tls_sec = tls; - - /* Ensure the alignment of the first section is the largest alignment, - so that the tls segment starts aligned. */ - if (tls != NULL) - tls->alignment_power = align; - - return tls; -} - -/* Return TRUE iff this is a non-common, definition of a non-function symbol. */ -static bfd_boolean -is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, - Elf_Internal_Sym *sym) -{ - const struct elf_backend_data *bed; - - /* Local symbols do not count, but target specific ones might. */ - if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL - && ELF_ST_BIND (sym->st_info) < STB_LOOS) - return FALSE; - - bed = get_elf_backend_data (abfd); - /* Function symbols do not count. */ - if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) - return FALSE; - - /* If the section is undefined, then so is the symbol. */ - if (sym->st_shndx == SHN_UNDEF) - return FALSE; - - /* If the symbol is defined in the common section, then - it is a common definition and so does not count. */ - if (bed->common_definition (sym)) - return FALSE; - - /* If the symbol is in a target specific section then we - must rely upon the backend to tell us what it is. */ - if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS) - /* FIXME - this function is not coded yet: - - return _bfd_is_global_symbol_definition (abfd, sym); - - Instead for now assume that the definition is not global, - Even if this is wrong, at least the linker will behave - in the same way that it used to do. */ - return FALSE; - - return TRUE; -} - -/* Search the symbol table of the archive element of the archive ABFD - whose archive map contains a mention of SYMDEF, and determine if - the symbol is defined in this element. */ -static bfd_boolean -elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) -{ - Elf_Internal_Shdr * hdr; - bfd_size_type symcount; - bfd_size_type extsymcount; - bfd_size_type extsymoff; - Elf_Internal_Sym *isymbuf; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - bfd_boolean result; - - abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); - if (abfd == NULL) - return FALSE; - - if (! bfd_check_format (abfd, bfd_object)) - return FALSE; - - /* If we have already included the element containing this symbol in the - link then we do not need to include it again. Just claim that any symbol - it contains is not a definition, so that our caller will not decide to - (re)include this element. */ - if (abfd->archive_pass) - return FALSE; - - /* Select the appropriate symbol table. */ - if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0) - hdr = &elf_tdata (abfd)->symtab_hdr; - else - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - - symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols. */ - if (elf_bad_symtab (abfd)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - if (extsymcount == 0) - return FALSE; - - /* Read in the symbol table. */ - isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, - NULL, NULL, NULL); - if (isymbuf == NULL) - return FALSE; - - /* Scan the symbol table looking for SYMDEF. */ - result = FALSE; - for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++) - { - const char *name; - - name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, - isym->st_name); - if (name == NULL) - break; - - if (strcmp (name, symdef->name) == 0) - { - result = is_global_data_symbol_definition (abfd, isym); - break; - } - } - - free (isymbuf); - - return result; -} - -/* Add an entry to the .dynamic table. */ - -bfd_boolean -_bfd_elf_add_dynamic_entry (struct bfd_link_info *info, - bfd_vma tag, - bfd_vma val) -{ - struct elf_link_hash_table *hash_table; - const struct elf_backend_data *bed; - asection *s; - bfd_size_type newsize; - bfd_byte *newcontents; - Elf_Internal_Dyn dyn; - - hash_table = elf_hash_table (info); - if (! is_elf_hash_table (hash_table)) - return FALSE; - - bed = get_elf_backend_data (hash_table->dynobj); - s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - - newsize = s->size + bed->s->sizeof_dyn; - newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize); - if (newcontents == NULL) - return FALSE; - - dyn.d_tag = tag; - dyn.d_un.d_val = val; - bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->size); - - s->size = newsize; - s->contents = newcontents; - - return TRUE; -} - -/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true, - otherwise just check whether one already exists. Returns -1 on error, - 1 if a DT_NEEDED tag already exists, and 0 on success. */ - -static int -elf_add_dt_needed_tag (bfd *abfd, - struct bfd_link_info *info, - const char *soname, - bfd_boolean do_it) -{ - struct elf_link_hash_table *hash_table; - bfd_size_type oldsize; - bfd_size_type strindex; - - if (!_bfd_elf_link_create_dynstrtab (abfd, info)) - return -1; - - hash_table = elf_hash_table (info); - oldsize = _bfd_elf_strtab_size (hash_table->dynstr); - strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE); - if (strindex == (bfd_size_type) -1) - return -1; - - if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr)) - { - asection *sdyn; - const struct elf_backend_data *bed; - bfd_byte *extdyn; - - bed = get_elf_backend_data (hash_table->dynobj); - sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); - if (sdyn != NULL) - for (extdyn = sdyn->contents; - extdyn < sdyn->contents + sdyn->size; - extdyn += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - - bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn); - if (dyn.d_tag == DT_NEEDED - && dyn.d_un.d_val == strindex) - { - _bfd_elf_strtab_delref (hash_table->dynstr, strindex); - return 1; - } - } - } - - if (do_it) - { - if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info)) - return -1; - - if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex)) - return -1; - } - else - /* We were just checking for existence of the tag. */ - _bfd_elf_strtab_delref (hash_table->dynstr, strindex); - - return 0; -} - -static bfd_boolean -on_needed_list (const char *soname, struct bfd_link_needed_list *needed) -{ - for (; needed != NULL; needed = needed->next) - if (strcmp (soname, needed->name) == 0) - return TRUE; - - return FALSE; -} - -/* Sort symbol by value and section. */ -static int -elf_sort_symbol (const void *arg1, const void *arg2) -{ - const struct elf_link_hash_entry *h1; - const struct elf_link_hash_entry *h2; - bfd_signed_vma vdiff; - - h1 = *(const struct elf_link_hash_entry **) arg1; - h2 = *(const struct elf_link_hash_entry **) arg2; - vdiff = h1->root.u.def.value - h2->root.u.def.value; - if (vdiff != 0) - return vdiff > 0 ? 1 : -1; - else - { - long sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id; - if (sdiff != 0) - return sdiff > 0 ? 1 : -1; - } - return 0; -} - -/* This function is used to adjust offsets into .dynstr for - dynamic symbols. This is called via elf_link_hash_traverse. */ - -static bfd_boolean -elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data) -{ - struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data; - - if (h->dynindx != -1) - h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index); - return TRUE; -} - -/* Assign string offsets in .dynstr, update all structures referencing - them. */ - -static bfd_boolean -elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) -{ - struct elf_link_hash_table *hash_table = elf_hash_table (info); - struct elf_link_local_dynamic_entry *entry; - struct elf_strtab_hash *dynstr = hash_table->dynstr; - bfd *dynobj = hash_table->dynobj; - asection *sdyn; - bfd_size_type size; - const struct elf_backend_data *bed; - bfd_byte *extdyn; - - _bfd_elf_strtab_finalize (dynstr); - size = _bfd_elf_strtab_size (dynstr); - - bed = get_elf_backend_data (dynobj); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (sdyn != NULL); - - /* Update all .dynamic entries referencing .dynstr strings. */ - for (extdyn = sdyn->contents; - extdyn < sdyn->contents + sdyn->size; - extdyn += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - - bed->s->swap_dyn_in (dynobj, extdyn, &dyn); - switch (dyn.d_tag) - { - case DT_STRSZ: - dyn.d_un.d_val = size; - break; - case DT_NEEDED: - case DT_SONAME: - case DT_RPATH: - case DT_RUNPATH: - case DT_FILTER: - case DT_AUXILIARY: - case DT_AUDIT: - case DT_DEPAUDIT: - dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val); - break; - default: - continue; - } - bed->s->swap_dyn_out (dynobj, &dyn, extdyn); - } - - /* Now update local dynamic symbols. */ - for (entry = hash_table->dynlocal; entry ; entry = entry->next) - entry->isym.st_name = _bfd_elf_strtab_offset (dynstr, - entry->isym.st_name); - - /* And the rest of dynamic symbols. */ - elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr); - - /* Adjust version definitions. */ - if (elf_tdata (output_bfd)->cverdefs) - { - asection *s; - bfd_byte *p; - bfd_size_type i; - Elf_Internal_Verdef def; - Elf_Internal_Verdaux defaux; - - s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); - p = s->contents; - do - { - _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p, - &def); - p += sizeof (Elf_External_Verdef); - if (def.vd_aux != sizeof (Elf_External_Verdef)) - continue; - for (i = 0; i < def.vd_cnt; ++i) - { - _bfd_elf_swap_verdaux_in (output_bfd, - (Elf_External_Verdaux *) p, &defaux); - defaux.vda_name = _bfd_elf_strtab_offset (dynstr, - defaux.vda_name); - _bfd_elf_swap_verdaux_out (output_bfd, - &defaux, (Elf_External_Verdaux *) p); - p += sizeof (Elf_External_Verdaux); - } - } - while (def.vd_next); - } - - /* Adjust version references. */ - if (elf_tdata (output_bfd)->verref) - { - asection *s; - bfd_byte *p; - bfd_size_type i; - Elf_Internal_Verneed need; - Elf_Internal_Vernaux needaux; - - s = bfd_get_section_by_name (dynobj, ".gnu.version_r"); - p = s->contents; - do - { - _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p, - &need); - need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file); - _bfd_elf_swap_verneed_out (output_bfd, &need, - (Elf_External_Verneed *) p); - p += sizeof (Elf_External_Verneed); - for (i = 0; i < need.vn_cnt; ++i) - { - _bfd_elf_swap_vernaux_in (output_bfd, - (Elf_External_Vernaux *) p, &needaux); - needaux.vna_name = _bfd_elf_strtab_offset (dynstr, - needaux.vna_name); - _bfd_elf_swap_vernaux_out (output_bfd, - &needaux, - (Elf_External_Vernaux *) p); - p += sizeof (Elf_External_Vernaux); - } - } - while (need.vn_next); - } - - return TRUE; -} - -/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. - The default is to only match when the INPUT and OUTPUT are exactly - the same target. */ - -bfd_boolean -_bfd_elf_default_relocs_compatible (const bfd_target *input, - const bfd_target *output) -{ - return input == output; -} - -/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. - This version is used when different targets for the same architecture - are virtually identical. */ - -bfd_boolean -_bfd_elf_relocs_compatible (const bfd_target *input, - const bfd_target *output) -{ - const struct elf_backend_data *obed, *ibed; - - if (input == output) - return TRUE; - - ibed = xvec_get_elf_backend_data (input); - obed = xvec_get_elf_backend_data (output); - - if (ibed->arch != obed->arch) - return FALSE; - - /* If both backends are using this function, deem them compatible. */ - return ibed->relocs_compatible == obed->relocs_compatible; -} - -/* Add symbols from an ELF object file to the linker hash table. */ - -static bfd_boolean -elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) -{ - Elf_Internal_Ehdr *ehdr; - Elf_Internal_Shdr *hdr; - bfd_size_type symcount; - bfd_size_type extsymcount; - bfd_size_type extsymoff; - struct elf_link_hash_entry **sym_hash; - bfd_boolean dynamic; - Elf_External_Versym *extversym = NULL; - Elf_External_Versym *ever; - struct elf_link_hash_entry *weaks; - struct elf_link_hash_entry **nondeflt_vers = NULL; - bfd_size_type nondeflt_vers_cnt = 0; - Elf_Internal_Sym *isymbuf = NULL; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - const struct elf_backend_data *bed; - bfd_boolean add_needed; - struct elf_link_hash_table *htab; - bfd_size_type amt; - void *alloc_mark = NULL; - struct bfd_hash_entry **old_table = NULL; - unsigned int old_size = 0; - unsigned int old_count = 0; - void *old_tab = NULL; - void *old_hash; - void *old_ent; - struct bfd_link_hash_entry *old_undefs = NULL; - struct bfd_link_hash_entry *old_undefs_tail = NULL; - long old_dynsymcount = 0; - size_t tabsize = 0; - size_t hashsize = 0; - - htab = elf_hash_table (info); - bed = get_elf_backend_data (abfd); - - if ((abfd->flags & DYNAMIC) == 0) - dynamic = FALSE; - else - { - dynamic = TRUE; - - /* You can't use -r against a dynamic object. Also, there's no - hope of using a dynamic object which does not exactly match - the format of the output file. */ - if (info->relocatable - || !is_elf_hash_table (htab) - || info->output_bfd->xvec != abfd->xvec) - { - if (info->relocatable) - bfd_set_error (bfd_error_invalid_operation); - else - bfd_set_error (bfd_error_wrong_format); - goto error_return; - } - } - - ehdr = elf_elfheader (abfd); - if (info->warn_alternate_em - && bed->elf_machine_code != ehdr->e_machine - && ((bed->elf_machine_alt1 != 0 - && ehdr->e_machine == bed->elf_machine_alt1) - || (bed->elf_machine_alt2 != 0 - && ehdr->e_machine == bed->elf_machine_alt2))) - info->callbacks->einfo - (_("%P: alternate ELF machine code found (%d) in %B, expecting %d\n"), - ehdr->e_machine, abfd, bed->elf_machine_code); - - /* As a GNU extension, any input sections which are named - .gnu.warning.SYMBOL are treated as warning symbols for the given - symbol. This differs from .gnu.warning sections, which generate - warnings when they are included in an output file. */ - /* PR 12761: Also generate this warning when building shared libraries. */ - if (info->executable || info->shared) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - { - const char *name; - - name = bfd_get_section_name (abfd, s); - if (CONST_STRNEQ (name, ".gnu.warning.")) - { - char *msg; - bfd_size_type sz; - - name += sizeof ".gnu.warning." - 1; - - /* If this is a shared object, then look up the symbol - in the hash table. If it is there, and it is already - been defined, then we will not be using the entry - from this shared object, so we don't need to warn. - FIXME: If we see the definition in a regular object - later on, we will warn, but we shouldn't. The only - fix is to keep track of what warnings we are supposed - to emit, and then handle them all at the end of the - link. */ - if (dynamic) - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (htab, name, FALSE, FALSE, TRUE); - - /* FIXME: What about bfd_link_hash_common? */ - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - /* We don't want to issue this warning. Clobber - the section size so that the warning does not - get copied into the output file. */ - s->size = 0; - continue; - } - } - - sz = s->size; - msg = (char *) bfd_alloc (abfd, sz + 1); - if (msg == NULL) - goto error_return; - - if (! bfd_get_section_contents (abfd, s, msg, 0, sz)) - goto error_return; - - msg[sz] = '\0'; - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, BSF_WARNING, s, 0, msg, - FALSE, bed->collect, NULL))) - goto error_return; - - if (! info->relocatable) - { - /* Clobber the section size so that the warning does - not get copied into the output file. */ - s->size = 0; - - /* Also set SEC_EXCLUDE, so that symbols defined in - the warning section don't get copied to the output. */ - s->flags |= SEC_EXCLUDE; - } - } - } - } - - add_needed = TRUE; - if (! dynamic) - { - /* If we are creating a shared library, create all the dynamic - sections immediately. We need to attach them to something, - so we attach them to this BFD, provided it is the right - format. FIXME: If there are no input BFD's of the same - format as the output, we can't make a shared library. */ - if (info->shared - && is_elf_hash_table (htab) - && info->output_bfd->xvec == abfd->xvec - && !htab->dynamic_sections_created) - { - if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } - } - else if (!is_elf_hash_table (htab)) - goto error_return; - else - { - asection *s; - const char *soname = NULL; - char *audit = NULL; - struct bfd_link_needed_list *rpath = NULL, *runpath = NULL; - int ret; - - /* ld --just-symbols and dynamic objects don't mix very well. - ld shouldn't allow it. */ - if ((s = abfd->sections) != NULL - && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) - abort (); - - /* If this dynamic lib was specified on the command line with - --as-needed in effect, then we don't want to add a DT_NEEDED - tag unless the lib is actually used. Similary for libs brought - in by another lib's DT_NEEDED. When --no-add-needed is used - on a dynamic lib, we don't want to add a DT_NEEDED entry for - any dynamic library in DT_NEEDED tags in the dynamic lib at - all. */ - add_needed = (elf_dyn_lib_class (abfd) - & (DYN_AS_NEEDED | DYN_DT_NEEDED - | DYN_NO_NEEDED)) == 0; - - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - bfd_byte *dynbuf; - bfd_byte *extdyn; - unsigned int elfsec; - unsigned long shlink; - - if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) - { -error_free_dyn: - free (dynbuf); - goto error_return; - } - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == SHN_BAD) - goto error_free_dyn; - shlink = elf_elfsections (abfd)[elfsec]->sh_link; - - for (extdyn = dynbuf; - extdyn < dynbuf + s->size; - extdyn += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - - bed->s->swap_dyn_in (abfd, extdyn, &dyn); - if (dyn.d_tag == DT_SONAME) - { - unsigned int tagv = dyn.d_un.d_val; - soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (soname == NULL) - goto error_free_dyn; - } - if (dyn.d_tag == DT_NEEDED) - { - struct bfd_link_needed_list *n, **pn; - char *fnm, *anm; - unsigned int tagv = dyn.d_un.d_val; - - amt = sizeof (struct bfd_link_needed_list); - n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); - fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (n == NULL || fnm == NULL) - goto error_free_dyn; - amt = strlen (fnm) + 1; - anm = (char *) bfd_alloc (abfd, amt); - if (anm == NULL) - goto error_free_dyn; - memcpy (anm, fnm, amt); - n->name = anm; - n->by = abfd; - n->next = NULL; - for (pn = &htab->needed; *pn != NULL; pn = &(*pn)->next) - ; - *pn = n; - } - if (dyn.d_tag == DT_RUNPATH) - { - struct bfd_link_needed_list *n, **pn; - char *fnm, *anm; - unsigned int tagv = dyn.d_un.d_val; - - amt = sizeof (struct bfd_link_needed_list); - n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); - fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (n == NULL || fnm == NULL) - goto error_free_dyn; - amt = strlen (fnm) + 1; - anm = (char *) bfd_alloc (abfd, amt); - if (anm == NULL) - goto error_free_dyn; - memcpy (anm, fnm, amt); - n->name = anm; - n->by = abfd; - n->next = NULL; - for (pn = & runpath; - *pn != NULL; - pn = &(*pn)->next) - ; - *pn = n; - } - /* Ignore DT_RPATH if we have seen DT_RUNPATH. */ - if (!runpath && dyn.d_tag == DT_RPATH) - { - struct bfd_link_needed_list *n, **pn; - char *fnm, *anm; - unsigned int tagv = dyn.d_un.d_val; - - amt = sizeof (struct bfd_link_needed_list); - n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); - fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (n == NULL || fnm == NULL) - goto error_free_dyn; - amt = strlen (fnm) + 1; - anm = (char *) bfd_alloc (abfd, amt); - if (anm == NULL) - goto error_free_dyn; - memcpy (anm, fnm, amt); - n->name = anm; - n->by = abfd; - n->next = NULL; - for (pn = & rpath; - *pn != NULL; - pn = &(*pn)->next) - ; - *pn = n; - } - if (dyn.d_tag == DT_AUDIT) - { - unsigned int tagv = dyn.d_un.d_val; - audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - } - } - - free (dynbuf); - } - - /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that - frees all more recently bfd_alloc'd blocks as well. */ - if (runpath) - rpath = runpath; - - if (rpath) - { - struct bfd_link_needed_list **pn; - for (pn = &htab->runpath; *pn != NULL; pn = &(*pn)->next) - ; - *pn = rpath; - } - - /* We do not want to include any of the sections in a dynamic - object in the output file. We hack by simply clobbering the - list of sections in the BFD. This could be handled more - cleanly by, say, a new section flag; the existing - SEC_NEVER_LOAD flag is not the one we want, because that one - still implies that the section takes up space in the output - file. */ - bfd_section_list_clear (abfd); - - /* Find the name to use in a DT_NEEDED entry that refers to this - object. If the object has a DT_SONAME entry, we use it. - Otherwise, if the generic linker stuck something in - elf_dt_name, we use that. Otherwise, we just use the file - name. */ - if (soname == NULL || *soname == '\0') - { - soname = elf_dt_name (abfd); - if (soname == NULL || *soname == '\0') - soname = bfd_get_filename (abfd); - } - - /* Save the SONAME because sometimes the linker emulation code - will need to know it. */ - elf_dt_name (abfd) = soname; - - ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); - if (ret < 0) - goto error_return; - - /* If we have already included this dynamic object in the - link, just ignore it. There is no reason to include a - particular dynamic object more than once. */ - if (ret > 0) - return TRUE; - - /* Save the DT_AUDIT entry for the linker emulation code. */ - elf_dt_audit (abfd) = audit; - } - - /* If this is a dynamic object, we always link against the .dynsym - symbol table, not the .symtab symbol table. The dynamic linker - will only see the .dynsym symbol table, so there is no reason to - look at .symtab for a dynamic object. */ - - if (! dynamic || elf_dynsymtab (abfd) == 0) - hdr = &elf_tdata (abfd)->symtab_hdr; - else - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - - symcount = hdr->sh_size / bed->s->sizeof_sym; - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - if (elf_bad_symtab (abfd)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - sym_hash = NULL; - if (extsymcount != 0) - { - isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, - NULL, NULL, NULL); - if (isymbuf == NULL) - goto error_return; - - /* We store a pointer to the hash table entry for each external - symbol. */ - amt = extsymcount * sizeof (struct elf_link_hash_entry *); - sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt); - if (sym_hash == NULL) - goto error_free_sym; - elf_sym_hashes (abfd) = sym_hash; - } - - if (dynamic) - { - /* Read in any version definitions. */ - if (!_bfd_elf_slurp_version_tables (abfd, - info->default_imported_symver)) - goto error_free_sym; - - /* Read in the symbol versions, but don't bother to convert them - to internal format. */ - if (elf_dynversym (abfd) != 0) - { - Elf_Internal_Shdr *versymhdr; - - versymhdr = &elf_tdata (abfd)->dynversym_hdr; - extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size); - if (extversym == NULL) - goto error_free_sym; - amt = versymhdr->sh_size; - if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0 - || bfd_bread (extversym, amt, abfd) != amt) - goto error_free_vers; - } - } - - /* If we are loading an as-needed shared lib, save the symbol table - state before we start adding symbols. If the lib turns out - to be unneeded, restore the state. */ - if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) - { - unsigned int i; - size_t entsize; - - for (entsize = 0, i = 0; i < htab->root.table.size; i++) - { - struct bfd_hash_entry *p; - struct elf_link_hash_entry *h; - - for (p = htab->root.table.table[i]; p != NULL; p = p->next) - { - h = (struct elf_link_hash_entry *) p; - entsize += htab->root.table.entsize; - if (h->root.type == bfd_link_hash_warning) - entsize += htab->root.table.entsize; - } - } - - tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *); - hashsize = extsymcount * sizeof (struct elf_link_hash_entry *); - old_tab = bfd_malloc (tabsize + entsize + hashsize); - if (old_tab == NULL) - goto error_free_vers; - - /* Remember the current objalloc pointer, so that all mem for - symbols added can later be reclaimed. */ - alloc_mark = bfd_hash_allocate (&htab->root.table, 1); - if (alloc_mark == NULL) - goto error_free_vers; - - /* Make a special call to the linker "notice" function to - tell it that we are about to handle an as-needed lib. */ - if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, - notice_as_needed, 0, NULL)) - goto error_free_vers; - - /* Clone the symbol table and sym hashes. Remember some - pointers into the symbol table, and dynamic symbol count. */ - old_hash = (char *) old_tab + tabsize; - old_ent = (char *) old_hash + hashsize; - memcpy (old_tab, htab->root.table.table, tabsize); - memcpy (old_hash, sym_hash, hashsize); - old_undefs = htab->root.undefs; - old_undefs_tail = htab->root.undefs_tail; - old_table = htab->root.table.table; - old_size = htab->root.table.size; - old_count = htab->root.table.count; - old_dynsymcount = htab->dynsymcount; - - for (i = 0; i < htab->root.table.size; i++) - { - struct bfd_hash_entry *p; - struct elf_link_hash_entry *h; - - for (p = htab->root.table.table[i]; p != NULL; p = p->next) - { - memcpy (old_ent, p, htab->root.table.entsize); - old_ent = (char *) old_ent + htab->root.table.entsize; - h = (struct elf_link_hash_entry *) p; - if (h->root.type == bfd_link_hash_warning) - { - memcpy (old_ent, h->root.u.i.link, htab->root.table.entsize); - old_ent = (char *) old_ent + htab->root.table.entsize; - } - } - } - } - - weaks = NULL; - ever = extversym != NULL ? extversym + extsymoff : NULL; - for (isym = isymbuf, isymend = isymbuf + extsymcount; - isym < isymend; - isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) - { - int bind; - bfd_vma value; - asection *sec, *new_sec; - flagword flags; - const char *name; - struct elf_link_hash_entry *h; - bfd_boolean definition; - bfd_boolean size_change_ok; - bfd_boolean type_change_ok; - bfd_boolean new_weakdef; - bfd_boolean override; - bfd_boolean common; - unsigned int old_alignment; - bfd *old_bfd; - bfd * undef_bfd = NULL; - - override = FALSE; - - flags = BSF_NO_FLAGS; - sec = NULL; - value = isym->st_value; - *sym_hash = NULL; - common = bed->common_definition (isym); - - bind = ELF_ST_BIND (isym->st_info); - switch (bind) - { - case STB_LOCAL: - /* This should be impossible, since ELF requires that all - global symbols follow all local symbols, and that sh_info - point to the first global symbol. Unfortunately, Irix 5 - screws this up. */ - continue; - - case STB_GLOBAL: - if (isym->st_shndx != SHN_UNDEF && !common) - flags = BSF_GLOBAL; - break; - - case STB_WEAK: - flags = BSF_WEAK; - break; - - case STB_GNU_UNIQUE: - flags = BSF_GNU_UNIQUE; - break; - - default: - /* Leave it up to the processor backend. */ - break; - } - - if (isym->st_shndx == SHN_UNDEF) - sec = bfd_und_section_ptr; - else if (isym->st_shndx == SHN_ABS) - sec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - { - sec = bfd_com_section_ptr; - /* What ELF calls the size we call the value. What ELF - calls the value we call the alignment. */ - value = isym->st_size; - } - else - { - sec = bfd_section_from_elf_index (abfd, isym->st_shndx); - if (sec == NULL) - sec = bfd_abs_section_ptr; - else if (elf_discarded_section (sec)) - { - /* Symbols from discarded section are undefined. We keep - its visibility. */ - sec = bfd_und_section_ptr; - isym->st_shndx = SHN_UNDEF; - } - else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) - value -= sec->vma; - } - - name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, - isym->st_name); - if (name == NULL) - goto error_free_vers; - - if (isym->st_shndx == SHN_COMMON - && (abfd->flags & BFD_PLUGIN) != 0) - { - asection *xc = bfd_get_section_by_name (abfd, "COMMON"); - - if (xc == NULL) - { - flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP - | SEC_EXCLUDE); - xc = bfd_make_section_with_flags (abfd, "COMMON", sflags); - if (xc == NULL) - goto error_free_vers; - } - sec = xc; - } - else if (isym->st_shndx == SHN_COMMON - && ELF_ST_TYPE (isym->st_info) == STT_TLS - && !info->relocatable) - { - asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon"); - - if (tcomm == NULL) - { - flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON - | SEC_LINKER_CREATED); - tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags); - if (tcomm == NULL) - goto error_free_vers; - } - sec = tcomm; - } - else if (bed->elf_add_symbol_hook) - { - if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags, - &sec, &value)) - goto error_free_vers; - - /* The hook function sets the name to NULL if this symbol - should be skipped for some reason. */ - if (name == NULL) - continue; - } - - /* Sanity check that all possibilities were handled. */ - if (sec == NULL) - { - bfd_set_error (bfd_error_bad_value); - goto error_free_vers; - } - - if (bfd_is_und_section (sec) - || bfd_is_com_section (sec)) - definition = FALSE; - else - definition = TRUE; - - size_change_ok = FALSE; - type_change_ok = bed->type_change_ok; - old_alignment = 0; - old_bfd = NULL; - new_sec = sec; - - if (is_elf_hash_table (htab)) - { - Elf_Internal_Versym iver; - unsigned int vernum = 0; - bfd_boolean skip; - - /* If this is a definition of a symbol which was previously - referenced in a non-weak manner then make a note of the bfd - that contained the reference. This is used if we need to - refer to the source of the reference later on. */ - if (! bfd_is_und_section (sec)) - { - h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); - - if (h != NULL - && h->root.type == bfd_link_hash_undefined - && h->root.u.undef.abfd) - undef_bfd = h->root.u.undef.abfd; - } - - if (ever == NULL) - { - if (info->default_imported_symver) - /* Use the default symbol version created earlier. */ - iver.vs_vers = elf_tdata (abfd)->cverdefs; - else - iver.vs_vers = 0; - } - else - _bfd_elf_swap_versym_in (abfd, ever, &iver); - - vernum = iver.vs_vers & VERSYM_VERSION; - - /* If this is a hidden symbol, or if it is not version - 1, we append the version name to the symbol name. - However, we do not modify a non-hidden absolute symbol - if it is not a function, because it might be the version - symbol itself. FIXME: What if it isn't? */ - if ((iver.vs_vers & VERSYM_HIDDEN) != 0 - || (vernum > 1 - && (!bfd_is_abs_section (sec) - || bed->is_function_type (ELF_ST_TYPE (isym->st_info))))) - { - const char *verstr; - size_t namelen, verlen, newlen; - char *newname, *p; - - if (isym->st_shndx != SHN_UNDEF) - { - if (vernum > elf_tdata (abfd)->cverdefs) - verstr = NULL; - else if (vernum > 1) - verstr = - elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; - else - verstr = ""; - - if (verstr == NULL) - { - (*_bfd_error_handler) - (_("%B: %s: invalid version %u (max %d)"), - abfd, name, vernum, - elf_tdata (abfd)->cverdefs); - bfd_set_error (bfd_error_bad_value); - goto error_free_vers; - } - } - else - { - /* We cannot simply test for the number of - entries in the VERNEED section since the - numbers for the needed versions do not start - at 0. */ - Elf_Internal_Verneed *t; - - verstr = NULL; - for (t = elf_tdata (abfd)->verref; - t != NULL; - t = t->vn_nextref) - { - Elf_Internal_Vernaux *a; - - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - { - if (a->vna_other == vernum) - { - verstr = a->vna_nodename; - break; - } - } - if (a != NULL) - break; - } - if (verstr == NULL) - { - (*_bfd_error_handler) - (_("%B: %s: invalid needed version %d"), - abfd, name, vernum); - bfd_set_error (bfd_error_bad_value); - goto error_free_vers; - } - } - - namelen = strlen (name); - verlen = strlen (verstr); - newlen = namelen + verlen + 2; - if ((iver.vs_vers & VERSYM_HIDDEN) == 0 - && isym->st_shndx != SHN_UNDEF) - ++newlen; - - newname = (char *) bfd_hash_allocate (&htab->root.table, newlen); - if (newname == NULL) - goto error_free_vers; - memcpy (newname, name, namelen); - p = newname + namelen; - *p++ = ELF_VER_CHR; - /* If this is a defined non-hidden version symbol, - we add another @ to the name. This indicates the - default version of the symbol. */ - if ((iver.vs_vers & VERSYM_HIDDEN) == 0 - && isym->st_shndx != SHN_UNDEF) - *p++ = ELF_VER_CHR; - memcpy (p, verstr, verlen + 1); - - name = newname; - } - - /* If necessary, make a second attempt to locate the bfd - containing an unresolved, non-weak reference to the - current symbol. */ - if (! bfd_is_und_section (sec) && undef_bfd == NULL) - { - h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); - - if (h != NULL - && h->root.type == bfd_link_hash_undefined - && h->root.u.undef.abfd) - undef_bfd = h->root.u.undef.abfd; - } - - if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, - &value, &old_alignment, - sym_hash, &skip, &override, - &type_change_ok, &size_change_ok)) - goto error_free_vers; - - if (skip) - continue; - - if (override) - definition = FALSE; - - h = *sym_hash; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* Remember the old alignment if this is a common symbol, so - that we don't reduce the alignment later on. We can't - check later, because _bfd_generic_link_add_one_symbol - will set a default for the alignment which we want to - override. We also remember the old bfd where the existing - definition comes from. */ - switch (h->root.type) - { - default: - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - old_bfd = h->root.u.def.section->owner; - break; - - case bfd_link_hash_common: - old_bfd = h->root.u.c.p->section->owner; - old_alignment = h->root.u.c.p->alignment_power; - break; - } - - if (elf_tdata (abfd)->verdef != NULL - && ! override - && vernum > 1 - && definition) - h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; - } - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect, - (struct bfd_link_hash_entry **) sym_hash))) - goto error_free_vers; - - h = *sym_hash; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - *sym_hash = h; - if (is_elf_hash_table (htab)) - h->unique_global = (flags & BSF_GNU_UNIQUE) != 0; - - new_weakdef = FALSE; - if (dynamic - && definition - && (flags & BSF_WEAK) != 0 - && !bed->is_function_type (ELF_ST_TYPE (isym->st_info)) - && is_elf_hash_table (htab) - && h->u.weakdef == NULL) - { - /* Keep a list of all weak defined non function symbols from - a dynamic object, using the weakdef field. Later in this - function we will set the weakdef field to the correct - value. We only put non-function symbols from dynamic - objects on this list, because that happens to be the only - time we need to know the normal symbol corresponding to a - weak symbol, and the information is time consuming to - figure out. If the weakdef field is not already NULL, - then this symbol was already defined by some previous - dynamic object, and we will be using that previous - definition anyhow. */ - - h->u.weakdef = weaks; - weaks = h; - new_weakdef = TRUE; - } - - /* Set the alignment of a common symbol. */ - if ((common || bfd_is_com_section (sec)) - && h->root.type == bfd_link_hash_common) - { - unsigned int align; - - if (common) - align = bfd_log2 (isym->st_value); - else - { - /* The new symbol is a common symbol in a shared object. - We need to get the alignment from the section. */ - align = new_sec->alignment_power; - } - if (align > old_alignment) - h->root.u.c.p->alignment_power = align; - else - h->root.u.c.p->alignment_power = old_alignment; - } - - if (is_elf_hash_table (htab)) - { - bfd_boolean dynsym; - - /* Check the alignment when a common symbol is involved. This - can change when a common symbol is overridden by a normal - definition or a common symbol is ignored due to the old - normal definition. We need to make sure the maximum - alignment is maintained. */ - if ((old_alignment || common) - && h->root.type != bfd_link_hash_common) - { - unsigned int common_align; - unsigned int normal_align; - unsigned int symbol_align; - bfd *normal_bfd; - bfd *common_bfd; - - symbol_align = ffs (h->root.u.def.value) - 1; - if (h->root.u.def.section->owner != NULL - && (h->root.u.def.section->owner->flags & DYNAMIC) == 0) - { - normal_align = h->root.u.def.section->alignment_power; - if (normal_align > symbol_align) - normal_align = symbol_align; - } - else - normal_align = symbol_align; - - if (old_alignment) - { - common_align = old_alignment; - common_bfd = old_bfd; - normal_bfd = abfd; - } - else - { - common_align = bfd_log2 (isym->st_value); - common_bfd = abfd; - normal_bfd = old_bfd; - } - - if (normal_align < common_align) - { - /* PR binutils/2735 */ - if (normal_bfd == NULL) - (*_bfd_error_handler) - (_("Warning: alignment %u of common symbol `%s' in %B" - " is greater than the alignment (%u) of its section %A"), - common_bfd, h->root.u.def.section, - 1 << common_align, name, 1 << normal_align); - else - (*_bfd_error_handler) - (_("Warning: alignment %u of symbol `%s' in %B" - " is smaller than %u in %B"), - normal_bfd, common_bfd, - 1 << normal_align, name, 1 << common_align); - } - } - - /* Remember the symbol size if it isn't undefined. */ - if ((isym->st_size != 0 && isym->st_shndx != SHN_UNDEF) - && (definition || h->size == 0)) - { - if (h->size != 0 - && h->size != isym->st_size - && ! size_change_ok) - (*_bfd_error_handler) - (_("Warning: size of symbol `%s' changed" - " from %lu in %B to %lu in %B"), - old_bfd, abfd, - name, (unsigned long) h->size, - (unsigned long) isym->st_size); - - h->size = isym->st_size; - } - - /* If this is a common symbol, then we always want H->SIZE - to be the size of the common symbol. The code just above - won't fix the size if a common symbol becomes larger. We - don't warn about a size change here, because that is - covered by --warn-common. Allow changed between different - function types. */ - if (h->root.type == bfd_link_hash_common) - h->size = h->root.u.c.size; - - if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE - && (definition || h->type == STT_NOTYPE)) - { - unsigned int type = ELF_ST_TYPE (isym->st_info); - - /* Turn an IFUNC symbol from a DSO into a normal FUNC - symbol. */ - if (type == STT_GNU_IFUNC - && (abfd->flags & DYNAMIC) != 0) - type = STT_FUNC; - - if (h->type != type) - { - if (h->type != STT_NOTYPE && ! type_change_ok) - (*_bfd_error_handler) - (_("Warning: type of symbol `%s' changed" - " from %d to %d in %B"), - abfd, name, h->type, type); - - h->type = type; - } - } - - /* Merge st_other field. */ - elf_merge_st_other (abfd, h, isym, definition, dynamic); - - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of - the number of dynamic symbols we find. A dynamic symbol - is one which is referenced or defined by both a regular - object and a shared object. */ - dynsym = FALSE; - if (! dynamic) - { - if (! definition) - { - h->ref_regular = 1; - if (bind != STB_WEAK) - h->ref_regular_nonweak = 1; - } - else - { - h->def_regular = 1; - if (h->def_dynamic) - { - h->def_dynamic = 0; - h->ref_dynamic = 1; - } - } - if (! info->executable - || h->def_dynamic - || h->ref_dynamic) - dynsym = TRUE; - } - else - { - if (! definition) - h->ref_dynamic = 1; - else - { - h->def_dynamic = 1; - h->dynamic_def = 1; - } - if (h->def_regular - || h->ref_regular - || (h->u.weakdef != NULL - && ! new_weakdef - && h->u.weakdef->dynindx != -1)) - dynsym = TRUE; - } - - /* We don't want to make debug symbol dynamic. */ - if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable) - dynsym = FALSE; - - /* Nor should we make plugin symbols dynamic. */ - if ((abfd->flags & BFD_PLUGIN) != 0) - dynsym = FALSE; - - if (definition) - h->target_internal = isym->st_target_internal; - - /* Check to see if we need to add an indirect symbol for - the default name. */ - if (definition || h->root.type == bfd_link_hash_common) - if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, - &sec, &value, &dynsym, - override)) - goto error_free_vers; - - if (definition && !dynamic) - { - char *p = strchr (name, ELF_VER_CHR); - if (p != NULL && p[1] != ELF_VER_CHR) - { - /* Queue non-default versions so that .symver x, x@FOO - aliases can be checked. */ - if (!nondeflt_vers) - { - amt = ((isymend - isym + 1) - * sizeof (struct elf_link_hash_entry *)); - nondeflt_vers = - (struct elf_link_hash_entry **) bfd_malloc (amt); - if (!nondeflt_vers) - goto error_free_vers; - } - nondeflt_vers[nondeflt_vers_cnt++] = h; - } - } - - if (dynsym && h->dynindx == -1) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_free_vers; - if (h->u.weakdef != NULL - && ! new_weakdef - && h->u.weakdef->dynindx == -1) - { - if (!bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef)) - goto error_free_vers; - } - } - else if (dynsym && h->dynindx != -1) - /* If the symbol already has a dynamic index, but - visibility says it should not be visible, turn it into - a local symbol. */ - switch (ELF_ST_VISIBILITY (h->other)) - { - case STV_INTERNAL: - case STV_HIDDEN: - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - dynsym = FALSE; - break; - } - - if (!add_needed - && definition - && ((dynsym - && h->ref_regular) - || (h->ref_dynamic - && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0 - && !on_needed_list (elf_dt_name (abfd), htab->needed)))) - { - int ret; - const char *soname = elf_dt_name (abfd); - - /* A symbol from a library loaded via DT_NEEDED of some - other library is referenced by a regular object. - Add a DT_NEEDED entry for it. Issue an error if - --no-add-needed is used and the reference was not - a weak one. */ - if (undef_bfd != NULL - && (elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0) - { - (*_bfd_error_handler) - (_("%B: undefined reference to symbol '%s'"), - undef_bfd, name); - (*_bfd_error_handler) - (_("note: '%s' is defined in DSO %B so try adding it to the linker command line"), - abfd, name); - bfd_set_error (bfd_error_invalid_operation); - goto error_free_vers; - } - - elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class) - (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED); - - add_needed = TRUE; - ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); - if (ret < 0) - goto error_free_vers; - - BFD_ASSERT (ret == 0); - } - } - } - - if (extversym != NULL) - { - free (extversym); - extversym = NULL; - } - - if (isymbuf != NULL) - { - free (isymbuf); - isymbuf = NULL; - } - - if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) - { - unsigned int i; - - /* Restore the symbol table. */ - if (bed->as_needed_cleanup) - (*bed->as_needed_cleanup) (abfd, info); - old_hash = (char *) old_tab + tabsize; - old_ent = (char *) old_hash + hashsize; - sym_hash = elf_sym_hashes (abfd); - htab->root.table.table = old_table; - htab->root.table.size = old_size; - htab->root.table.count = old_count; - memcpy (htab->root.table.table, old_tab, tabsize); - memcpy (sym_hash, old_hash, hashsize); - htab->root.undefs = old_undefs; - htab->root.undefs_tail = old_undefs_tail; - for (i = 0; i < htab->root.table.size; i++) - { - struct bfd_hash_entry *p; - struct elf_link_hash_entry *h; - bfd_size_type size; - unsigned int alignment_power; - - for (p = htab->root.table.table[i]; p != NULL; p = p->next) - { - h = (struct elf_link_hash_entry *) p; - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->dynindx >= old_dynsymcount) - _bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index); - - /* Preserve the maximum alignment and size for common - symbols even if this dynamic lib isn't on DT_NEEDED - since it can still be loaded at the run-time by another - dynamic lib. */ - if (h->root.type == bfd_link_hash_common) - { - size = h->root.u.c.size; - alignment_power = h->root.u.c.p->alignment_power; - } - else - { - size = 0; - alignment_power = 0; - } - memcpy (p, old_ent, htab->root.table.entsize); - old_ent = (char *) old_ent + htab->root.table.entsize; - h = (struct elf_link_hash_entry *) p; - if (h->root.type == bfd_link_hash_warning) - { - memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize); - old_ent = (char *) old_ent + htab->root.table.entsize; - } - else if (h->root.type == bfd_link_hash_common) - { - if (size > h->root.u.c.size) - h->root.u.c.size = size; - if (alignment_power > h->root.u.c.p->alignment_power) - h->root.u.c.p->alignment_power = alignment_power; - } - } - } - - /* Make a special call to the linker "notice" function to - tell it that symbols added for crefs may need to be removed. */ - if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, - notice_not_needed, 0, NULL)) - goto error_free_vers; - - free (old_tab); - objalloc_free_block ((struct objalloc *) htab->root.table.memory, - alloc_mark); - if (nondeflt_vers != NULL) - free (nondeflt_vers); - return TRUE; - } - - if (old_tab != NULL) - { - if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, - notice_needed, 0, NULL)) - goto error_free_vers; - free (old_tab); - old_tab = NULL; - } - - /* Now that all the symbols from this input file are created, handle - .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */ - if (nondeflt_vers != NULL) - { - bfd_size_type cnt, symidx; - - for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt) - { - struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi; - char *shortname, *p; - - p = strchr (h->root.root.string, ELF_VER_CHR); - if (p == NULL - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak)) - continue; - - amt = p - h->root.root.string; - shortname = (char *) bfd_malloc (amt + 1); - if (!shortname) - goto error_free_vers; - memcpy (shortname, h->root.root.string, amt); - shortname[amt] = '\0'; - - hi = (struct elf_link_hash_entry *) - bfd_link_hash_lookup (&htab->root, shortname, - FALSE, FALSE, FALSE); - if (hi != NULL - && hi->root.type == h->root.type - && hi->root.u.def.value == h->root.u.def.value - && hi->root.u.def.section == h->root.u.def.section) - { - (*bed->elf_backend_hide_symbol) (info, hi, TRUE); - hi->root.type = bfd_link_hash_indirect; - hi->root.u.i.link = (struct bfd_link_hash_entry *) h; - (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); - sym_hash = elf_sym_hashes (abfd); - if (sym_hash) - for (symidx = 0; symidx < extsymcount; ++symidx) - if (sym_hash[symidx] == hi) - { - sym_hash[symidx] = h; - break; - } - } - free (shortname); - } - free (nondeflt_vers); - nondeflt_vers = NULL; - } - - /* Now set the weakdefs field correctly for all the weak defined - symbols we found. The only way to do this is to search all the - symbols. Since we only need the information for non functions in - dynamic objects, that's the only time we actually put anything on - the list WEAKS. We need this information so that if a regular - object refers to a symbol defined weakly in a dynamic object, the - real symbol in the dynamic object is also put in the dynamic - symbols; we also must arrange for both symbols to point to the - same memory location. We could handle the general case of symbol - aliasing, but a general symbol alias can only be generated in - assembler code, handling it correctly would be very time - consuming, and other ELF linkers don't handle general aliasing - either. */ - if (weaks != NULL) - { - struct elf_link_hash_entry **hpp; - struct elf_link_hash_entry **hppend; - struct elf_link_hash_entry **sorted_sym_hash; - struct elf_link_hash_entry *h; - size_t sym_count; - - /* Since we have to search the whole symbol list for each weak - defined symbol, search time for N weak defined symbols will be - O(N^2). Binary search will cut it down to O(NlogN). */ - amt = extsymcount * sizeof (struct elf_link_hash_entry *); - sorted_sym_hash = (struct elf_link_hash_entry **) bfd_malloc (amt); - if (sorted_sym_hash == NULL) - goto error_return; - sym_hash = sorted_sym_hash; - hpp = elf_sym_hashes (abfd); - hppend = hpp + extsymcount; - sym_count = 0; - for (; hpp < hppend; hpp++) - { - h = *hpp; - if (h != NULL - && h->root.type == bfd_link_hash_defined - && !bed->is_function_type (h->type)) - { - *sym_hash = h; - sym_hash++; - sym_count++; - } - } - - qsort (sorted_sym_hash, sym_count, - sizeof (struct elf_link_hash_entry *), - elf_sort_symbol); - - while (weaks != NULL) - { - struct elf_link_hash_entry *hlook; - asection *slook; - bfd_vma vlook; - long ilook; - size_t i, j, idx; - - hlook = weaks; - weaks = hlook->u.weakdef; - hlook->u.weakdef = NULL; - - BFD_ASSERT (hlook->root.type == bfd_link_hash_defined - || hlook->root.type == bfd_link_hash_defweak - || hlook->root.type == bfd_link_hash_common - || hlook->root.type == bfd_link_hash_indirect); - slook = hlook->root.u.def.section; - vlook = hlook->root.u.def.value; - - ilook = -1; - i = 0; - j = sym_count; - while (i < j) - { - bfd_signed_vma vdiff; - idx = (i + j) / 2; - h = sorted_sym_hash [idx]; - vdiff = vlook - h->root.u.def.value; - if (vdiff < 0) - j = idx; - else if (vdiff > 0) - i = idx + 1; - else - { - long sdiff = slook->id - h->root.u.def.section->id; - if (sdiff < 0) - j = idx; - else if (sdiff > 0) - i = idx + 1; - else - { - ilook = idx; - break; - } - } - } - - /* We didn't find a value/section match. */ - if (ilook == -1) - continue; - - for (i = ilook; i < sym_count; i++) - { - h = sorted_sym_hash [i]; - - /* Stop if value or section doesn't match. */ - if (h->root.u.def.value != vlook - || h->root.u.def.section != slook) - break; - else if (h != hlook) - { - hlook->u.weakdef = h; - - /* If the weak definition is in the list of dynamic - symbols, make sure the real definition is put - there as well. */ - if (hlook->dynindx != -1 && h->dynindx == -1) - { - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - { - err_free_sym_hash: - free (sorted_sym_hash); - goto error_return; - } - } - - /* If the real definition is in the list of dynamic - symbols, make sure the weak definition is put - there as well. If we don't do this, then the - dynamic loader might not merge the entries for the - real definition and the weak definition. */ - if (h->dynindx != -1 && hlook->dynindx == -1) - { - if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) - goto err_free_sym_hash; - } - break; - } - } - } - - free (sorted_sym_hash); - } - - if (bed->check_directives - && !(*bed->check_directives) (abfd, info)) - return FALSE; - - /* If this object is the same format as the output object, and it is - not a shared library, then let the backend look through the - relocs. - - This is required to build global offset table entries and to - arrange for dynamic relocs. It is not required for the - particular common case of linking non PIC code, even when linking - against shared libraries, but unfortunately there is no way of - knowing whether an object file has been compiled PIC or not. - Looking through the relocs is not particularly time consuming. - The problem is that we must either (1) keep the relocs in memory, - which causes the linker to require additional runtime memory or - (2) read the relocs twice from the input file, which wastes time. - This would be a good case for using mmap. - - I have no idea how to handle linking PIC code into a file of a - different format. It probably can't be done. */ - if (! dynamic - && is_elf_hash_table (htab) - && bed->check_relocs != NULL - && elf_object_id (abfd) == elf_hash_table_id (htab) - && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec)) - { - asection *o; - - for (o = abfd->sections; o != NULL; o = o->next) - { - Elf_Internal_Rela *internal_relocs; - bfd_boolean ok; - - if ((o->flags & SEC_RELOC) == 0 - || o->reloc_count == 0 - || ((info->strip == strip_all || info->strip == strip_debugger) - && (o->flags & SEC_DEBUGGING) != 0) - || bfd_is_abs_section (o->output_section)) - continue; - - internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, - info->keep_memory); - if (internal_relocs == NULL) - goto error_return; - - ok = (*bed->check_relocs) (abfd, info, o, internal_relocs); - - if (elf_section_data (o)->relocs != internal_relocs) - free (internal_relocs); - - if (! ok) - goto error_return; - } - } - - /* If this is a non-traditional link, try to optimize the handling - of the .stab/.stabstr sections. */ - if (! dynamic - && ! info->traditional_format - && is_elf_hash_table (htab) - && (info->strip != strip_all && info->strip != strip_debugger)) - { - asection *stabstr; - - stabstr = bfd_get_section_by_name (abfd, ".stabstr"); - if (stabstr != NULL) - { - bfd_size_type string_offset = 0; - asection *stab; - - for (stab = abfd->sections; stab; stab = stab->next) - if (CONST_STRNEQ (stab->name, ".stab") - && (!stab->name[5] || - (stab->name[5] == '.' && ISDIGIT (stab->name[6]))) - && (stab->flags & SEC_MERGE) == 0 - && !bfd_is_abs_section (stab->output_section)) - { - struct bfd_elf_section_data *secdata; - - secdata = elf_section_data (stab); - if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab, - stabstr, &secdata->sec_info, - &string_offset)) - goto error_return; - if (secdata->sec_info) - stab->sec_info_type = ELF_INFO_TYPE_STABS; - } - } - } - - if (is_elf_hash_table (htab) && add_needed) - { - /* Add this bfd to the loaded list. */ - struct elf_link_loaded_list *n; - - n = (struct elf_link_loaded_list *) - bfd_alloc (abfd, sizeof (struct elf_link_loaded_list)); - if (n == NULL) - goto error_return; - n->abfd = abfd; - n->next = htab->loaded; - htab->loaded = n; - } - - return TRUE; - - error_free_vers: - if (old_tab != NULL) - free (old_tab); - if (nondeflt_vers != NULL) - free (nondeflt_vers); - if (extversym != NULL) - free (extversym); - error_free_sym: - if (isymbuf != NULL) - free (isymbuf); - error_return: - return FALSE; -} - -/* Return the linker hash table entry of a symbol that might be - satisfied by an archive symbol. Return -1 on error. */ - -struct elf_link_hash_entry * -_bfd_elf_archive_symbol_lookup (bfd *abfd, - struct bfd_link_info *info, - const char *name) -{ - struct elf_link_hash_entry *h; - char *p, *copy; - size_t len, first; - - h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, TRUE); - if (h != NULL) - return h; - - /* If this is a default version (the name contains @@), look up the - symbol again with only one `@' as well as without the version. - The effect is that references to the symbol with and without the - version will be matched by the default symbol in the archive. */ - - p = strchr (name, ELF_VER_CHR); - if (p == NULL || p[1] != ELF_VER_CHR) - return h; - - /* First check with only one `@'. */ - len = strlen (name); - copy = (char *) bfd_alloc (abfd, len); - if (copy == NULL) - return (struct elf_link_hash_entry *) 0 - 1; - - first = p - name + 1; - memcpy (copy, name, first); - memcpy (copy + first, name + first + 1, len - first); - - h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, TRUE); - if (h == NULL) - { - /* We also need to check references to the symbol without the - version. */ - copy[first - 1] = '\0'; - h = elf_link_hash_lookup (elf_hash_table (info), copy, - FALSE, FALSE, TRUE); - } - - bfd_release (abfd, copy); - return h; -} - -/* Add symbols from an ELF archive file to the linker hash table. We - don't use _bfd_generic_link_add_archive_symbols because of a - problem which arises on UnixWare. The UnixWare libc.so is an - archive which includes an entry libc.so.1 which defines a bunch of - symbols. The libc.so archive also includes a number of other - object files, which also define symbols, some of which are the same - as those defined in libc.so.1. Correct linking requires that we - consider each object file in turn, and include it if it defines any - symbols we need. _bfd_generic_link_add_archive_symbols does not do - this; it looks through the list of undefined symbols, and includes - any object file which defines them. When this algorithm is used on - UnixWare, it winds up pulling in libc.so.1 early and defining a - bunch of symbols. This means that some of the other objects in the - archive are not included in the link, which is incorrect since they - precede libc.so.1 in the archive. - - Fortunately, ELF archive handling is simpler than that done by - _bfd_generic_link_add_archive_symbols, which has to allow for a.out - oddities. In ELF, if we find a symbol in the archive map, and the - symbol is currently undefined, we know that we must pull in that - object file. - - Unfortunately, we do have to make multiple passes over the symbol - table until nothing further is resolved. */ - -static bfd_boolean -elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) -{ - symindex c; - bfd_boolean *defined = NULL; - bfd_boolean *included = NULL; - carsym *symdefs; - bfd_boolean loop; - bfd_size_type amt; - const struct elf_backend_data *bed; - struct elf_link_hash_entry * (*archive_symbol_lookup) - (bfd *, struct bfd_link_info *, const char *); - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, NULL) == NULL) - return TRUE; - bfd_set_error (bfd_error_no_armap); - return FALSE; - } - - /* Keep track of all symbols we know to be already defined, and all - files we know to be already included. This is to speed up the - second and subsequent passes. */ - c = bfd_ardata (abfd)->symdef_count; - if (c == 0) - return TRUE; - amt = c; - amt *= sizeof (bfd_boolean); - defined = (bfd_boolean *) bfd_zmalloc (amt); - included = (bfd_boolean *) bfd_zmalloc (amt); - if (defined == NULL || included == NULL) - goto error_return; - - symdefs = bfd_ardata (abfd)->symdefs; - bed = get_elf_backend_data (abfd); - archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup; - - do - { - file_ptr last; - symindex i; - carsym *symdef; - carsym *symdefend; - - loop = FALSE; - last = -1; - - symdef = symdefs; - symdefend = symdef + c; - for (i = 0; symdef < symdefend; symdef++, i++) - { - struct elf_link_hash_entry *h; - bfd *element; - struct bfd_link_hash_entry *undefs_tail; - symindex mark; - - if (defined[i] || included[i]) - continue; - if (symdef->file_offset == last) - { - included[i] = TRUE; - continue; - } - - h = archive_symbol_lookup (abfd, info, symdef->name); - if (h == (struct elf_link_hash_entry *) 0 - 1) - goto error_return; - - if (h == NULL) - continue; - - if (h->root.type == bfd_link_hash_common) - { - /* We currently have a common symbol. The archive map contains - a reference to this symbol, so we may want to include it. We - only want to include it however, if this archive element - contains a definition of the symbol, not just another common - declaration of it. - - Unfortunately some archivers (including GNU ar) will put - declarations of common symbols into their archive maps, as - well as real definitions, so we cannot just go by the archive - map alone. Instead we must read in the element's symbol - table and check that to see what kind of symbol definition - this is. */ - if (! elf_link_is_defined_archive_symbol (abfd, symdef)) - continue; - } - else if (h->root.type != bfd_link_hash_undefined) - { - if (h->root.type != bfd_link_hash_undefweak) - defined[i] = TRUE; - continue; - } - - /* We need to include this archive member. */ - element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); - if (element == NULL) - goto error_return; - - if (! bfd_check_format (element, bfd_object)) - goto error_return; - - /* Doublecheck that we have not included this object - already--it should be impossible, but there may be - something wrong with the archive. */ - if (element->archive_pass != 0) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - element->archive_pass = 1; - - undefs_tail = info->hash->undefs_tail; - - if (!(*info->callbacks - ->add_archive_element) (info, element, symdef->name, &element)) - goto error_return; - if (!bfd_link_add_symbols (element, info)) - goto error_return; - - /* If there are any new undefined symbols, we need to make - another pass through the archive in order to see whether - they can be defined. FIXME: This isn't perfect, because - common symbols wind up on undefs_tail and because an - undefined symbol which is defined later on in this pass - does not require another pass. This isn't a bug, but it - does make the code less efficient than it could be. */ - if (undefs_tail != info->hash->undefs_tail) - loop = TRUE; - - /* Look backward to mark all symbols from this object file - which we have already seen in this pass. */ - mark = i; - do - { - included[mark] = TRUE; - if (mark == 0) - break; - --mark; - } - while (symdefs[mark].file_offset == symdef->file_offset); - - /* We mark subsequent symbols from this object file as we go - on through the loop. */ - last = symdef->file_offset; - } - } - while (loop); - - free (defined); - free (included); - - return TRUE; - - error_return: - if (defined != NULL) - free (defined); - if (included != NULL) - free (included); - return FALSE; -} - -/* Given an ELF BFD, add symbols to the global hash table as - appropriate. */ - -bfd_boolean -bfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info) -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return elf_link_add_object_symbols (abfd, info); - case bfd_archive: - return elf_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } -} - -struct hash_codes_info -{ - unsigned long *hashcodes; - bfd_boolean error; -}; - -/* This function will be called though elf_link_hash_traverse to store - all hash value of the exported symbols in an array. */ - -static bfd_boolean -elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) -{ - struct hash_codes_info *inf = (struct hash_codes_info *) data; - const char *name; - char *p; - unsigned long ha; - char *alc = NULL; - - /* Ignore indirect symbols. These are added by the versioning code. */ - if (h->dynindx == -1) - return TRUE; - - name = h->root.root.string; - p = strchr (name, ELF_VER_CHR); - if (p != NULL) - { - alc = (char *) bfd_malloc (p - name + 1); - if (alc == NULL) - { - inf->error = TRUE; - return FALSE; - } - memcpy (alc, name, p - name); - alc[p - name] = '\0'; - name = alc; - } - - /* Compute the hash value. */ - ha = bfd_elf_hash (name); - - /* Store the found hash value in the array given as the argument. */ - *(inf->hashcodes)++ = ha; - - /* And store it in the struct so that we can put it in the hash table - later. */ - h->u.elf_hash_value = ha; - - if (alc != NULL) - free (alc); - - return TRUE; -} - -struct collect_gnu_hash_codes -{ - bfd *output_bfd; - const struct elf_backend_data *bed; - unsigned long int nsyms; - unsigned long int maskbits; - unsigned long int *hashcodes; - unsigned long int *hashval; - unsigned long int *indx; - unsigned long int *counts; - bfd_vma *bitmask; - bfd_byte *contents; - long int min_dynindx; - unsigned long int bucketcount; - unsigned long int symindx; - long int local_indx; - long int shift1, shift2; - unsigned long int mask; - bfd_boolean error; -}; - -/* This function will be called though elf_link_hash_traverse to store - all hash value of the exported symbols in an array. */ - -static bfd_boolean -elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) -{ - struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; - const char *name; - char *p; - unsigned long ha; - char *alc = NULL; - - /* Ignore indirect symbols. These are added by the versioning code. */ - if (h->dynindx == -1) - return TRUE; - - /* Ignore also local symbols and undefined symbols. */ - if (! (*s->bed->elf_hash_symbol) (h)) - return TRUE; - - name = h->root.root.string; - p = strchr (name, ELF_VER_CHR); - if (p != NULL) - { - alc = (char *) bfd_malloc (p - name + 1); - if (alc == NULL) - { - s->error = TRUE; - return FALSE; - } - memcpy (alc, name, p - name); - alc[p - name] = '\0'; - name = alc; - } - - /* Compute the hash value. */ - ha = bfd_elf_gnu_hash (name); - - /* Store the found hash value in the array for compute_bucket_count, - and also for .dynsym reordering purposes. */ - s->hashcodes[s->nsyms] = ha; - s->hashval[h->dynindx] = ha; - ++s->nsyms; - if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx) - s->min_dynindx = h->dynindx; - - if (alc != NULL) - free (alc); - - return TRUE; -} - -/* This function will be called though elf_link_hash_traverse to do - final dynaminc symbol renumbering. */ - -static bfd_boolean -elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data) -{ - struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; - unsigned long int bucket; - unsigned long int val; - - /* Ignore indirect symbols. */ - if (h->dynindx == -1) - return TRUE; - - /* Ignore also local symbols and undefined symbols. */ - if (! (*s->bed->elf_hash_symbol) (h)) - { - if (h->dynindx >= s->min_dynindx) - h->dynindx = s->local_indx++; - return TRUE; - } - - bucket = s->hashval[h->dynindx] % s->bucketcount; - val = (s->hashval[h->dynindx] >> s->shift1) - & ((s->maskbits >> s->shift1) - 1); - s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask); - s->bitmask[val] - |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask); - val = s->hashval[h->dynindx] & ~(unsigned long int) 1; - if (s->counts[bucket] == 1) - /* Last element terminates the chain. */ - val |= 1; - bfd_put_32 (s->output_bfd, val, - s->contents + (s->indx[bucket] - s->symindx) * 4); - --s->counts[bucket]; - h->dynindx = s->indx[bucket]++; - return TRUE; -} - -/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ - -bfd_boolean -_bfd_elf_hash_symbol (struct elf_link_hash_entry *h) -{ - return !(h->forced_local - || h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak - || ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && h->root.u.def.section->output_section == NULL)); -} - -/* Array used to determine the number of hash table buckets to use - based on the number of symbols there are. If there are fewer than - 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, - fewer than 37 we use 17 buckets, and so forth. We never use more - than 32771 buckets. */ - -static const size_t elf_buckets[] = -{ - 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, - 16411, 32771, 0 -}; - -/* Compute bucket count for hashing table. We do not use a static set - of possible tables sizes anymore. Instead we determine for all - possible reasonable sizes of the table the outcome (i.e., the - number of collisions etc) and choose the best solution. The - weighting functions are not too simple to allow the table to grow - without bounds. Instead one of the weighting factors is the size. - Therefore the result is always a good payoff between few collisions - (= short chain lengths) and table size. */ -static size_t -compute_bucket_count (struct bfd_link_info *info ATTRIBUTE_UNUSED, - unsigned long int *hashcodes ATTRIBUTE_UNUSED, - unsigned long int nsyms, - int gnu_hash) -{ - size_t best_size = 0; - unsigned long int i; - - /* We have a problem here. The following code to optimize the table - size requires an integer type with more the 32 bits. If - BFD_HOST_U_64_BIT is set we know about such a type. */ -#ifdef BFD_HOST_U_64_BIT - if (info->optimize) - { - size_t minsize; - size_t maxsize; - BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0); - bfd *dynobj = elf_hash_table (info)->dynobj; - size_t dynsymcount = elf_hash_table (info)->dynsymcount; - const struct elf_backend_data *bed = get_elf_backend_data (dynobj); - unsigned long int *counts; - bfd_size_type amt; - unsigned int no_improvement_count = 0; - - /* Possible optimization parameters: if we have NSYMS symbols we say - that the hashing table must at least have NSYMS/4 and at most - 2*NSYMS buckets. */ - minsize = nsyms / 4; - if (minsize == 0) - minsize = 1; - best_size = maxsize = nsyms * 2; - if (gnu_hash) - { - if (minsize < 2) - minsize = 2; - if ((best_size & 31) == 0) - ++best_size; - } - - /* Create array where we count the collisions in. We must use bfd_malloc - since the size could be large. */ - amt = maxsize; - amt *= sizeof (unsigned long int); - counts = (unsigned long int *) bfd_malloc (amt); - if (counts == NULL) - return 0; - - /* Compute the "optimal" size for the hash table. The criteria is a - minimal chain length. The minor criteria is (of course) the size - of the table. */ - for (i = minsize; i < maxsize; ++i) - { - /* Walk through the array of hashcodes and count the collisions. */ - BFD_HOST_U_64_BIT max; - unsigned long int j; - unsigned long int fact; - - if (gnu_hash && (i & 31) == 0) - continue; - - memset (counts, '\0', i * sizeof (unsigned long int)); - - /* Determine how often each hash bucket is used. */ - for (j = 0; j < nsyms; ++j) - ++counts[hashcodes[j] % i]; - - /* For the weight function we need some information about the - pagesize on the target. This is information need not be 100% - accurate. Since this information is not available (so far) we - define it here to a reasonable default value. If it is crucial - to have a better value some day simply define this value. */ -# ifndef BFD_TARGET_PAGESIZE -# define BFD_TARGET_PAGESIZE (4096) -# endif - - /* We in any case need 2 + DYNSYMCOUNT entries for the size values - and the chains. */ - max = (2 + dynsymcount) * bed->s->sizeof_hash_entry; - -# if 1 - /* Variant 1: optimize for short chains. We add the squares - of all the chain lengths (which favors many small chain - over a few long chains). */ - for (j = 0; j < i; ++j) - max += counts[j] * counts[j]; - - /* This adds penalties for the overall size of the table. */ - fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; - max *= fact * fact; -# else - /* Variant 2: Optimize a lot more for small table. Here we - also add squares of the size but we also add penalties for - empty slots (the +1 term). */ - for (j = 0; j < i; ++j) - max += (1 + counts[j]) * (1 + counts[j]); - - /* The overall size of the table is considered, but not as - strong as in variant 1, where it is squared. */ - fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; - max *= fact; -# endif - - /* Compare with current best results. */ - if (max < best_chlen) - { - best_chlen = max; - best_size = i; - no_improvement_count = 0; - } - /* PR 11843: Avoid futile long searches for the best bucket size - when there are a large number of symbols. */ - else if (++no_improvement_count == 100) - break; - } - - free (counts); - } - else -#endif /* defined (BFD_HOST_U_64_BIT) */ - { - /* This is the fallback solution if no 64bit type is available or if we - are not supposed to spend much time on optimizations. We select the - bucket count using a fixed set of numbers. */ - for (i = 0; elf_buckets[i] != 0; i++) - { - best_size = elf_buckets[i]; - if (nsyms < elf_buckets[i + 1]) - break; - } - if (gnu_hash && best_size < 2) - best_size = 2; - } - - return best_size; -} - -/* Size any SHT_GROUP section for ld -r. */ - -bfd_boolean -_bfd_elf_size_group_sections (struct bfd_link_info *info) -{ - bfd *ibfd; - - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) - if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour - && !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr)) - return FALSE; - return TRUE; -} - -/* Set up the sizes and contents of the ELF dynamic sections. This is - called by the ELF linker emulation before_allocation routine. We - must set the sizes of the sections before the linker sets the - addresses of the various sections. */ - -bfd_boolean -bfd_elf_size_dynamic_sections (bfd *output_bfd, - const char *soname, - const char *rpath, - const char *filter_shlib, - const char *audit, - const char *depaudit, - const char * const *auxiliary_filters, - struct bfd_link_info *info, - asection **sinterpptr) -{ - bfd_size_type soname_indx; - bfd *dynobj; - const struct elf_backend_data *bed; - struct elf_info_failed asvinfo; - - *sinterpptr = NULL; - - soname_indx = (bfd_size_type) -1; - - if (!is_elf_hash_table (info->hash)) - return TRUE; - - bed = get_elf_backend_data (output_bfd); - if (info->execstack) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - else if (info->noexecstack) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; - else - { - bfd *inputobj; - asection *notesec = NULL; - int exec = 0; - - for (inputobj = info->input_bfds; - inputobj; - inputobj = inputobj->link_next) - { - asection *s; - - if (inputobj->flags - & (DYNAMIC | EXEC_P | BFD_PLUGIN | BFD_LINKER_CREATED)) - continue; - s = bfd_get_section_by_name (inputobj, ".note.GNU-stack"); - if (s) - { - if (s->flags & SEC_CODE) - exec = PF_X; - notesec = s; - } - else if (bed->default_execstack) - exec = PF_X; - } - if (notesec) - { - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; - if (exec && info->relocatable - && notesec->output_section != bfd_abs_section_ptr) - notesec->output_section->flags |= SEC_CODE; - } - } - - /* Any syms created from now on start with -1 in - got.refcount/offset and plt.refcount/offset. */ - elf_hash_table (info)->init_got_refcount - = elf_hash_table (info)->init_got_offset; - elf_hash_table (info)->init_plt_refcount - = elf_hash_table (info)->init_plt_offset; - - if (info->relocatable - && !_bfd_elf_size_group_sections (info)) - return FALSE; - - /* The backend may have to create some sections regardless of whether - we're dynamic or not. */ - if (bed->elf_backend_always_size_sections - && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) - return FALSE; - - if (! _bfd_elf_maybe_strip_eh_frame_hdr (info)) - return FALSE; - - dynobj = elf_hash_table (info)->dynobj; - - /* If there were no dynamic objects in the link, there is nothing to - do here. */ - if (dynobj == NULL) - return TRUE; - - if (elf_hash_table (info)->dynamic_sections_created) - { - struct elf_info_failed eif; - struct elf_link_hash_entry *h; - asection *dynstr; - struct bfd_elf_version_tree *t; - struct bfd_elf_version_expr *d; - asection *s; - bfd_boolean all_defined; - - *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (*sinterpptr != NULL || !info->executable); - - if (soname != NULL) - { - soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - soname, TRUE); - if (soname_indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx)) - return FALSE; - } - - if (info->symbolic) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) - return FALSE; - info->flags |= DF_SYMBOLIC; - } - - if (rpath != NULL) - { - bfd_size_type indx; - - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath, - TRUE); - if (indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_RPATH, indx)) - return FALSE; - - if (info->new_dtags) - { - _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx); - if (!_bfd_elf_add_dynamic_entry (info, DT_RUNPATH, indx)) - return FALSE; - } - } - - if (filter_shlib != NULL) - { - bfd_size_type indx; - - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - filter_shlib, TRUE); - if (indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx)) - return FALSE; - } - - if (auxiliary_filters != NULL) - { - const char * const *p; - - for (p = auxiliary_filters; *p != NULL; p++) - { - bfd_size_type indx; - - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - *p, TRUE); - if (indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx)) - return FALSE; - } - } - - if (audit != NULL) - { - bfd_size_type indx; - - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit, - TRUE); - if (indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx)) - return FALSE; - } - - if (depaudit != NULL) - { - bfd_size_type indx; - - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit, - TRUE); - if (indx == (bfd_size_type) -1 - || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx)) - return FALSE; - } - - eif.info = info; - eif.failed = FALSE; - - /* If we are supposed to export all symbols into the dynamic symbol - table (this is not the normal case), then do so. */ - if (info->export_dynamic - || (info->executable && info->dynamic)) - { - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_export_symbol, - &eif); - if (eif.failed) - return FALSE; - } - - /* Make all global versions with definition. */ - for (t = info->version_info; t != NULL; t = t->next) - for (d = t->globals.list; d != NULL; d = d->next) - if (!d->symver && d->literal) - { - const char *verstr, *name; - size_t namelen, verlen, newlen; - char *newname, *p, leading_char; - struct elf_link_hash_entry *newh; - - leading_char = bfd_get_symbol_leading_char (output_bfd); - name = d->pattern; - namelen = strlen (name) + (leading_char != '\0'); - verstr = t->name; - verlen = strlen (verstr); - newlen = namelen + verlen + 3; - - newname = (char *) bfd_malloc (newlen); - if (newname == NULL) - return FALSE; - newname[0] = leading_char; - memcpy (newname + (leading_char != '\0'), name, namelen); - - /* Check the hidden versioned definition. */ - p = newname + namelen; - *p++ = ELF_VER_CHR; - memcpy (p, verstr, verlen + 1); - newh = elf_link_hash_lookup (elf_hash_table (info), - newname, FALSE, FALSE, - FALSE); - if (newh == NULL - || (newh->root.type != bfd_link_hash_defined - && newh->root.type != bfd_link_hash_defweak)) - { - /* Check the default versioned definition. */ - *p++ = ELF_VER_CHR; - memcpy (p, verstr, verlen + 1); - newh = elf_link_hash_lookup (elf_hash_table (info), - newname, FALSE, FALSE, - FALSE); - } - free (newname); - - /* Mark this version if there is a definition and it is - not defined in a shared object. */ - if (newh != NULL - && !newh->def_dynamic - && (newh->root.type == bfd_link_hash_defined - || newh->root.type == bfd_link_hash_defweak)) - d->symver = 1; - } - - /* Attach all the symbols to their version information. */ - asvinfo.info = info; - asvinfo.failed = FALSE; - - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_link_assign_sym_version, - &asvinfo); - if (asvinfo.failed) - return FALSE; - - if (!info->allow_undefined_version) - { - /* Check if all global versions have a definition. */ - all_defined = TRUE; - for (t = info->version_info; t != NULL; t = t->next) - for (d = t->globals.list; d != NULL; d = d->next) - if (d->literal && !d->symver && !d->script) - { - (*_bfd_error_handler) - (_("%s: undefined version: %s"), - d->pattern, t->name); - all_defined = FALSE; - } - - if (!all_defined) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - } - - /* Find all symbols which were defined in a dynamic object and make - the backend pick a reasonable value for them. */ - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_adjust_dynamic_symbol, - &eif); - if (eif.failed) - return FALSE; - - /* Add some entries to the .dynamic section. We fill in some of the - values later, in bfd_elf_final_link, but we must add the entries - now so that we know the final size of the .dynamic section. */ - - /* If there are initialization and/or finalization functions to - call then add the corresponding DT_INIT/DT_FINI entries. */ - h = (info->init_function - ? elf_link_hash_lookup (elf_hash_table (info), - info->init_function, FALSE, - FALSE, FALSE) - : NULL); - if (h != NULL - && (h->ref_regular - || h->def_regular)) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0)) - return FALSE; - } - h = (info->fini_function - ? elf_link_hash_lookup (elf_hash_table (info), - info->fini_function, FALSE, - FALSE, FALSE) - : NULL); - if (h != NULL - && (h->ref_regular - || h->def_regular)) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0)) - return FALSE; - } - - s = bfd_get_section_by_name (output_bfd, ".preinit_array"); - if (s != NULL && s->linker_has_input) - { - /* DT_PREINIT_ARRAY is not allowed in shared library. */ - if (! info->executable) - { - bfd *sub; - asection *o; - - for (sub = info->input_bfds; sub != NULL; - sub = sub->link_next) - if (bfd_get_flavour (sub) == bfd_target_elf_flavour) - for (o = sub->sections; o != NULL; o = o->next) - if (elf_section_data (o)->this_hdr.sh_type - == SHT_PREINIT_ARRAY) - { - (*_bfd_error_handler) - (_("%B: .preinit_array section is not allowed in DSO"), - sub); - break; - } - - bfd_set_error (bfd_error_nonrepresentable_section); - return FALSE; - } - - if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0)) - return FALSE; - } - s = bfd_get_section_by_name (output_bfd, ".init_array"); - if (s != NULL && s->linker_has_input) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0)) - return FALSE; - } - s = bfd_get_section_by_name (output_bfd, ".fini_array"); - if (s != NULL && s->linker_has_input) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0)) - return FALSE; - } - - dynstr = bfd_get_section_by_name (dynobj, ".dynstr"); - /* If .dynstr is excluded from the link, we don't want any of - these tags. Strictly, we should be checking each section - individually; This quick check covers for the case where - someone does a /DISCARD/ : { *(*) }. */ - if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr) - { - bfd_size_type strsize; - - strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); - if ((info->emit_hash - && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)) - || (info->emit_gnu_hash - && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0)) - || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize) - || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT, - bed->s->sizeof_sym)) - return FALSE; - } - } - - /* The backend must work out the sizes of all the other dynamic - sections. */ - if (bed->elf_backend_size_dynamic_sections - && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) - return FALSE; - - if (elf_hash_table (info)->dynamic_sections_created) - { - unsigned long section_sym_count; - struct bfd_elf_version_tree *verdefs; - asection *s; - - /* Set up the version definition section. */ - s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); - BFD_ASSERT (s != NULL); - - /* We may have created additional version definitions if we are - just linking a regular application. */ - verdefs = info->version_info; - - /* Skip anonymous version tag. */ - if (verdefs != NULL && verdefs->vernum == 0) - verdefs = verdefs->next; - - if (verdefs == NULL && !info->create_default_symver) - s->flags |= SEC_EXCLUDE; - else - { - unsigned int cdefs; - bfd_size_type size; - struct bfd_elf_version_tree *t; - bfd_byte *p; - Elf_Internal_Verdef def; - Elf_Internal_Verdaux defaux; - struct bfd_link_hash_entry *bh; - struct elf_link_hash_entry *h; - const char *name; - - cdefs = 0; - size = 0; - - /* Make space for the base version. */ - size += sizeof (Elf_External_Verdef); - size += sizeof (Elf_External_Verdaux); - ++cdefs; - - /* Make space for the default version. */ - if (info->create_default_symver) - { - size += sizeof (Elf_External_Verdef); - ++cdefs; - } - - for (t = verdefs; t != NULL; t = t->next) - { - struct bfd_elf_version_deps *n; - - /* Don't emit base version twice. */ - if (t->vernum == 0) - continue; - - size += sizeof (Elf_External_Verdef); - size += sizeof (Elf_External_Verdaux); - ++cdefs; - - for (n = t->deps; n != NULL; n = n->next) - size += sizeof (Elf_External_Verdaux); - } - - s->size = size; - s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); - if (s->contents == NULL && s->size != 0) - return FALSE; - - /* Fill in the version definition section. */ - - p = s->contents; - - def.vd_version = VER_DEF_CURRENT; - def.vd_flags = VER_FLG_BASE; - def.vd_ndx = 1; - def.vd_cnt = 1; - if (info->create_default_symver) - { - def.vd_aux = 2 * sizeof (Elf_External_Verdef); - def.vd_next = sizeof (Elf_External_Verdef); - } - else - { - def.vd_aux = sizeof (Elf_External_Verdef); - def.vd_next = (sizeof (Elf_External_Verdef) - + sizeof (Elf_External_Verdaux)); - } - - if (soname_indx != (bfd_size_type) -1) - { - _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, - soname_indx); - def.vd_hash = bfd_elf_hash (soname); - defaux.vda_name = soname_indx; - name = soname; - } - else - { - bfd_size_type indx; - - name = lbasename (output_bfd->filename); - def.vd_hash = bfd_elf_hash (name); - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - name, FALSE); - if (indx == (bfd_size_type) -1) - return FALSE; - defaux.vda_name = indx; - } - defaux.vda_next = 0; - - _bfd_elf_swap_verdef_out (output_bfd, &def, - (Elf_External_Verdef *) p); - p += sizeof (Elf_External_Verdef); - if (info->create_default_symver) - { - /* Add a symbol representing this version. */ - bh = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr, - 0, NULL, FALSE, - get_elf_backend_data (dynobj)->collect, &bh))) - return FALSE; - h = (struct elf_link_hash_entry *) bh; - h->non_elf = 0; - h->def_regular = 1; - h->type = STT_OBJECT; - h->verinfo.vertree = NULL; - - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - - /* Create a duplicate of the base version with the same - aux block, but different flags. */ - def.vd_flags = 0; - def.vd_ndx = 2; - def.vd_aux = sizeof (Elf_External_Verdef); - if (verdefs) - def.vd_next = (sizeof (Elf_External_Verdef) - + sizeof (Elf_External_Verdaux)); - else - def.vd_next = 0; - _bfd_elf_swap_verdef_out (output_bfd, &def, - (Elf_External_Verdef *) p); - p += sizeof (Elf_External_Verdef); - } - _bfd_elf_swap_verdaux_out (output_bfd, &defaux, - (Elf_External_Verdaux *) p); - p += sizeof (Elf_External_Verdaux); - - for (t = verdefs; t != NULL; t = t->next) - { - unsigned int cdeps; - struct bfd_elf_version_deps *n; - - /* Don't emit the base version twice. */ - if (t->vernum == 0) - continue; - - cdeps = 0; - for (n = t->deps; n != NULL; n = n->next) - ++cdeps; - - /* Add a symbol representing this version. */ - bh = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr, - 0, NULL, FALSE, - get_elf_backend_data (dynobj)->collect, &bh))) - return FALSE; - h = (struct elf_link_hash_entry *) bh; - h->non_elf = 0; - h->def_regular = 1; - h->type = STT_OBJECT; - h->verinfo.vertree = t; - - if (! bfd_elf_link_record_dynamic_symbol (info, h)) - return FALSE; - - def.vd_version = VER_DEF_CURRENT; - def.vd_flags = 0; - if (t->globals.list == NULL - && t->locals.list == NULL - && ! t->used) - def.vd_flags |= VER_FLG_WEAK; - def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1); - def.vd_cnt = cdeps + 1; - def.vd_hash = bfd_elf_hash (t->name); - def.vd_aux = sizeof (Elf_External_Verdef); - def.vd_next = 0; - - /* If a basever node is next, it *must* be the last node in - the chain, otherwise Verdef construction breaks. */ - if (t->next != NULL && t->next->vernum == 0) - BFD_ASSERT (t->next->next == NULL); - - if (t->next != NULL && t->next->vernum != 0) - def.vd_next = (sizeof (Elf_External_Verdef) - + (cdeps + 1) * sizeof (Elf_External_Verdaux)); - - _bfd_elf_swap_verdef_out (output_bfd, &def, - (Elf_External_Verdef *) p); - p += sizeof (Elf_External_Verdef); - - defaux.vda_name = h->dynstr_index; - _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, - h->dynstr_index); - defaux.vda_next = 0; - if (t->deps != NULL) - defaux.vda_next = sizeof (Elf_External_Verdaux); - t->name_indx = defaux.vda_name; - - _bfd_elf_swap_verdaux_out (output_bfd, &defaux, - (Elf_External_Verdaux *) p); - p += sizeof (Elf_External_Verdaux); - - for (n = t->deps; n != NULL; n = n->next) - { - if (n->version_needed == NULL) - { - /* This can happen if there was an error in the - version script. */ - defaux.vda_name = 0; - } - else - { - defaux.vda_name = n->version_needed->name_indx; - _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, - defaux.vda_name); - } - if (n->next == NULL) - defaux.vda_next = 0; - else - defaux.vda_next = sizeof (Elf_External_Verdaux); - - _bfd_elf_swap_verdaux_out (output_bfd, &defaux, - (Elf_External_Verdaux *) p); - p += sizeof (Elf_External_Verdaux); - } - } - - if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs)) - return FALSE; - - elf_tdata (output_bfd)->cverdefs = cdefs; - } - - if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS)) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags)) - return FALSE; - } - else if (info->flags & DF_BIND_NOW) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0)) - return FALSE; - } - - if (info->flags_1) - { - if (info->executable) - info->flags_1 &= ~ (DF_1_INITFIRST - | DF_1_NODELETE - | DF_1_NOOPEN); - if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1)) - return FALSE; - } - - /* Work out the size of the version reference section. */ - - s = bfd_get_section_by_name (dynobj, ".gnu.version_r"); - BFD_ASSERT (s != NULL); - { - struct elf_find_verdep_info sinfo; - - sinfo.info = info; - sinfo.vers = elf_tdata (output_bfd)->cverdefs; - if (sinfo.vers == 0) - sinfo.vers = 1; - sinfo.failed = FALSE; - - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_link_find_version_dependencies, - &sinfo); - if (sinfo.failed) - return FALSE; - - if (elf_tdata (output_bfd)->verref == NULL) - s->flags |= SEC_EXCLUDE; - else - { - Elf_Internal_Verneed *t; - unsigned int size; - unsigned int crefs; - bfd_byte *p; - - /* Build the version dependency section. */ - size = 0; - crefs = 0; - for (t = elf_tdata (output_bfd)->verref; - t != NULL; - t = t->vn_nextref) - { - Elf_Internal_Vernaux *a; - - size += sizeof (Elf_External_Verneed); - ++crefs; - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - size += sizeof (Elf_External_Vernaux); - } - - s->size = size; - s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); - if (s->contents == NULL) - return FALSE; - - p = s->contents; - for (t = elf_tdata (output_bfd)->verref; - t != NULL; - t = t->vn_nextref) - { - unsigned int caux; - Elf_Internal_Vernaux *a; - bfd_size_type indx; - - caux = 0; - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - ++caux; - - t->vn_version = VER_NEED_CURRENT; - t->vn_cnt = caux; - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - elf_dt_name (t->vn_bfd) != NULL - ? elf_dt_name (t->vn_bfd) - : lbasename (t->vn_bfd->filename), - FALSE); - if (indx == (bfd_size_type) -1) - return FALSE; - t->vn_file = indx; - t->vn_aux = sizeof (Elf_External_Verneed); - if (t->vn_nextref == NULL) - t->vn_next = 0; - else - t->vn_next = (sizeof (Elf_External_Verneed) - + caux * sizeof (Elf_External_Vernaux)); - - _bfd_elf_swap_verneed_out (output_bfd, t, - (Elf_External_Verneed *) p); - p += sizeof (Elf_External_Verneed); - - for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) - { - a->vna_hash = bfd_elf_hash (a->vna_nodename); - indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, - a->vna_nodename, FALSE); - if (indx == (bfd_size_type) -1) - return FALSE; - a->vna_name = indx; - if (a->vna_nextptr == NULL) - a->vna_next = 0; - else - a->vna_next = sizeof (Elf_External_Vernaux); - - _bfd_elf_swap_vernaux_out (output_bfd, a, - (Elf_External_Vernaux *) p); - p += sizeof (Elf_External_Vernaux); - } - } - - if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs)) - return FALSE; - - elf_tdata (output_bfd)->cverrefs = crefs; - } - } - - if ((elf_tdata (output_bfd)->cverrefs == 0 - && elf_tdata (output_bfd)->cverdefs == 0) - || _bfd_elf_link_renumber_dynsyms (output_bfd, info, - §ion_sym_count) == 0) - { - s = bfd_get_section_by_name (dynobj, ".gnu.version"); - s->flags |= SEC_EXCLUDE; - } - } - return TRUE; -} - -/* Find the first non-excluded output section. We'll use its - section symbol for some emitted relocs. */ -void -_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info) -{ - asection *s; - - for (s = output_bfd->sections; s != NULL; s = s->next) - if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC - && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) - { - elf_hash_table (info)->text_index_section = s; - break; - } -} - -/* Find two non-excluded output sections, one for code, one for data. - We'll use their section symbols for some emitted relocs. */ -void -_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info) -{ - asection *s; - - /* Data first, since setting text_index_section changes - _bfd_elf_link_omit_section_dynsym. */ - for (s = output_bfd->sections; s != NULL; s = s->next) - if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) - && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) - { - elf_hash_table (info)->data_index_section = s; - break; - } - - for (s = output_bfd->sections; s != NULL; s = s->next) - if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) - == (SEC_ALLOC | SEC_READONLY)) - && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) - { - elf_hash_table (info)->text_index_section = s; - break; - } - - if (elf_hash_table (info)->text_index_section == NULL) - elf_hash_table (info)->text_index_section - = elf_hash_table (info)->data_index_section; -} - -bfd_boolean -bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) -{ - const struct elf_backend_data *bed; - - if (!is_elf_hash_table (info->hash)) - return TRUE; - - bed = get_elf_backend_data (output_bfd); - (*bed->elf_backend_init_index_section) (output_bfd, info); - - if (elf_hash_table (info)->dynamic_sections_created) - { - bfd *dynobj; - asection *s; - bfd_size_type dynsymcount; - unsigned long section_sym_count; - unsigned int dtagcount; - - dynobj = elf_hash_table (info)->dynobj; - - /* Assign dynsym indicies. In a shared library we generate a - section symbol for each output section, which come first. - Next come all of the back-end allocated local dynamic syms, - followed by the rest of the global symbols. */ - - dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info, - §ion_sym_count); - - /* Work out the size of the symbol version section. */ - s = bfd_get_section_by_name (dynobj, ".gnu.version"); - BFD_ASSERT (s != NULL); - if (dynsymcount != 0 - && (s->flags & SEC_EXCLUDE) == 0) - { - s->size = dynsymcount * sizeof (Elf_External_Versym); - s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); - if (s->contents == NULL) - return FALSE; - - if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0)) - return FALSE; - } - - /* Set the size of the .dynsym and .hash sections. We counted - the number of dynamic symbols in elf_link_add_object_symbols. - We will build the contents of .dynsym and .hash when we build - the final symbol table, because until then we do not know the - correct value to give the symbols. We built the .dynstr - section as we went along in elf_link_add_object_symbols. */ - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->size = dynsymcount * bed->s->sizeof_sym; - - if (dynsymcount != 0) - { - s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); - if (s->contents == NULL) - return FALSE; - - /* The first entry in .dynsym is a dummy symbol. - Clear all the section syms, in case we don't output them all. */ - ++section_sym_count; - memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); - } - - elf_hash_table (info)->bucketcount = 0; - - /* Compute the size of the hashing table. As a side effect this - computes the hash values for all the names we export. */ - if (info->emit_hash) - { - unsigned long int *hashcodes; - struct hash_codes_info hashinf; - bfd_size_type amt; - unsigned long int nsyms; - size_t bucketcount; - size_t hash_entry_size; - - /* Compute the hash values for all exported symbols. At the same - time store the values in an array so that we could use them for - optimizations. */ - amt = dynsymcount * sizeof (unsigned long int); - hashcodes = (unsigned long int *) bfd_malloc (amt); - if (hashcodes == NULL) - return FALSE; - hashinf.hashcodes = hashcodes; - hashinf.error = FALSE; - - /* Put all hash values in HASHCODES. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_collect_hash_codes, &hashinf); - if (hashinf.error) - { - free (hashcodes); - return FALSE; - } - - nsyms = hashinf.hashcodes - hashcodes; - bucketcount - = compute_bucket_count (info, hashcodes, nsyms, 0); - free (hashcodes); - - if (bucketcount == 0) - return FALSE; - - elf_hash_table (info)->bucketcount = bucketcount; - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; - s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); - s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); - if (s->contents == NULL) - return FALSE; - - bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); - bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, - s->contents + hash_entry_size); - } - - if (info->emit_gnu_hash) - { - size_t i, cnt; - unsigned char *contents; - struct collect_gnu_hash_codes cinfo; - bfd_size_type amt; - size_t bucketcount; - - memset (&cinfo, 0, sizeof (cinfo)); - - /* Compute the hash values for all exported symbols. At the same - time store the values in an array so that we could use them for - optimizations. */ - amt = dynsymcount * 2 * sizeof (unsigned long int); - cinfo.hashcodes = (long unsigned int *) bfd_malloc (amt); - if (cinfo.hashcodes == NULL) - return FALSE; - - cinfo.hashval = cinfo.hashcodes + dynsymcount; - cinfo.min_dynindx = -1; - cinfo.output_bfd = output_bfd; - cinfo.bed = bed; - - /* Put all hash values in HASHCODES. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_collect_gnu_hash_codes, &cinfo); - if (cinfo.error) - { - free (cinfo.hashcodes); - return FALSE; - } - - bucketcount - = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); - - if (bucketcount == 0) - { - free (cinfo.hashcodes); - return FALSE; - } - - s = bfd_get_section_by_name (dynobj, ".gnu.hash"); - BFD_ASSERT (s != NULL); - - if (cinfo.nsyms == 0) - { - /* Empty .gnu.hash section is special. */ - BFD_ASSERT (cinfo.min_dynindx == -1); - free (cinfo.hashcodes); - s->size = 5 * 4 + bed->s->arch_size / 8; - contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); - if (contents == NULL) - return FALSE; - s->contents = contents; - /* 1 empty bucket. */ - bfd_put_32 (output_bfd, 1, contents); - /* SYMIDX above the special symbol 0. */ - bfd_put_32 (output_bfd, 1, contents + 4); - /* Just one word for bitmask. */ - bfd_put_32 (output_bfd, 1, contents + 8); - /* Only hash fn bloom filter. */ - bfd_put_32 (output_bfd, 0, contents + 12); - /* No hashes are valid - empty bitmask. */ - bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16); - /* No hashes in the only bucket. */ - bfd_put_32 (output_bfd, 0, - contents + 16 + bed->s->arch_size / 8); - } - else - { - unsigned long int maskwords, maskbitslog2, x; - BFD_ASSERT (cinfo.min_dynindx != -1); - - x = cinfo.nsyms; - maskbitslog2 = 1; - while ((x >>= 1) != 0) - ++maskbitslog2; - if (maskbitslog2 < 3) - maskbitslog2 = 5; - else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms) - maskbitslog2 = maskbitslog2 + 3; - else - maskbitslog2 = maskbitslog2 + 2; - if (bed->s->arch_size == 64) - { - if (maskbitslog2 == 5) - maskbitslog2 = 6; - cinfo.shift1 = 6; - } - else - cinfo.shift1 = 5; - cinfo.mask = (1 << cinfo.shift1) - 1; - cinfo.shift2 = maskbitslog2; - cinfo.maskbits = 1 << maskbitslog2; - maskwords = 1 << (maskbitslog2 - cinfo.shift1); - amt = bucketcount * sizeof (unsigned long int) * 2; - amt += maskwords * sizeof (bfd_vma); - cinfo.bitmask = (bfd_vma *) bfd_malloc (amt); - if (cinfo.bitmask == NULL) - { - free (cinfo.hashcodes); - return FALSE; - } - - cinfo.counts = (long unsigned int *) (cinfo.bitmask + maskwords); - cinfo.indx = cinfo.counts + bucketcount; - cinfo.symindx = dynsymcount - cinfo.nsyms; - memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); - - /* Determine how often each hash bucket is used. */ - memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0])); - for (i = 0; i < cinfo.nsyms; ++i) - ++cinfo.counts[cinfo.hashcodes[i] % bucketcount]; - - for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i) - if (cinfo.counts[i] != 0) - { - cinfo.indx[i] = cnt; - cnt += cinfo.counts[i]; - } - BFD_ASSERT (cnt == dynsymcount); - cinfo.bucketcount = bucketcount; - cinfo.local_indx = cinfo.min_dynindx; - - s->size = (4 + bucketcount + cinfo.nsyms) * 4; - s->size += cinfo.maskbits / 8; - contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); - if (contents == NULL) - { - free (cinfo.bitmask); - free (cinfo.hashcodes); - return FALSE; - } - - s->contents = contents; - bfd_put_32 (output_bfd, bucketcount, contents); - bfd_put_32 (output_bfd, cinfo.symindx, contents + 4); - bfd_put_32 (output_bfd, maskwords, contents + 8); - bfd_put_32 (output_bfd, cinfo.shift2, contents + 12); - contents += 16 + cinfo.maskbits / 8; - - for (i = 0; i < bucketcount; ++i) - { - if (cinfo.counts[i] == 0) - bfd_put_32 (output_bfd, 0, contents); - else - bfd_put_32 (output_bfd, cinfo.indx[i], contents); - contents += 4; - } - - cinfo.contents = contents; - - /* Renumber dynamic symbols, populate .gnu.hash section. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_renumber_gnu_hash_syms, &cinfo); - - contents = s->contents + 16; - for (i = 0; i < maskwords; ++i) - { - bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i], - contents); - contents += bed->s->arch_size / 8; - } - - free (cinfo.bitmask); - free (cinfo.hashcodes); - } - } - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - - elf_finalize_dynstr (output_bfd, info); - - s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); - - for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount) - if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0)) - return FALSE; - } - - return TRUE; -} - -/* Indicate that we are only retrieving symbol values from this - section. */ - -void -_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info) -{ - if (is_elf_hash_table (info->hash)) - sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS; - _bfd_generic_link_just_syms (sec, info); -} - -/* Make sure sec_info_type is cleared if sec_info is cleared too. */ - -static void -merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec) -{ - BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE); - sec->sec_info_type = ELF_INFO_TYPE_NONE; -} - -/* Finish SHF_MERGE section merging. */ - -bfd_boolean -_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info) -{ - bfd *ibfd; - asection *sec; - - if (!is_elf_hash_table (info->hash)) - return FALSE; - - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) - if ((ibfd->flags & DYNAMIC) == 0) - for (sec = ibfd->sections; sec != NULL; sec = sec->next) - if ((sec->flags & SEC_MERGE) != 0 - && !bfd_is_abs_section (sec->output_section)) - { - struct bfd_elf_section_data *secdata; - - secdata = elf_section_data (sec); - if (! _bfd_add_merge_section (abfd, - &elf_hash_table (info)->merge_info, - sec, &secdata->sec_info)) - return FALSE; - else if (secdata->sec_info) - sec->sec_info_type = ELF_INFO_TYPE_MERGE; - } - - if (elf_hash_table (info)->merge_info != NULL) - _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info, - merge_sections_remove_hook); - return TRUE; -} - -/* Create an entry in an ELF linker hash table. */ - -struct bfd_hash_entry * -_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = _bfd_link_hash_newfunc (entry, table, string); - if (entry != NULL) - { - struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry; - struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table; - - /* Set local fields. */ - ret->indx = -1; - ret->dynindx = -1; - ret->got = htab->init_got_refcount; - ret->plt = htab->init_plt_refcount; - memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry) - - offsetof (struct elf_link_hash_entry, size))); - /* Assume that we have been called by a non-ELF symbol reader. - This flag is then reset by the code which reads an ELF input - file. This ensures that a symbol created by a non-ELF symbol - reader will have the flag set correctly. */ - ret->non_elf = 1; - } - - return entry; -} - -/* Copy data from an indirect symbol to its direct symbol, hiding the - old indirect symbol. Also used for copying flags to a weakdef. */ - -void -_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info, - struct elf_link_hash_entry *dir, - struct elf_link_hash_entry *ind) -{ - struct elf_link_hash_table *htab; - - /* Copy down any references that we may have already seen to the - symbol which just became indirect. */ - - dir->ref_dynamic |= ind->ref_dynamic; - dir->ref_regular |= ind->ref_regular; - dir->ref_regular_nonweak |= ind->ref_regular_nonweak; - dir->non_got_ref |= ind->non_got_ref; - dir->needs_plt |= ind->needs_plt; - dir->pointer_equality_needed |= ind->pointer_equality_needed; - - if (ind->root.type != bfd_link_hash_indirect) - return; - - /* Copy over the global and procedure linkage table refcount entries. - These may have been already set up by a check_relocs routine. */ - htab = elf_hash_table (info); - if (ind->got.refcount > htab->init_got_refcount.refcount) - { - if (dir->got.refcount < 0) - dir->got.refcount = 0; - dir->got.refcount += ind->got.refcount; - ind->got.refcount = htab->init_got_refcount.refcount; - } - - if (ind->plt.refcount > htab->init_plt_refcount.refcount) - { - if (dir->plt.refcount < 0) - dir->plt.refcount = 0; - dir->plt.refcount += ind->plt.refcount; - ind->plt.refcount = htab->init_plt_refcount.refcount; - } - - if (ind->dynindx != -1) - { - if (dir->dynindx != -1) - _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index); - dir->dynindx = ind->dynindx; - dir->dynstr_index = ind->dynstr_index; - ind->dynindx = -1; - ind->dynstr_index = 0; - } -} - -void -_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h, - bfd_boolean force_local) -{ - /* STT_GNU_IFUNC symbol must go through PLT. */ - if (h->type != STT_GNU_IFUNC) - { - h->plt = elf_hash_table (info)->init_plt_offset; - h->needs_plt = 0; - } - if (force_local) - { - h->forced_local = 1; - if (h->dynindx != -1) - { - h->dynindx = -1; - _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr, - h->dynstr_index); - } - } -} - -/* Initialize an ELF linker hash table. */ - -bfd_boolean -_bfd_elf_link_hash_table_init - (struct elf_link_hash_table *table, - bfd *abfd, - struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int entsize, - enum elf_target_id target_id) -{ - bfd_boolean ret; - int can_refcount = get_elf_backend_data (abfd)->can_refcount; - - memset (table, 0, sizeof * table); - table->init_got_refcount.refcount = can_refcount - 1; - table->init_plt_refcount.refcount = can_refcount - 1; - table->init_got_offset.offset = -(bfd_vma) 1; - table->init_plt_offset.offset = -(bfd_vma) 1; - /* The first dynamic symbol is a dummy. */ - table->dynsymcount = 1; - - ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize); - - table->root.type = bfd_link_elf_hash_table; - table->hash_table_id = target_id; - - return ret; -} - -/* Create an ELF linker hash table. */ - -struct bfd_link_hash_table * -_bfd_elf_link_hash_table_create (bfd *abfd) -{ - struct elf_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_link_hash_table); - - ret = (struct elf_link_hash_table *) bfd_malloc (amt); - if (ret == NULL) - return NULL; - - if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc, - sizeof (struct elf_link_hash_entry), - GENERIC_ELF_DATA)) - { - free (ret); - return NULL; - } - - return &ret->root; -} - -/* This is a hook for the ELF emulation code in the generic linker to - tell the backend linker what file name to use for the DT_NEEDED - entry for a dynamic object. */ - -void -bfd_elf_set_dt_needed_name (bfd *abfd, const char *name) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - elf_dt_name (abfd) = name; -} - -int -bfd_elf_get_dyn_lib_class (bfd *abfd) -{ - int lib_class; - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - lib_class = elf_dyn_lib_class (abfd); - else - lib_class = 0; - return lib_class; -} - -void -bfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - elf_dyn_lib_class (abfd) = lib_class; -} - -/* Get the list of DT_NEEDED entries for a link. This is a hook for - the linker ELF emulation code. */ - -struct bfd_link_needed_list * -bfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info) -{ - if (! is_elf_hash_table (info->hash)) - return NULL; - return elf_hash_table (info)->needed; -} - -/* Get the list of DT_RPATH/DT_RUNPATH entries for a link. This is a - hook for the linker ELF emulation code. */ - -struct bfd_link_needed_list * -bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info) -{ - if (! is_elf_hash_table (info->hash)) - return NULL; - return elf_hash_table (info)->runpath; -} - -/* Get the name actually used for a dynamic object for a link. This - is the SONAME entry if there is one. Otherwise, it is the string - passed to bfd_elf_set_dt_needed_name, or it is the filename. */ - -const char * -bfd_elf_get_dt_soname (bfd *abfd) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && bfd_get_format (abfd) == bfd_object) - return elf_dt_name (abfd); - return NULL; -} - -/* Get the list of DT_NEEDED entries from a BFD. This is a hook for - the ELF linker emulation code. */ - -bfd_boolean -bfd_elf_get_bfd_needed_list (bfd *abfd, - struct bfd_link_needed_list **pneeded) -{ - asection *s; - bfd_byte *dynbuf = NULL; - unsigned int elfsec; - unsigned long shlink; - bfd_byte *extdyn, *extdynend; - size_t extdynsize; - void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *); - - *pneeded = NULL; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour - || bfd_get_format (abfd) != bfd_object) - return TRUE; - - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s == NULL || s->size == 0) - return TRUE; - - if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) - goto error_return; - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == SHN_BAD) - goto error_return; - - shlink = elf_elfsections (abfd)[elfsec]->sh_link; - - extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn; - swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in; - - extdyn = dynbuf; - extdynend = extdyn + s->size; - for (; extdyn < extdynend; extdyn += extdynsize) - { - Elf_Internal_Dyn dyn; - - (*swap_dyn_in) (abfd, extdyn, &dyn); - - if (dyn.d_tag == DT_NULL) - break; - - if (dyn.d_tag == DT_NEEDED) - { - const char *string; - struct bfd_link_needed_list *l; - unsigned int tagv = dyn.d_un.d_val; - bfd_size_type amt; - - string = bfd_elf_string_from_elf_section (abfd, shlink, tagv); - if (string == NULL) - goto error_return; - - amt = sizeof *l; - l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); - if (l == NULL) - goto error_return; - - l->by = abfd; - l->name = string; - l->next = *pneeded; - *pneeded = l; - } - } - - free (dynbuf); - - return TRUE; - - error_return: - if (dynbuf != NULL) - free (dynbuf); - return FALSE; -} - -struct elf_symbuf_symbol -{ - unsigned long st_name; /* Symbol name, index in string tbl */ - unsigned char st_info; /* Type and binding attributes */ - unsigned char st_other; /* Visibilty, and target specific */ -}; - -struct elf_symbuf_head -{ - struct elf_symbuf_symbol *ssym; - bfd_size_type count; - unsigned int st_shndx; -}; - -struct elf_symbol -{ - union - { - Elf_Internal_Sym *isym; - struct elf_symbuf_symbol *ssym; - } u; - const char *name; -}; - -/* Sort references to symbols by ascending section number. */ - -static int -elf_sort_elf_symbol (const void *arg1, const void *arg2) -{ - const Elf_Internal_Sym *s1 = *(const Elf_Internal_Sym **) arg1; - const Elf_Internal_Sym *s2 = *(const Elf_Internal_Sym **) arg2; - - return s1->st_shndx - s2->st_shndx; -} - -static int -elf_sym_name_compare (const void *arg1, const void *arg2) -{ - const struct elf_symbol *s1 = (const struct elf_symbol *) arg1; - const struct elf_symbol *s2 = (const struct elf_symbol *) arg2; - return strcmp (s1->name, s2->name); -} - -static struct elf_symbuf_head * -elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf) -{ - Elf_Internal_Sym **ind, **indbufend, **indbuf; - struct elf_symbuf_symbol *ssym; - struct elf_symbuf_head *ssymbuf, *ssymhead; - bfd_size_type i, shndx_count, total_size; - - indbuf = (Elf_Internal_Sym **) bfd_malloc2 (symcount, sizeof (*indbuf)); - if (indbuf == NULL) - return NULL; - - for (ind = indbuf, i = 0; i < symcount; i++) - if (isymbuf[i].st_shndx != SHN_UNDEF) - *ind++ = &isymbuf[i]; - indbufend = ind; - - qsort (indbuf, indbufend - indbuf, sizeof (Elf_Internal_Sym *), - elf_sort_elf_symbol); - - shndx_count = 0; - if (indbufend > indbuf) - for (ind = indbuf, shndx_count++; ind < indbufend - 1; ind++) - if (ind[0]->st_shndx != ind[1]->st_shndx) - shndx_count++; - - total_size = ((shndx_count + 1) * sizeof (*ssymbuf) - + (indbufend - indbuf) * sizeof (*ssym)); - ssymbuf = (struct elf_symbuf_head *) bfd_malloc (total_size); - if (ssymbuf == NULL) - { - free (indbuf); - return NULL; - } - - ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1); - ssymbuf->ssym = NULL; - ssymbuf->count = shndx_count; - ssymbuf->st_shndx = 0; - for (ssymhead = ssymbuf, ind = indbuf; ind < indbufend; ssym++, ind++) - { - if (ind == indbuf || ssymhead->st_shndx != (*ind)->st_shndx) - { - ssymhead++; - ssymhead->ssym = ssym; - ssymhead->count = 0; - ssymhead->st_shndx = (*ind)->st_shndx; - } - ssym->st_name = (*ind)->st_name; - ssym->st_info = (*ind)->st_info; - ssym->st_other = (*ind)->st_other; - ssymhead->count++; - } - BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count - && (((bfd_hostptr_t) ssym - (bfd_hostptr_t) ssymbuf) - == total_size)); - - free (indbuf); - return ssymbuf; -} - -/* Check if 2 sections define the same set of local and global - symbols. */ - -static bfd_boolean -bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, - struct bfd_link_info *info) -{ - bfd *bfd1, *bfd2; - const struct elf_backend_data *bed1, *bed2; - Elf_Internal_Shdr *hdr1, *hdr2; - bfd_size_type symcount1, symcount2; - Elf_Internal_Sym *isymbuf1, *isymbuf2; - struct elf_symbuf_head *ssymbuf1, *ssymbuf2; - Elf_Internal_Sym *isym, *isymend; - struct elf_symbol *symtable1 = NULL, *symtable2 = NULL; - bfd_size_type count1, count2, i; - unsigned int shndx1, shndx2; - bfd_boolean result; - - bfd1 = sec1->owner; - bfd2 = sec2->owner; - - /* Both sections have to be in ELF. */ - if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour - || bfd_get_flavour (bfd2) != bfd_target_elf_flavour) - return FALSE; - - if (elf_section_type (sec1) != elf_section_type (sec2)) - return FALSE; - - shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1); - shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2); - if (shndx1 == SHN_BAD || shndx2 == SHN_BAD) - return FALSE; - - bed1 = get_elf_backend_data (bfd1); - bed2 = get_elf_backend_data (bfd2); - hdr1 = &elf_tdata (bfd1)->symtab_hdr; - symcount1 = hdr1->sh_size / bed1->s->sizeof_sym; - hdr2 = &elf_tdata (bfd2)->symtab_hdr; - symcount2 = hdr2->sh_size / bed2->s->sizeof_sym; - - if (symcount1 == 0 || symcount2 == 0) - return FALSE; - - result = FALSE; - isymbuf1 = NULL; - isymbuf2 = NULL; - ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf; - ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf; - - if (ssymbuf1 == NULL) - { - isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0, - NULL, NULL, NULL); - if (isymbuf1 == NULL) - goto done; - - if (!info->reduce_memory_overheads) - elf_tdata (bfd1)->symbuf = ssymbuf1 - = elf_create_symbuf (symcount1, isymbuf1); - } - - if (ssymbuf1 == NULL || ssymbuf2 == NULL) - { - isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0, - NULL, NULL, NULL); - if (isymbuf2 == NULL) - goto done; - - if (ssymbuf1 != NULL && !info->reduce_memory_overheads) - elf_tdata (bfd2)->symbuf = ssymbuf2 - = elf_create_symbuf (symcount2, isymbuf2); - } - - if (ssymbuf1 != NULL && ssymbuf2 != NULL) - { - /* Optimized faster version. */ - bfd_size_type lo, hi, mid; - struct elf_symbol *symp; - struct elf_symbuf_symbol *ssym, *ssymend; - - lo = 0; - hi = ssymbuf1->count; - ssymbuf1++; - count1 = 0; - while (lo < hi) - { - mid = (lo + hi) / 2; - if (shndx1 < ssymbuf1[mid].st_shndx) - hi = mid; - else if (shndx1 > ssymbuf1[mid].st_shndx) - lo = mid + 1; - else - { - count1 = ssymbuf1[mid].count; - ssymbuf1 += mid; - break; - } - } - - lo = 0; - hi = ssymbuf2->count; - ssymbuf2++; - count2 = 0; - while (lo < hi) - { - mid = (lo + hi) / 2; - if (shndx2 < ssymbuf2[mid].st_shndx) - hi = mid; - else if (shndx2 > ssymbuf2[mid].st_shndx) - lo = mid + 1; - else - { - count2 = ssymbuf2[mid].count; - ssymbuf2 += mid; - break; - } - } - - if (count1 == 0 || count2 == 0 || count1 != count2) - goto done; - - symtable1 = (struct elf_symbol *) - bfd_malloc (count1 * sizeof (struct elf_symbol)); - symtable2 = (struct elf_symbol *) - bfd_malloc (count2 * sizeof (struct elf_symbol)); - if (symtable1 == NULL || symtable2 == NULL) - goto done; - - symp = symtable1; - for (ssym = ssymbuf1->ssym, ssymend = ssym + count1; - ssym < ssymend; ssym++, symp++) - { - symp->u.ssym = ssym; - symp->name = bfd_elf_string_from_elf_section (bfd1, - hdr1->sh_link, - ssym->st_name); - } - - symp = symtable2; - for (ssym = ssymbuf2->ssym, ssymend = ssym + count2; - ssym < ssymend; ssym++, symp++) - { - symp->u.ssym = ssym; - symp->name = bfd_elf_string_from_elf_section (bfd2, - hdr2->sh_link, - ssym->st_name); - } - - /* Sort symbol by name. */ - qsort (symtable1, count1, sizeof (struct elf_symbol), - elf_sym_name_compare); - qsort (symtable2, count1, sizeof (struct elf_symbol), - elf_sym_name_compare); - - for (i = 0; i < count1; i++) - /* Two symbols must have the same binding, type and name. */ - if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info - || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other - || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) - goto done; - - result = TRUE; - goto done; - } - - symtable1 = (struct elf_symbol *) - bfd_malloc (symcount1 * sizeof (struct elf_symbol)); - symtable2 = (struct elf_symbol *) - bfd_malloc (symcount2 * sizeof (struct elf_symbol)); - if (symtable1 == NULL || symtable2 == NULL) - goto done; - - /* Count definitions in the section. */ - count1 = 0; - for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++) - if (isym->st_shndx == shndx1) - symtable1[count1++].u.isym = isym; - - count2 = 0; - for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++) - if (isym->st_shndx == shndx2) - symtable2[count2++].u.isym = isym; - - if (count1 == 0 || count2 == 0 || count1 != count2) - goto done; - - for (i = 0; i < count1; i++) - symtable1[i].name - = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link, - symtable1[i].u.isym->st_name); - - for (i = 0; i < count2; i++) - symtable2[i].name - = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link, - symtable2[i].u.isym->st_name); - - /* Sort symbol by name. */ - qsort (symtable1, count1, sizeof (struct elf_symbol), - elf_sym_name_compare); - qsort (symtable2, count1, sizeof (struct elf_symbol), - elf_sym_name_compare); - - for (i = 0; i < count1; i++) - /* Two symbols must have the same binding, type and name. */ - if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info - || symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other - || strcmp (symtable1 [i].name, symtable2 [i].name) != 0) - goto done; - - result = TRUE; - -done: - if (symtable1) - free (symtable1); - if (symtable2) - free (symtable2); - if (isymbuf1) - free (isymbuf1); - if (isymbuf2) - free (isymbuf2); - - return result; -} - -/* Return TRUE if 2 section types are compatible. */ - -bfd_boolean -_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec, - bfd *bbfd, const asection *bsec) -{ - if (asec == NULL - || bsec == NULL - || abfd->xvec->flavour != bfd_target_elf_flavour - || bbfd->xvec->flavour != bfd_target_elf_flavour) - return TRUE; - - return elf_section_type (asec) == elf_section_type (bsec); -} - -/* Final phase of ELF linker. */ - -/* A structure we use to avoid passing large numbers of arguments. */ - -struct elf_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ - struct bfd_strtab_hash *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ - asection *hash_sec; - /* symbol version section (.gnu.version). */ - asection *symver_sec; - /* Buffer large enough to hold contents of any section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any section. */ - void *external_relocs; - /* Buffer large enough to hold internal relocs of any section. */ - Elf_Internal_Rela *internal_relocs; - /* Buffer large enough to hold external local symbols of any input - BFD. */ - bfd_byte *external_syms; - /* And a buffer for symbol section indices. */ - Elf_External_Sym_Shndx *locsym_shndx; - /* Buffer large enough to hold internal local symbols of any input - BFD. */ - Elf_Internal_Sym *internal_syms; - /* Array large enough to hold a symbol index for each local symbol - of any input BFD. */ - long *indices; - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; - /* Buffer to hold swapped out symbols. */ - bfd_byte *symbuf; - /* And one for symbol section indices. */ - Elf_External_Sym_Shndx *symshndxbuf; - /* Number of swapped out symbols in buffer. */ - size_t symbuf_count; - /* Number of symbols which fit in symbuf. */ - size_t symbuf_size; - /* And same for symshndxbuf. */ - size_t shndxbuf_size; -}; - -/* This struct is used to pass information to elf_link_output_extsym. */ - -struct elf_outext_info -{ - bfd_boolean failed; - bfd_boolean localsyms; - struct elf_final_link_info *finfo; -}; - - -/* Support for evaluating a complex relocation. - - Complex relocations are generalized, self-describing relocations. The - implementation of them consists of two parts: complex symbols, and the - relocations themselves. - - The relocations are use a reserved elf-wide relocation type code (R_RELC - external / BFD_RELOC_RELC internal) and an encoding of relocation field - information (start bit, end bit, word width, etc) into the addend. This - information is extracted from CGEN-generated operand tables within gas. - - Complex symbols are mangled symbols (BSF_RELC external / STT_RELC - internal) representing prefix-notation expressions, including but not - limited to those sorts of expressions normally encoded as addends in the - addend field. The symbol mangling format is: - - := - | ':' - | ':' ':' - ; - - := 's' ':' - | 'S' ':' - | '#' - ; - - := as in C - := as in C, plus "0-" for unambiguous negation. */ - -static void -set_symbol_value (bfd *bfd_with_globals, - Elf_Internal_Sym *isymbuf, - size_t locsymcount, - size_t symidx, - bfd_vma val) -{ - struct elf_link_hash_entry **sym_hashes; - struct elf_link_hash_entry *h; - size_t extsymoff = locsymcount; - - if (symidx < locsymcount) - { - Elf_Internal_Sym *sym; - - sym = isymbuf + symidx; - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - { - /* It is a local symbol: move it to the - "absolute" section and give it a value. */ - sym->st_shndx = SHN_ABS; - sym->st_value = val; - return; - } - BFD_ASSERT (elf_bad_symtab (bfd_with_globals)); - extsymoff = 0; - } - - /* It is a global symbol: set its link type - to "defined" and give it a value. */ - - sym_hashes = elf_sym_hashes (bfd_with_globals); - h = sym_hashes [symidx - extsymoff]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - h->root.type = bfd_link_hash_defined; - h->root.u.def.value = val; - h->root.u.def.section = bfd_abs_section_ptr; -} - -static bfd_boolean -resolve_symbol (const char *name, - bfd *input_bfd, - struct elf_final_link_info *finfo, - bfd_vma *result, - Elf_Internal_Sym *isymbuf, - size_t locsymcount) -{ - Elf_Internal_Sym *sym; - struct bfd_link_hash_entry *global_entry; - const char *candidate = NULL; - Elf_Internal_Shdr *symtab_hdr; - size_t i; - - symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; - - for (i = 0; i < locsymcount; ++ i) - { - sym = isymbuf + i; - - if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) - continue; - - candidate = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); -#ifdef DEBUG - printf ("Comparing string: '%s' vs. '%s' = 0x%lx\n", - name, candidate, (unsigned long) sym->st_value); -#endif - if (candidate && strcmp (candidate, name) == 0) - { - asection *sec = finfo->sections [i]; - - *result = _bfd_elf_rel_local_sym (input_bfd, sym, &sec, 0); - *result += sec->output_offset + sec->output_section->vma; -#ifdef DEBUG - printf ("Found symbol with value %8.8lx\n", - (unsigned long) *result); -#endif - return TRUE; - } - } - - /* Hmm, haven't found it yet. perhaps it is a global. */ - global_entry = bfd_link_hash_lookup (finfo->info->hash, name, - FALSE, FALSE, TRUE); - if (!global_entry) - return FALSE; - - if (global_entry->type == bfd_link_hash_defined - || global_entry->type == bfd_link_hash_defweak) - { - *result = (global_entry->u.def.value - + global_entry->u.def.section->output_section->vma - + global_entry->u.def.section->output_offset); -#ifdef DEBUG - printf ("Found GLOBAL symbol '%s' with value %8.8lx\n", - global_entry->root.string, (unsigned long) *result); -#endif - return TRUE; - } - - return FALSE; -} - -static bfd_boolean -resolve_section (const char *name, - asection *sections, - bfd_vma *result) -{ - asection *curr; - unsigned int len; - - for (curr = sections; curr; curr = curr->next) - if (strcmp (curr->name, name) == 0) - { - *result = curr->vma; - return TRUE; - } - - /* Hmm. still haven't found it. try pseudo-section names. */ - for (curr = sections; curr; curr = curr->next) - { - len = strlen (curr->name); - if (len > strlen (name)) - continue; - - if (strncmp (curr->name, name, len) == 0) - { - if (strncmp (".end", name + len, 4) == 0) - { - *result = curr->vma + curr->size; - return TRUE; - } - - /* Insert more pseudo-section names here, if you like. */ - } - } - - return FALSE; -} - -static void -undefined_reference (const char *reftype, const char *name) -{ - _bfd_error_handler (_("undefined %s reference in complex symbol: %s"), - reftype, name); -} - -static bfd_boolean -eval_symbol (bfd_vma *result, - const char **symp, - bfd *input_bfd, - struct elf_final_link_info *finfo, - bfd_vma dot, - Elf_Internal_Sym *isymbuf, - size_t locsymcount, - int signed_p) -{ - size_t len; - size_t symlen; - bfd_vma a; - bfd_vma b; - char symbuf[4096]; - const char *sym = *symp; - const char *symend; - bfd_boolean symbol_is_section = FALSE; - - len = strlen (sym); - symend = sym + len; - - if (len < 1 || len > sizeof (symbuf)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - switch (* sym) - { - case '.': - *result = dot; - *symp = sym + 1; - return TRUE; - - case '#': - ++sym; - *result = strtoul (sym, (char **) symp, 16); - return TRUE; - - case 'S': - symbol_is_section = TRUE; - case 's': - ++sym; - symlen = strtol (sym, (char **) symp, 10); - sym = *symp + 1; /* Skip the trailing ':'. */ - - if (symend < sym || symlen + 1 > sizeof (symbuf)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - memcpy (symbuf, sym, symlen); - symbuf[symlen] = '\0'; - *symp = sym + symlen; - - /* Is it always possible, with complex symbols, that gas "mis-guessed" - the symbol as a section, or vice-versa. so we're pretty liberal in our - interpretation here; section means "try section first", not "must be a - section", and likewise with symbol. */ - - if (symbol_is_section) - { - if (!resolve_section (symbuf, finfo->output_bfd->sections, result) - && !resolve_symbol (symbuf, input_bfd, finfo, result, - isymbuf, locsymcount)) - { - undefined_reference ("section", symbuf); - return FALSE; - } - } - else - { - if (!resolve_symbol (symbuf, input_bfd, finfo, result, - isymbuf, locsymcount) - && !resolve_section (symbuf, finfo->output_bfd->sections, - result)) - { - undefined_reference ("symbol", symbuf); - return FALSE; - } - } - - return TRUE; - - /* All that remains are operators. */ - -#define UNARY_OP(op) \ - if (strncmp (sym, #op, strlen (#op)) == 0) \ - { \ - sym += strlen (#op); \ - if (*sym == ':') \ - ++sym; \ - *symp = sym; \ - if (!eval_symbol (&a, symp, input_bfd, finfo, dot, \ - isymbuf, locsymcount, signed_p)) \ - return FALSE; \ - if (signed_p) \ - *result = op ((bfd_signed_vma) a); \ - else \ - *result = op a; \ - return TRUE; \ - } - -#define BINARY_OP(op) \ - if (strncmp (sym, #op, strlen (#op)) == 0) \ - { \ - sym += strlen (#op); \ - if (*sym == ':') \ - ++sym; \ - *symp = sym; \ - if (!eval_symbol (&a, symp, input_bfd, finfo, dot, \ - isymbuf, locsymcount, signed_p)) \ - return FALSE; \ - ++*symp; \ - if (!eval_symbol (&b, symp, input_bfd, finfo, dot, \ - isymbuf, locsymcount, signed_p)) \ - return FALSE; \ - if (signed_p) \ - *result = ((bfd_signed_vma) a) op ((bfd_signed_vma) b); \ - else \ - *result = a op b; \ - return TRUE; \ - } - - default: - UNARY_OP (0-); - BINARY_OP (<<); - BINARY_OP (>>); - BINARY_OP (==); - BINARY_OP (!=); - BINARY_OP (<=); - BINARY_OP (>=); - BINARY_OP (&&); - BINARY_OP (||); - UNARY_OP (~); - UNARY_OP (!); - BINARY_OP (*); - BINARY_OP (/); - BINARY_OP (%); - BINARY_OP (^); - BINARY_OP (|); - BINARY_OP (&); - BINARY_OP (+); - BINARY_OP (-); - BINARY_OP (<); - BINARY_OP (>); -#undef UNARY_OP -#undef BINARY_OP - _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym); - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } -} - -static void -put_value (bfd_vma size, - unsigned long chunksz, - bfd *input_bfd, - bfd_vma x, - bfd_byte *location) -{ - location += (size - chunksz); - - for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8)) - { - switch (chunksz) - { - default: - case 0: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } - } -} - -static bfd_vma -get_value (bfd_vma size, - unsigned long chunksz, - bfd *input_bfd, - bfd_byte *location) -{ - bfd_vma x = 0; - - for (; size; size -= chunksz, location += chunksz) - { - switch (chunksz) - { - default: - case 0: - abort (); - case 1: - x = (x << (8 * chunksz)) | bfd_get_8 (input_bfd, location); - break; - case 2: - x = (x << (8 * chunksz)) | bfd_get_16 (input_bfd, location); - break; - case 4: - x = (x << (8 * chunksz)) | bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = (x << (8 * chunksz)) | bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } - } - return x; -} - -static void -decode_complex_addend (unsigned long *start, /* in bits */ - unsigned long *oplen, /* in bits */ - unsigned long *len, /* in bits */ - unsigned long *wordsz, /* in bytes */ - unsigned long *chunksz, /* in bytes */ - unsigned long *lsb0_p, - unsigned long *signed_p, - unsigned long *trunc_p, - unsigned long encoded) -{ - * start = encoded & 0x3F; - * len = (encoded >> 6) & 0x3F; - * oplen = (encoded >> 12) & 0x3F; - * wordsz = (encoded >> 18) & 0xF; - * chunksz = (encoded >> 22) & 0xF; - * lsb0_p = (encoded >> 27) & 1; - * signed_p = (encoded >> 28) & 1; - * trunc_p = (encoded >> 29) & 1; -} - -bfd_reloc_status_type -bfd_elf_perform_complex_relocation (bfd *input_bfd, - asection *input_section ATTRIBUTE_UNUSED, - bfd_byte *contents, - Elf_Internal_Rela *rel, - bfd_vma relocation) -{ - bfd_vma shift, x, mask; - unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p; - bfd_reloc_status_type r; - - /* Perform this reloc, since it is complex. - (this is not to say that it necessarily refers to a complex - symbol; merely that it is a self-describing CGEN based reloc. - i.e. the addend has the complete reloc information (bit start, end, - word size, etc) encoded within it.). */ - - decode_complex_addend (&start, &oplen, &len, &wordsz, - &chunksz, &lsb0_p, &signed_p, - &trunc_p, rel->r_addend); - - mask = (((1L << (len - 1)) - 1) << 1) | 1; - - if (lsb0_p) - shift = (start + 1) - len; - else - shift = (8 * wordsz) - (start + len); - - /* FIXME: octets_per_byte. */ - x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset); - -#ifdef DEBUG - printf ("Doing complex reloc: " - "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, " - "chunksz %ld, start %ld, len %ld, oplen %ld\n" - " dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n", - lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len, - oplen, (unsigned long) x, (unsigned long) mask, - (unsigned long) relocation); -#endif - - r = bfd_reloc_ok; - if (! trunc_p) - /* Now do an overflow check. */ - r = bfd_check_overflow ((signed_p - ? complain_overflow_signed - : complain_overflow_unsigned), - len, 0, (8 * wordsz), - relocation); - - /* Do the deed. */ - x = (x & ~(mask << shift)) | ((relocation & mask) << shift); - -#ifdef DEBUG - printf (" relocation: %8.8lx\n" - " shifted mask: %8.8lx\n" - " shifted/masked reloc: %8.8lx\n" - " result: %8.8lx\n", - (unsigned long) relocation, (unsigned long) (mask << shift), - (unsigned long) ((relocation & mask) << shift), (unsigned long) x); -#endif - /* FIXME: octets_per_byte. */ - put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset); - return r; -} - -/* When performing a relocatable link, the input relocations are - preserved. But, if they reference global symbols, the indices - referenced must be updated. Update all the relocations found in - RELDATA. */ - -static void -elf_link_adjust_relocs (bfd *abfd, - struct bfd_elf_section_reloc_data *reldata) -{ - unsigned int i; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_byte *erela; - void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - bfd_vma r_type_mask; - int r_sym_shift; - unsigned int count = reldata->count; - struct elf_link_hash_entry **rel_hash = reldata->hashes; - - if (reldata->hdr->sh_entsize == bed->s->sizeof_rel) - { - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - else if (reldata->hdr->sh_entsize == bed->s->sizeof_rela) - { - swap_in = bed->s->swap_reloca_in; - swap_out = bed->s->swap_reloca_out; - } - else - abort (); - - if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) - abort (); - - if (bed->s->arch_size == 32) - { - r_type_mask = 0xff; - r_sym_shift = 8; - } - else - { - r_type_mask = 0xffffffff; - r_sym_shift = 32; - } - - erela = reldata->hdr->contents; - for (i = 0; i < count; i++, rel_hash++, erela += reldata->hdr->sh_entsize) - { - Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; - unsigned int j; - - if (*rel_hash == NULL) - continue; - - BFD_ASSERT ((*rel_hash)->indx >= 0); - - (*swap_in) (abfd, erela, irela); - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) - irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift - | (irela[j].r_info & r_type_mask)); - (*swap_out) (abfd, irela, erela); - } -} - -struct elf_link_sort_rela -{ - union { - bfd_vma offset; - bfd_vma sym_mask; - } u; - enum elf_reloc_type_class type; - /* We use this as an array of size int_rels_per_ext_rel. */ - Elf_Internal_Rela rela[1]; -}; - -static int -elf_link_sort_cmp1 (const void *A, const void *B) -{ - const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; - const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; - int relativea, relativeb; - - relativea = a->type == reloc_class_relative; - relativeb = b->type == reloc_class_relative; - - if (relativea < relativeb) - return 1; - if (relativea > relativeb) - return -1; - if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) - return -1; - if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) - return 1; - if (a->rela->r_offset < b->rela->r_offset) - return -1; - if (a->rela->r_offset > b->rela->r_offset) - return 1; - return 0; -} - -static int -elf_link_sort_cmp2 (const void *A, const void *B) -{ - const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; - const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; - int copya, copyb; - - if (a->u.offset < b->u.offset) - return -1; - if (a->u.offset > b->u.offset) - return 1; - copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt); - copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt); - if (copya < copyb) - return -1; - if (copya > copyb) - return 1; - if (a->rela->r_offset < b->rela->r_offset) - return -1; - if (a->rela->r_offset > b->rela->r_offset) - return 1; - return 0; -} - -static size_t -elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) -{ - asection *dynamic_relocs; - asection *rela_dyn; - asection *rel_dyn; - bfd_size_type count, size; - size_t i, ret, sort_elt, ext_size; - bfd_byte *sort, *s_non_relative, *p; - struct elf_link_sort_rela *sq; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - int i2e = bed->s->int_rels_per_ext_rel; - void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - struct bfd_link_order *lo; - bfd_vma r_sym_mask; - bfd_boolean use_rela; - - /* Find a dynamic reloc section. */ - rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn"); - rel_dyn = bfd_get_section_by_name (abfd, ".rel.dyn"); - if (rela_dyn != NULL && rela_dyn->size > 0 - && rel_dyn != NULL && rel_dyn->size > 0) - { - bfd_boolean use_rela_initialised = FALSE; - - /* This is just here to stop gcc from complaining. - It's initialization checking code is not perfect. */ - use_rela = TRUE; - - /* Both sections are present. Examine the sizes - of the indirect sections to help us choose. */ - for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - asection *o = lo->u.indirect.section; - - if ((o->size % bed->s->sizeof_rela) == 0) - { - if ((o->size % bed->s->sizeof_rel) == 0) - /* Section size is divisible by both rel and rela sizes. - It is of no help to us. */ - ; - else - { - /* Section size is only divisible by rela. */ - if (use_rela_initialised && (use_rela == FALSE)) - { - _bfd_error_handler - (_("%B: Unable to sort relocs - they are in more than one size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - else - { - use_rela = TRUE; - use_rela_initialised = TRUE; - } - } - } - else if ((o->size % bed->s->sizeof_rel) == 0) - { - /* Section size is only divisible by rel. */ - if (use_rela_initialised && (use_rela == TRUE)) - { - _bfd_error_handler - (_("%B: Unable to sort relocs - they are in more than one size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - else - { - use_rela = FALSE; - use_rela_initialised = TRUE; - } - } - else - { - /* The section size is not divisible by either - something is wrong. */ - _bfd_error_handler - (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - } - - for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - asection *o = lo->u.indirect.section; - - if ((o->size % bed->s->sizeof_rela) == 0) - { - if ((o->size % bed->s->sizeof_rel) == 0) - /* Section size is divisible by both rel and rela sizes. - It is of no help to us. */ - ; - else - { - /* Section size is only divisible by rela. */ - if (use_rela_initialised && (use_rela == FALSE)) - { - _bfd_error_handler - (_("%B: Unable to sort relocs - they are in more than one size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - else - { - use_rela = TRUE; - use_rela_initialised = TRUE; - } - } - } - else if ((o->size % bed->s->sizeof_rel) == 0) - { - /* Section size is only divisible by rel. */ - if (use_rela_initialised && (use_rela == TRUE)) - { - _bfd_error_handler - (_("%B: Unable to sort relocs - they are in more than one size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - else - { - use_rela = FALSE; - use_rela_initialised = TRUE; - } - } - else - { - /* The section size is not divisible by either - something is wrong. */ - _bfd_error_handler - (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - } - - if (! use_rela_initialised) - /* Make a guess. */ - use_rela = TRUE; - } - else if (rela_dyn != NULL && rela_dyn->size > 0) - use_rela = TRUE; - else if (rel_dyn != NULL && rel_dyn->size > 0) - use_rela = FALSE; - else - return 0; - - if (use_rela) - { - dynamic_relocs = rela_dyn; - ext_size = bed->s->sizeof_rela; - swap_in = bed->s->swap_reloca_in; - swap_out = bed->s->swap_reloca_out; - } - else - { - dynamic_relocs = rel_dyn; - ext_size = bed->s->sizeof_rel; - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - - size = 0; - for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - size += lo->u.indirect.section->size; - - if (size != dynamic_relocs->size) - return 0; - - sort_elt = (sizeof (struct elf_link_sort_rela) - + (i2e - 1) * sizeof (Elf_Internal_Rela)); - - count = dynamic_relocs->size / ext_size; - if (count == 0) - return 0; - sort = (bfd_byte *) bfd_zmalloc (sort_elt * count); - - if (sort == NULL) - { - (*info->callbacks->warning) - (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0); - return 0; - } - - if (bed->s->arch_size == 32) - r_sym_mask = ~(bfd_vma) 0xff; - else - r_sym_mask = ~(bfd_vma) 0xffffffff; - - for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - bfd_byte *erel, *erelend; - asection *o = lo->u.indirect.section; - - if (o->contents == NULL && o->size != 0) - { - /* This is a reloc section that is being handled as a normal - section. See bfd_section_from_shdr. We can't combine - relocs in this case. */ - free (sort); - return 0; - } - erel = o->contents; - erelend = o->contents + o->size; - /* FIXME: octets_per_byte. */ - p = sort + o->output_offset / ext_size * sort_elt; - - while (erel < erelend) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - - (*swap_in) (abfd, erel, s->rela); - s->type = (*bed->elf_backend_reloc_type_class) (s->rela); - s->u.sym_mask = r_sym_mask; - p += sort_elt; - erel += ext_size; - } - } - - qsort (sort, count, sort_elt, elf_link_sort_cmp1); - - for (i = 0, p = sort; i < count; i++, p += sort_elt) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - if (s->type != reloc_class_relative) - break; - } - ret = i; - s_non_relative = p; - - sq = (struct elf_link_sort_rela *) s_non_relative; - for (; i < count; i++, p += sort_elt) - { - struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; - if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) - sq = sp; - sp->u.offset = sq->rela->r_offset; - } - - qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); - - for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - bfd_byte *erel, *erelend; - asection *o = lo->u.indirect.section; - - erel = o->contents; - erelend = o->contents + o->size; - /* FIXME: octets_per_byte. */ - p = sort + o->output_offset / ext_size * sort_elt; - while (erel < erelend) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - (*swap_out) (abfd, s->rela, erel); - p += sort_elt; - erel += ext_size; - } - } - - free (sort); - *psec = dynamic_relocs; - return ret; -} - -/* Flush the output symbols to the file. */ - -static bfd_boolean -elf_link_flush_output_syms (struct elf_final_link_info *finfo, - const struct elf_backend_data *bed) -{ - if (finfo->symbuf_count > 0) - { - Elf_Internal_Shdr *hdr; - file_ptr pos; - bfd_size_type amt; - - hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr; - pos = hdr->sh_offset + hdr->sh_size; - amt = finfo->symbuf_count * bed->s->sizeof_sym; - if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0 - || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt) - return FALSE; - - hdr->sh_size += amt; - finfo->symbuf_count = 0; - } - - return TRUE; -} - -/* Add a symbol to the output symbol table. */ - -static int -elf_link_output_sym (struct elf_final_link_info *finfo, - const char *name, - Elf_Internal_Sym *elfsym, - asection *input_sec, - struct elf_link_hash_entry *h) -{ - bfd_byte *dest; - Elf_External_Sym_Shndx *destshndx; - int (*output_symbol_hook) - (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (finfo->output_bfd); - output_symbol_hook = bed->elf_backend_link_output_symbol_hook; - if (output_symbol_hook != NULL) - { - int ret = (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h); - if (ret != 1) - return ret; - } - - if (name == NULL || *name == '\0') - elfsym->st_name = 0; - else if (input_sec->flags & SEC_EXCLUDE) - elfsym->st_name = 0; - else - { - elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, - name, TRUE, FALSE); - if (elfsym->st_name == (unsigned long) -1) - return 0; - } - - if (finfo->symbuf_count >= finfo->symbuf_size) - { - if (! elf_link_flush_output_syms (finfo, bed)) - return 0; - } - - dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym; - destshndx = finfo->symshndxbuf; - if (destshndx != NULL) - { - if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size) - { - bfd_size_type amt; - - amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); - destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx, - amt * 2); - if (destshndx == NULL) - return 0; - finfo->symshndxbuf = destshndx; - memset ((char *) destshndx + amt, 0, amt); - finfo->shndxbuf_size *= 2; - } - destshndx += bfd_get_symcount (finfo->output_bfd); - } - - bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx); - finfo->symbuf_count += 1; - bfd_get_symcount (finfo->output_bfd) += 1; - - return 1; -} - -/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */ - -static bfd_boolean -check_dynsym (bfd *abfd, Elf_Internal_Sym *sym) -{ - if (sym->st_shndx >= (SHN_LORESERVE & 0xffff) - && sym->st_shndx < SHN_LORESERVE) - { - /* The gABI doesn't support dynamic symbols in output sections - beyond 64k. */ - (*_bfd_error_handler) - (_("%B: Too many sections: %d (>= %d)"), - abfd, bfd_count_sections (abfd), SHN_LORESERVE & 0xffff); - bfd_set_error (bfd_error_nonrepresentable_section); - return FALSE; - } - return TRUE; -} - -/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in - allowing an unsatisfied unversioned symbol in the DSO to match a - versioned symbol that would normally require an explicit version. - We also handle the case that a DSO references a hidden symbol - which may be satisfied by a versioned symbol in another DSO. */ - -static bfd_boolean -elf_link_check_versioned_symbol (struct bfd_link_info *info, - const struct elf_backend_data *bed, - struct elf_link_hash_entry *h) -{ - bfd *abfd; - struct elf_link_loaded_list *loaded; - - if (!is_elf_hash_table (info->hash)) - return FALSE; - - switch (h->root.type) - { - default: - abfd = NULL; - break; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - abfd = h->root.u.undef.abfd; - if ((abfd->flags & DYNAMIC) == 0 - || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0) - return FALSE; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - abfd = h->root.u.def.section->owner; - break; - - case bfd_link_hash_common: - abfd = h->root.u.c.p->section->owner; - break; - } - BFD_ASSERT (abfd != NULL); - - for (loaded = elf_hash_table (info)->loaded; - loaded != NULL; - loaded = loaded->next) - { - bfd *input; - Elf_Internal_Shdr *hdr; - bfd_size_type symcount; - bfd_size_type extsymcount; - bfd_size_type extsymoff; - Elf_Internal_Shdr *versymhdr; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - Elf_Internal_Sym *isymbuf; - Elf_External_Versym *ever; - Elf_External_Versym *extversym; - - input = loaded->abfd; - - /* We check each DSO for a possible hidden versioned definition. */ - if (input == abfd - || (input->flags & DYNAMIC) == 0 - || elf_dynversym (input) == 0) - continue; - - hdr = &elf_tdata (input)->dynsymtab_hdr; - - symcount = hdr->sh_size / bed->s->sizeof_sym; - if (elf_bad_symtab (input)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - if (extsymcount == 0) - continue; - - isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, - NULL, NULL, NULL); - if (isymbuf == NULL) - return FALSE; - - /* Read in any version definitions. */ - versymhdr = &elf_tdata (input)->dynversym_hdr; - extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size); - if (extversym == NULL) - goto error_ret; - - if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 - || (bfd_bread (extversym, versymhdr->sh_size, input) - != versymhdr->sh_size)) - { - free (extversym); - error_ret: - free (isymbuf); - return FALSE; - } - - ever = extversym + extsymoff; - isymend = isymbuf + extsymcount; - for (isym = isymbuf; isym < isymend; isym++, ever++) - { - const char *name; - Elf_Internal_Versym iver; - unsigned short version_index; - - if (ELF_ST_BIND (isym->st_info) == STB_LOCAL - || isym->st_shndx == SHN_UNDEF) - continue; - - name = bfd_elf_string_from_elf_section (input, - hdr->sh_link, - isym->st_name); - if (strcmp (name, h->root.root.string) != 0) - continue; - - _bfd_elf_swap_versym_in (input, ever, &iver); - - if ((iver.vs_vers & VERSYM_HIDDEN) == 0 - && !(h->def_regular - && h->forced_local)) - { - /* If we have a non-hidden versioned sym, then it should - have provided a definition for the undefined sym unless - it is defined in a non-shared object and forced local. - */ - abort (); - } - - version_index = iver.vs_vers & VERSYM_VERSION; - if (version_index == 1 || version_index == 2) - { - /* This is the base or first version. We can use it. */ - free (extversym); - free (isymbuf); - return TRUE; - } - } - - free (extversym); - free (isymbuf); - } - - return FALSE; -} - -/* Add an external symbol to the symbol table. This is called from - the hash table traversal routine. When generating a shared object, - we go through the symbol table twice. The first time we output - anything that might have been forced to local scope in a version - script. The second time we output the symbols that are still - global symbols. */ - -static bfd_boolean -elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) -{ - struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh; - struct elf_outext_info *eoinfo = (struct elf_outext_info *) data; - struct elf_final_link_info *finfo = eoinfo->finfo; - bfd_boolean strip; - Elf_Internal_Sym sym; - asection *input_sec; - const struct elf_backend_data *bed; - long indx; - int ret; - - if (h->root.type == bfd_link_hash_warning) - { - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_new) - return TRUE; - } - - /* Decide whether to output this symbol in this pass. */ - if (eoinfo->localsyms) - { - if (!h->forced_local) - return TRUE; - } - else - { - if (h->forced_local) - return TRUE; - } - - bed = get_elf_backend_data (finfo->output_bfd); - - if (h->root.type == bfd_link_hash_undefined) - { - /* If we have an undefined symbol reference here then it must have - come from a shared library that is being linked in. (Undefined - references in regular files have already been handled unless - they are in unreferenced sections which are removed by garbage - collection). */ - bfd_boolean ignore_undef = FALSE; - - /* Some symbols may be special in that the fact that they're - undefined can be safely ignored - let backend determine that. */ - if (bed->elf_backend_ignore_undef_symbol) - ignore_undef = bed->elf_backend_ignore_undef_symbol (h); - - /* If we are reporting errors for this situation then do so now. */ - if (!ignore_undef - && h->ref_dynamic - && (!h->ref_regular || finfo->info->gc_sections) - && ! elf_link_check_versioned_symbol (finfo->info, bed, h) - && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) - { - if (! (finfo->info->callbacks->undefined_symbol - (finfo->info, h->root.root.string, - h->ref_regular ? NULL : h->root.u.undef.abfd, - NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) - { - bfd_set_error (bfd_error_bad_value); - eoinfo->failed = TRUE; - return FALSE; - } - } - } - - /* We should also warn if a forced local symbol is referenced from - shared libraries. */ - if (!finfo->info->relocatable - && finfo->info->executable - && h->forced_local - && h->ref_dynamic - && h->def_regular - && !h->dynamic_def - && !h->dynamic_weak - && ! elf_link_check_versioned_symbol (finfo->info, bed, h)) - { - bfd *def_bfd; - const char *msg; - - if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL) - msg = _("%B: internal symbol `%s' in %B is referenced by DSO"); - else if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) - msg = _("%B: hidden symbol `%s' in %B is referenced by DSO"); - else - msg = _("%B: local symbol `%s' in %B is referenced by DSO"); - def_bfd = finfo->output_bfd; - if (h->root.u.def.section != bfd_abs_section_ptr) - def_bfd = h->root.u.def.section->owner; - (*_bfd_error_handler) (msg, finfo->output_bfd, def_bfd, - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - eoinfo->failed = TRUE; - return FALSE; - } - - /* We don't want to output symbols that have never been mentioned by - a regular file, or that we have been told to strip. However, if - h->indx is set to -2, the symbol is used by a reloc and we must - output it. */ - if (h->indx == -2) - strip = FALSE; - else if ((h->def_dynamic - || h->ref_dynamic - || h->root.type == bfd_link_hash_new) - && !h->def_regular - && !h->ref_regular) - strip = TRUE; - else if (finfo->info->strip == strip_all) - strip = TRUE; - else if (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, FALSE, FALSE) == NULL) - strip = TRUE; - else if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && ((finfo->info->strip_discarded - && elf_discarded_section (h->root.u.def.section)) - || (h->root.u.def.section->owner != NULL - && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0))) - strip = TRUE; - else if ((h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && h->root.u.undef.abfd != NULL - && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0) - strip = TRUE; - else - strip = FALSE; - - /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do unless it is a forced local symbol or a - STT_GNU_IFUNC symbol. */ - if (strip - && h->dynindx == -1 - && h->type != STT_GNU_IFUNC - && !h->forced_local) - return TRUE; - - sym.st_value = 0; - sym.st_size = h->size; - sym.st_other = h->other; - if (h->forced_local) - { - sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); - /* Turn off visibility on local symbol. */ - sym.st_other &= ~ELF_ST_VISIBILITY (-1); - } - else if (h->unique_global) - sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type); - else if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); - sym.st_target_internal = h->target_internal; - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - case bfd_link_hash_warning: - abort (); - return FALSE; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - input_sec = h->root.u.def.section; - if (input_sec->output_section != NULL) - { - sym.st_shndx = - _bfd_elf_section_from_bfd_section (finfo->output_bfd, - input_sec->output_section); - if (sym.st_shndx == SHN_BAD) - { - (*_bfd_error_handler) - (_("%B: could not find output section %A for input section %A"), - finfo->output_bfd, input_sec->output_section, input_sec); - bfd_set_error (bfd_error_nonrepresentable_section); - eoinfo->failed = TRUE; - return FALSE; - } - - /* ELF symbols in relocatable files are section relative, - but in nonrelocatable files they are virtual - addresses. */ - sym.st_value = h->root.u.def.value + input_sec->output_offset; - if (! finfo->info->relocatable) - { - sym.st_value += input_sec->output_section->vma; - if (h->type == STT_TLS) - { - asection *tls_sec = elf_hash_table (finfo->info)->tls_sec; - if (tls_sec != NULL) - sym.st_value -= tls_sec->vma; - else - { - /* The TLS section may have been garbage collected. */ - BFD_ASSERT (finfo->info->gc_sections - && !input_sec->gc_mark); - } - } - } - } - else - { - BFD_ASSERT (input_sec->owner == NULL - || (input_sec->owner->flags & DYNAMIC) != 0); - sym.st_shndx = SHN_UNDEF; - input_sec = bfd_und_section_ptr; - } - } - break; - - case bfd_link_hash_common: - input_sec = h->root.u.c.p->section; - sym.st_shndx = bed->common_section_index (input_sec); - sym.st_value = 1 << h->root.u.c.p->alignment_power; - break; - - case bfd_link_hash_indirect: - /* These symbols are created by symbol versioning. They point - to the decorated version of the name. For example, if the - symbol foo@@GNU_1.2 is the default, which should be used when - foo is used with no version, then we add an indirect symbol - foo which points to foo@@GNU_1.2. We ignore these symbols, - since the indirected symbol is already in the hash table. */ - return TRUE; - } - - /* Give the processor backend a chance to tweak the symbol value, - and also to finish up anything that needs to be done for this - symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for - forced local syms when non-shared is due to a historical quirk. - STT_GNU_IFUNC symbol must go through PLT. */ - if ((h->type == STT_GNU_IFUNC - && h->def_regular - && !finfo->info->relocatable) - || ((h->dynindx != -1 - || h->forced_local) - && ((finfo->info->shared - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) - || !h->forced_local) - && elf_hash_table (finfo->info)->dynamic_sections_created)) - { - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (finfo->output_bfd, finfo->info, h, &sym))) - { - eoinfo->failed = TRUE; - return FALSE; - } - } - - /* If we are marking the symbol as undefined, and there are no - non-weak references to this symbol from a regular object, then - mark the symbol as weak undefined; if there are non-weak - references, mark the symbol as strong. We can't do this earlier, - because it might not be marked as undefined until the - finish_dynamic_symbol routine gets through with it. */ - if (sym.st_shndx == SHN_UNDEF - && h->ref_regular - && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL - || ELF_ST_BIND (sym.st_info) == STB_WEAK)) - { - int bindtype; - unsigned int type = ELF_ST_TYPE (sym.st_info); - - /* Turn an undefined IFUNC symbol into a normal FUNC symbol. */ - if (type == STT_GNU_IFUNC) - type = STT_FUNC; - - if (h->ref_regular_nonweak) - bindtype = STB_GLOBAL; - else - bindtype = STB_WEAK; - sym.st_info = ELF_ST_INFO (bindtype, type); - } - - /* If this is a symbol defined in a dynamic library, don't use the - symbol size from the dynamic library. Relinking an executable - against a new library may introduce gratuitous changes in the - executable's symbols if we keep the size. */ - if (sym.st_shndx == SHN_UNDEF - && !h->def_regular - && h->def_dynamic) - sym.st_size = 0; - - /* If a non-weak symbol with non-default visibility is not defined - locally, it is a fatal error. */ - if (! finfo->info->relocatable - && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT - && ELF_ST_BIND (sym.st_info) != STB_WEAK - && h->root.type == bfd_link_hash_undefined - && !h->def_regular) - { - const char *msg; - - if (ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED) - msg = _("%B: protected symbol `%s' isn't defined"); - else if (ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL) - msg = _("%B: internal symbol `%s' isn't defined"); - else - msg = _("%B: hidden symbol `%s' isn't defined"); - (*_bfd_error_handler) (msg, finfo->output_bfd, h->root.root.string); - bfd_set_error (bfd_error_bad_value); - eoinfo->failed = TRUE; - return FALSE; - } - - /* If this symbol should be put in the .dynsym section, then put it - there now. We already know the symbol index. We also fill in - the entry in the .hash section. */ - if (h->dynindx != -1 - && elf_hash_table (finfo->info)->dynamic_sections_created) - { - bfd_byte *esym; - - sym.st_name = h->dynstr_index; - esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym; - if (! check_dynsym (finfo->output_bfd, &sym)) - { - eoinfo->failed = TRUE; - return FALSE; - } - bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0); - - if (finfo->hash_sec != NULL) - { - size_t hash_entry_size; - bfd_byte *bucketpos; - bfd_vma chain; - size_t bucketcount; - size_t bucket; - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = h->u.elf_hash_value % bucketcount; - - hash_entry_size - = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; - bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * hash_entry_size); - chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); - bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); - bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * hash_entry_size)); - } - - if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) - { - Elf_Internal_Versym iversym; - Elf_External_Versym *eversym; - - if (!h->def_regular) - { - if (h->verinfo.verdef == NULL) - iversym.vs_vers = 0; - else - iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; - } - else - { - if (h->verinfo.vertree == NULL) - iversym.vs_vers = 1; - else - iversym.vs_vers = h->verinfo.vertree->vernum + 1; - if (finfo->info->create_default_symver) - iversym.vs_vers++; - } - - if (h->hidden) - iversym.vs_vers |= VERSYM_HIDDEN; - - eversym = (Elf_External_Versym *) finfo->symver_sec->contents; - eversym += h->dynindx; - _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); - } - } - - /* If we're stripping it, then it was just a dynamic symbol, and - there's nothing else to do. */ - if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) - return TRUE; - - indx = bfd_get_symcount (finfo->output_bfd); - ret = elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h); - if (ret == 0) - { - eoinfo->failed = TRUE; - return FALSE; - } - else if (ret == 1) - h->indx = indx; - else if (h->indx == -2) - abort(); - - return TRUE; -} - -/* Return TRUE if special handling is done for relocs in SEC against - symbols defined in discarded sections. */ - -static bfd_boolean -elf_section_ignore_discarded_relocs (asection *sec) -{ - const struct elf_backend_data *bed; - - switch (sec->sec_info_type) - { - case ELF_INFO_TYPE_STABS: - case ELF_INFO_TYPE_EH_FRAME: - return TRUE; - default: - break; - } - - bed = get_elf_backend_data (sec->owner); - if (bed->elf_backend_ignore_discarded_relocs != NULL - && (*bed->elf_backend_ignore_discarded_relocs) (sec)) - return TRUE; - - return FALSE; -} - -/* Return a mask saying how ld should treat relocations in SEC against - symbols defined in discarded sections. If this function returns - COMPLAIN set, ld will issue a warning message. If this function - returns PRETEND set, and the discarded section was link-once and the - same size as the kept link-once section, ld will pretend that the - symbol was actually defined in the kept section. Otherwise ld will - zero the reloc (at least that is the intent, but some cooperation by - the target dependent code is needed, particularly for REL targets). */ - -unsigned int -_bfd_elf_default_action_discarded (asection *sec) -{ - if (sec->flags & SEC_DEBUGGING) - return PRETEND; - - if (strcmp (".eh_frame", sec->name) == 0) - return 0; - - if (strcmp (".gcc_except_table", sec->name) == 0) - return 0; - - return COMPLAIN | PRETEND; -} - -/* Find a match between a section and a member of a section group. */ - -static asection * -match_group_member (asection *sec, asection *group, - struct bfd_link_info *info) -{ - asection *first = elf_next_in_group (group); - asection *s = first; - - while (s != NULL) - { - if (bfd_elf_match_symbols_in_sections (s, sec, info)) - return s; - - s = elf_next_in_group (s); - if (s == first) - break; - } - - return NULL; -} - -/* Check if the kept section of a discarded section SEC can be used - to replace it. Return the replacement if it is OK. Otherwise return - NULL. */ - -asection * -_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info) -{ - asection *kept; - - kept = sec->kept_section; - if (kept != NULL) - { - if ((kept->flags & SEC_GROUP) != 0) - kept = match_group_member (sec, kept, info); - if (kept != NULL - && ((sec->rawsize != 0 ? sec->rawsize : sec->size) - != (kept->rawsize != 0 ? kept->rawsize : kept->size))) - kept = NULL; - sec->kept_section = kept; - } - return kept; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. - This is so that we only have to read the local symbols once, and - don't have to keep them in memory. */ - -static bfd_boolean -elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) -{ - int (*relocate_section) - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); - bfd *output_bfd; - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - Elf_Internal_Sym *isymbuf; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - long *pindex; - asection **ppsection; - asection *o; - const struct elf_backend_data *bed; - struct elf_link_hash_entry **sym_hashes; - bfd_size_type address_size; - bfd_vma r_type_mask; - int r_sym_shift; - - output_bfd = finfo->output_bfd; - bed = get_elf_backend_data (output_bfd); - relocate_section = bed->elf_backend_relocate_section; - - /* If this is a dynamic object, we don't want to do anything here: - we don't want the local symbols, and we don't want the section - contents. */ - if ((input_bfd->flags & DYNAMIC) != 0) - return TRUE; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - /* Read the local symbols. */ - isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; - if (isymbuf == NULL && locsymcount != 0) - { - isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, - finfo->internal_syms, - finfo->external_syms, - finfo->locsym_shndx); - if (isymbuf == NULL) - return FALSE; - } - - /* Find local symbol sections and adjust values of symbols in - SEC_MERGE sections. Write out those local symbols we know are - going into the output file. */ - isymend = isymbuf + locsymcount; - for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections; - isym < isymend; - isym++, pindex++, ppsection++) - { - asection *isec; - const char *name; - Elf_Internal_Sym osym; - long indx; - int ret; - - *pindex = -1; - - if (elf_bad_symtab (input_bfd)) - { - if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) - { - *ppsection = NULL; - continue; - } - } - - if (isym->st_shndx == SHN_UNDEF) - isec = bfd_und_section_ptr; - else if (isym->st_shndx == SHN_ABS) - isec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - isec = bfd_com_section_ptr; - else - { - isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); - if (isec == NULL) - { - /* Don't attempt to output symbols with st_shnx in the - reserved range other than SHN_ABS and SHN_COMMON. */ - *ppsection = NULL; - continue; - } - else if (isec->sec_info_type == ELF_INFO_TYPE_MERGE - && ELF_ST_TYPE (isym->st_info) != STT_SECTION) - isym->st_value = - _bfd_merged_section_offset (output_bfd, &isec, - elf_section_data (isec)->sec_info, - isym->st_value); - } - - *ppsection = isec; - - /* Don't output the first, undefined, symbol. */ - if (ppsection == finfo->sections) - continue; - - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - { - /* We never output section symbols. Instead, we use the - section symbol of the corresponding section in the output - file. */ - continue; - } - - /* If we are stripping all symbols, we don't want to output this - one. */ - if (finfo->info->strip == strip_all) - continue; - - /* If we are discarding all local symbols, we don't want to - output this one. If we are generating a relocatable output - file, then some of the local symbols may be required by - relocs; we output them below as we discover that they are - needed. */ - if (finfo->info->discard == discard_all) - continue; - - /* If this symbol is defined in a section which we are - discarding, we don't need to keep it. */ - if (isym->st_shndx != SHN_UNDEF - && isym->st_shndx < SHN_LORESERVE - && bfd_section_removed_from_list (output_bfd, - isec->output_section)) - continue; - - /* Get the name of the symbol. */ - name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, - isym->st_name); - if (name == NULL) - return FALSE; - - /* See if we are discarding symbols with this name. */ - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE) - == NULL)) - || (((finfo->info->discard == discard_sec_merge - && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable) - || finfo->info->discard == discard_l) - && bfd_is_local_label_name (input_bfd, name))) - continue; - - osym = *isym; - - /* Adjust the section index for the output file. */ - osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, - isec->output_section); - if (osym.st_shndx == SHN_BAD) - return FALSE; - - /* ELF symbols in relocatable files are section relative, but - in executable files they are virtual addresses. Note that - this code assumes that all ELF sections have an associated - BFD section with a reasonable value for output_offset; below - we assume that they also have a reasonable value for - output_section. Any special sections must be set up to meet - these requirements. */ - osym.st_value += isec->output_offset; - if (! finfo->info->relocatable) - { - osym.st_value += isec->output_section->vma; - if (ELF_ST_TYPE (osym.st_info) == STT_TLS) - { - /* STT_TLS symbols are relative to PT_TLS segment base. */ - BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); - osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; - } - } - - indx = bfd_get_symcount (output_bfd); - ret = elf_link_output_sym (finfo, name, &osym, isec, NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) - *pindex = indx; - } - - if (bed->s->arch_size == 32) - { - r_type_mask = 0xff; - r_sym_shift = 8; - address_size = 4; - } - else - { - r_type_mask = 0xffffffff; - r_sym_shift = 32; - address_size = 8; - } - - /* Relocate the contents of each section. */ - sym_hashes = elf_sym_hashes (input_bfd); - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if (! o->linker_mark) - { - /* This section was omitted from the link. */ - continue; - } - - if (finfo->info->relocatable - && (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP) - { - /* Deal with the group signature symbol. */ - struct bfd_elf_section_data *sec_data = elf_section_data (o); - unsigned long symndx = sec_data->this_hdr.sh_info; - asection *osec = o->output_section; - - if (symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[symndx] == NULL)) - { - struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - /* Arrange for symbol to be output. */ - h->indx = -2; - elf_section_data (osec)->this_hdr.sh_info = -2; - } - else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION) - { - /* We'll use the output section target_index. */ - asection *sec = finfo->sections[symndx]->output_section; - elf_section_data (osec)->this_hdr.sh_info = sec->target_index; - } - else - { - if (finfo->indices[symndx] == -1) - { - /* Otherwise output the local symbol now. */ - Elf_Internal_Sym sym = isymbuf[symndx]; - asection *sec = finfo->sections[symndx]->output_section; - const char *name; - long indx; - int ret; - - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym.st_name); - if (name == NULL) - return FALSE; - - sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, - sec); - if (sym.st_shndx == SHN_BAD) - return FALSE; - - sym.st_value += o->output_offset; - - indx = bfd_get_symcount (output_bfd); - ret = elf_link_output_sym (finfo, name, &sym, o, NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) - finfo->indices[symndx] = indx; - else - abort (); - } - elf_section_data (osec)->this_hdr.sh_info - = finfo->indices[symndx]; - } - } - - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) - continue; - - if ((o->flags & SEC_LINKER_CREATED) != 0) - { - /* Section was created by _bfd_elf_link_create_dynamic_sections - or somesuch. */ - continue; - } - - /* Get the contents of the section. They have been cached by a - relaxation routine. Note that o is a section in an input - file, so the contents field will not have been set by any of - the routines which work on output files. */ - if (elf_section_data (o)->this_hdr.contents != NULL) - contents = elf_section_data (o)->this_hdr.contents; - else - { - contents = finfo->contents; - if (! bfd_get_full_section_contents (input_bfd, o, &contents)) - return FALSE; - } - - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Rela *internal_relocs; - Elf_Internal_Rela *rel, *relend; - int action_discarded; - int ret; - - /* Get the swapped relocs. */ - internal_relocs - = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs, - finfo->internal_relocs, FALSE); - if (internal_relocs == NULL - && o->reloc_count > 0) - return FALSE; - - /* We need to reverse-copy input .ctors/.dtors sections if - they are placed in .init_array/.finit_array for output. */ - if (o->size > address_size - && ((strncmp (o->name, ".ctors", 6) == 0 - && strcmp (o->output_section->name, - ".init_array") == 0) - || (strncmp (o->name, ".dtors", 6) == 0 - && strcmp (o->output_section->name, - ".fini_array") == 0)) - && (o->name[6] == 0 || o->name[6] == '.')) - { - if (o->size != o->reloc_count * address_size) - { - (*_bfd_error_handler) - (_("error: %B: size of section %A is not " - "multiple of address size"), - input_bfd, o); - bfd_set_error (bfd_error_on_input); - return FALSE; - } - o->flags |= SEC_ELF_REVERSE_COPY; - } - - action_discarded = -1; - if (!elf_section_ignore_discarded_relocs (o)) - action_discarded = (*bed->action_discarded) (o); - - /* Run through the relocs evaluating complex reloc symbols and - looking for relocs against symbols from discarded sections - or section symbols from removed link-once sections. - Complain about relocs against discarded sections. Zero - relocs against removed link-once sections. */ - - rel = internal_relocs; - relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; - for ( ; rel < relend; rel++) - { - unsigned long r_symndx = rel->r_info >> r_sym_shift; - unsigned int s_type; - asection **ps, *sec; - struct elf_link_hash_entry *h = NULL; - const char *sym_name; - - if (r_symndx == STN_UNDEF) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - h = sym_hashes[r_symndx - extsymoff]; - - /* Badly formatted input files can contain relocs that - reference non-existant symbols. Check here so that - we do not seg fault. */ - if (h == NULL) - { - char buffer [32]; - - sprintf_vma (buffer, rel->r_info); - (*_bfd_error_handler) - (_("error: %B contains a reloc (0x%s) for section %A " - "that references a non-existent global symbol"), - input_bfd, o, buffer); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - s_type = h->type; - - ps = NULL; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - ps = &h->root.u.def.section; - - sym_name = h->root.root.string; - } - else - { - Elf_Internal_Sym *sym = isymbuf + r_symndx; - - s_type = ELF_ST_TYPE (sym->st_info); - ps = &finfo->sections[r_symndx]; - sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, - sym, *ps); - } - - if ((s_type == STT_RELC || s_type == STT_SRELC) - && !finfo->info->relocatable) - { - bfd_vma val; - bfd_vma dot = (rel->r_offset - + o->output_offset + o->output_section->vma); -#ifdef DEBUG - printf ("Encountered a complex symbol!"); - printf (" (input_bfd %s, section %s, reloc %ld\n", - input_bfd->filename, o->name, - (long) (rel - internal_relocs)); - printf (" symbol: idx %8.8lx, name %s\n", - r_symndx, sym_name); - printf (" reloc : info %8.8lx, addr %8.8lx\n", - (unsigned long) rel->r_info, - (unsigned long) rel->r_offset); -#endif - if (!eval_symbol (&val, &sym_name, input_bfd, finfo, dot, - isymbuf, locsymcount, s_type == STT_SRELC)) - return FALSE; - - /* Symbol evaluated OK. Update to absolute value. */ - set_symbol_value (input_bfd, isymbuf, locsymcount, - r_symndx, val); - continue; - } - - if (action_discarded != -1 && ps != NULL) - { - /* Complain if the definition comes from a - discarded section. */ - if ((sec = *ps) != NULL && elf_discarded_section (sec)) - { - BFD_ASSERT (r_symndx != STN_UNDEF); - if (action_discarded & COMPLAIN) - (*finfo->info->callbacks->einfo) - (_("%X`%s' referenced in section `%A' of %B: " - "defined in discarded section `%A' of %B\n"), - sym_name, o, input_bfd, sec, sec->owner); - - /* Try to do the best we can to support buggy old - versions of gcc. Pretend that the symbol is - really defined in the kept linkonce section. - FIXME: This is quite broken. Modifying the - symbol here means we will be changing all later - uses of the symbol, not just in this section. */ - if (action_discarded & PRETEND) - { - asection *kept; - - kept = _bfd_elf_check_kept_section (sec, - finfo->info); - if (kept != NULL) - { - *ps = kept; - continue; - } - } - } - } - } - - /* Relocate the section by invoking a back end routine. - - The back end routine is responsible for adjusting the - section contents as necessary, and (if using Rela relocs - and generating a relocatable output file) adjusting the - reloc addend as necessary. - - The back end routine does not have to worry about setting - the reloc address or the reloc symbol index. - - The back end routine is given a pointer to the swapped in - internal symbols, and can access the hash table entries - for the external symbols via elf_sym_hashes (input_bfd). - - When generating relocatable output, the back end routine - must handle STB_LOCAL/STT_SECTION symbols specially. The - output symbol is going to be a section symbol - corresponding to the output section, which will require - the addend to be adjusted. */ - - ret = (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, contents, - internal_relocs, - isymbuf, - finfo->sections); - if (!ret) - return FALSE; - - if (ret == 2 - || finfo->info->relocatable - || finfo->info->emitrelocations) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend, *irelamid; - bfd_vma last_offset; - struct elf_link_hash_entry **rel_hash; - struct elf_link_hash_entry **rel_hash_list, **rela_hash_list; - Elf_Internal_Shdr *input_rel_hdr, *input_rela_hdr; - unsigned int next_erel; - bfd_boolean rela_normal; - struct bfd_elf_section_data *esdi, *esdo; - - esdi = elf_section_data (o); - esdo = elf_section_data (o->output_section); - rela_normal = FALSE; - - /* Adjust the reloc addresses and symbol indices. */ - - irela = internal_relocs; - irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel; - rel_hash = esdo->rel.hashes + esdo->rel.count; - /* We start processing the REL relocs, if any. When we reach - IRELAMID in the loop, we switch to the RELA relocs. */ - irelamid = irela; - if (esdi->rel.hdr != NULL) - irelamid += (NUM_SHDR_ENTRIES (esdi->rel.hdr) - * bed->s->int_rels_per_ext_rel); - rel_hash_list = rel_hash; - rela_hash_list = NULL; - last_offset = o->output_offset; - if (!finfo->info->relocatable) - last_offset += o->output_section->vma; - for (next_erel = 0; irela < irelaend; irela++, next_erel++) - { - unsigned long r_symndx; - asection *sec; - Elf_Internal_Sym sym; - - if (next_erel == bed->s->int_rels_per_ext_rel) - { - rel_hash++; - next_erel = 0; - } - - if (irela == irelamid) - { - rel_hash = esdo->rela.hashes + esdo->rela.count; - rela_hash_list = rel_hash; - rela_normal = bed->rela_normal; - } - - irela->r_offset = _bfd_elf_section_offset (output_bfd, - finfo->info, o, - irela->r_offset); - if (irela->r_offset >= (bfd_vma) -2) - { - /* This is a reloc for a deleted entry or somesuch. - Turn it into an R_*_NONE reloc, at the same - offset as the last reloc. elf_eh_frame.c and - bfd_elf_discard_info rely on reloc offsets - being ordered. */ - irela->r_offset = last_offset; - irela->r_info = 0; - irela->r_addend = 0; - continue; - } - - irela->r_offset += o->output_offset; - - /* Relocs in an executable have to be virtual addresses. */ - if (!finfo->info->relocatable) - irela->r_offset += o->output_section->vma; - - last_offset = irela->r_offset; - - r_symndx = irela->r_info >> r_sym_shift; - if (r_symndx == STN_UNDEF) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - struct elf_link_hash_entry *rh; - unsigned long indx; - - /* This is a reloc against a global symbol. We - have not yet output all the local symbols, so - we do not know the symbol index of any global - symbol. We set the rel_hash entry for this - reloc to point to the global hash table entry - for this symbol. The symbol index is then - set at the end of bfd_elf_final_link. */ - indx = r_symndx - extsymoff; - rh = elf_sym_hashes (input_bfd)[indx]; - while (rh->root.type == bfd_link_hash_indirect - || rh->root.type == bfd_link_hash_warning) - rh = (struct elf_link_hash_entry *) rh->root.u.i.link; - - /* Setting the index to -2 tells - elf_link_output_extsym that this symbol is - used by a reloc. */ - BFD_ASSERT (rh->indx < 0); - rh->indx = -2; - - *rel_hash = rh; - - continue; - } - - /* This is a reloc against a local symbol. */ - - *rel_hash = NULL; - sym = isymbuf[r_symndx]; - sec = finfo->sections[r_symndx]; - if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) - { - /* I suppose the backend ought to fill in the - section of any STT_SECTION symbol against a - processor specific section. */ - r_symndx = STN_UNDEF; - if (bfd_is_abs_section (sec)) - ; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - else - { - asection *osec = sec->output_section; - - /* If we have discarded a section, the output - section will be the absolute section. In - case of discarded SEC_MERGE sections, use - the kept section. relocate_section should - have already handled discarded linkonce - sections. */ - if (bfd_is_abs_section (osec) - && sec->kept_section != NULL - && sec->kept_section->output_section != NULL) - { - osec = sec->kept_section->output_section; - irela->r_addend -= osec->vma; - } - - if (!bfd_is_abs_section (osec)) - { - r_symndx = osec->target_index; - if (r_symndx == STN_UNDEF) - { - struct elf_link_hash_table *htab; - asection *oi; - - htab = elf_hash_table (finfo->info); - oi = htab->text_index_section; - if ((osec->flags & SEC_READONLY) == 0 - && htab->data_index_section != NULL) - oi = htab->data_index_section; - - if (oi != NULL) - { - irela->r_addend += osec->vma - oi->vma; - r_symndx = oi->target_index; - } - } - - BFD_ASSERT (r_symndx != STN_UNDEF); - } - } - - /* Adjust the addend according to where the - section winds up in the output section. */ - if (rela_normal) - irela->r_addend += sec->output_offset; - } - else - { - if (finfo->indices[r_symndx] == -1) - { - unsigned long shlink; - const char *name; - asection *osec; - long indx; - - if (finfo->info->strip == strip_all) - { - /* You can't do ld -r -s. */ - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* This symbol was skipped earlier, but - since it is needed by a reloc, we - must output it now. */ - shlink = symtab_hdr->sh_link; - name = (bfd_elf_string_from_elf_section - (input_bfd, shlink, sym.st_name)); - if (name == NULL) - return FALSE; - - osec = sec->output_section; - sym.st_shndx = - _bfd_elf_section_from_bfd_section (output_bfd, - osec); - if (sym.st_shndx == SHN_BAD) - return FALSE; - - sym.st_value += sec->output_offset; - if (! finfo->info->relocatable) - { - sym.st_value += osec->vma; - if (ELF_ST_TYPE (sym.st_info) == STT_TLS) - { - /* STT_TLS symbols are relative to PT_TLS - segment base. */ - BFD_ASSERT (elf_hash_table (finfo->info) - ->tls_sec != NULL); - sym.st_value -= (elf_hash_table (finfo->info) - ->tls_sec->vma); - } - } - - indx = bfd_get_symcount (output_bfd); - ret = elf_link_output_sym (finfo, name, &sym, sec, - NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) - finfo->indices[r_symndx] = indx; - else - abort (); - } - - r_symndx = finfo->indices[r_symndx]; - } - - irela->r_info = ((bfd_vma) r_symndx << r_sym_shift - | (irela->r_info & r_type_mask)); - } - - /* Swap out the relocs. */ - input_rel_hdr = esdi->rel.hdr; - if (input_rel_hdr && input_rel_hdr->sh_size != 0) - { - if (!bed->elf_backend_emit_relocs (output_bfd, o, - input_rel_hdr, - internal_relocs, - rel_hash_list)) - return FALSE; - internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) - * bed->s->int_rels_per_ext_rel); - rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr); - } - - input_rela_hdr = esdi->rela.hdr; - if (input_rela_hdr && input_rela_hdr->sh_size != 0) - { - if (!bed->elf_backend_emit_relocs (output_bfd, o, - input_rela_hdr, - internal_relocs, - rela_hash_list)) - return FALSE; - } - } - } - - /* Write out the modified section contents. */ - if (bed->elf_backend_write_section - && (*bed->elf_backend_write_section) (output_bfd, finfo->info, o, - contents)) - { - /* Section written out. */ - } - else switch (o->sec_info_type) - { - case ELF_INFO_TYPE_STABS: - if (! (_bfd_write_section_stabs - (output_bfd, - &elf_hash_table (finfo->info)->stab_info, - o, &elf_section_data (o)->sec_info, contents))) - return FALSE; - break; - case ELF_INFO_TYPE_MERGE: - if (! _bfd_write_merged_section (output_bfd, o, - elf_section_data (o)->sec_info)) - return FALSE; - break; - case ELF_INFO_TYPE_EH_FRAME: - { - if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, - o, contents)) - return FALSE; - } - break; - default: - { - /* FIXME: octets_per_byte. */ - if (! (o->flags & SEC_EXCLUDE)) - { - file_ptr offset = (file_ptr) o->output_offset; - bfd_size_type todo = o->size; - if ((o->flags & SEC_ELF_REVERSE_COPY)) - { - /* Reverse-copy input section to output. */ - do - { - todo -= address_size; - if (! bfd_set_section_contents (output_bfd, - o->output_section, - contents + todo, - offset, - address_size)) - return FALSE; - if (todo == 0) - break; - offset += address_size; - } - while (1); - } - else if (! bfd_set_section_contents (output_bfd, - o->output_section, - contents, - offset, todo)) - return FALSE; - } - } - break; - } - } - - return TRUE; -} - -/* Generate a reloc when linking an ELF file. This is a reloc - requested by the linker, and does not come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static bfd_boolean -elf_reloc_link_order (bfd *output_bfd, - struct bfd_link_info *info, - asection *output_section, - struct bfd_link_order *link_order) -{ - reloc_howto_type *howto; - long indx; - bfd_vma offset; - bfd_vma addend; - struct bfd_elf_section_reloc_data *reldata; - struct elf_link_hash_entry **rel_hash_ptr; - Elf_Internal_Shdr *rel_hdr; - const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; - bfd_byte *erel; - unsigned int i; - struct bfd_elf_section_data *esdo = elf_section_data (output_section); - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - addend = link_order->u.reloc.p->addend; - - if (esdo->rel.hdr) - reldata = &esdo->rel; - else if (esdo->rela.hdr) - reldata = &esdo->rela; - else - { - reldata = NULL; - BFD_ASSERT (0); - } - - /* Figure out the symbol index. */ - rel_hash_ptr = reldata->hashes + reldata->count; - if (link_order->type == bfd_section_reloc_link_order) - { - indx = link_order->u.reloc.p->u.section->target_index; - BFD_ASSERT (indx != 0); - *rel_hash_ptr = NULL; - } - else - { - struct elf_link_hash_entry *h; - - /* Treat a reloc against a defined symbol as though it were - actually against the section. */ - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - FALSE, FALSE, TRUE)); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *section; - - section = h->root.u.def.section; - indx = section->output_section->target_index; - *rel_hash_ptr = NULL; - /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ - addend += section->output_section->vma + section->output_offset; - } - else if (h != NULL) - { - /* Setting the index to -2 tells elf_link_output_extsym that - this symbol is used by a reloc. */ - h->indx = -2; - *rel_hash_ptr = h; - indx = 0; - } - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) - return FALSE; - indx = 0; - } - } - - /* If this is an inplace reloc, we must write the addend into the - object file. */ - if (howto->partial_inplace && addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - bfd_boolean ok; - const char *sym_name; - - size = (bfd_size_type) bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return FALSE; - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - - default: - case bfd_reloc_outofrange: - abort (); - - case bfd_reloc_overflow: - if (link_order->type == bfd_section_reloc_link_order) - sym_name = bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section); - else - sym_name = link_order->u.reloc.p->u.name; - if (! ((*info->callbacks->reloc_overflow) - (info, NULL, sym_name, howto->name, addend, NULL, - NULL, (bfd_vma) 0))) - { - free (buf); - return FALSE; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, buf, - link_order->offset, size); - free (buf); - if (! ok) - return FALSE; - } - - /* The address of a reloc is relative to the section in a - relocatable file, and is a virtual address in an executable - file. */ - offset = link_order->offset; - if (! info->relocatable) - offset += output_section->vma; - - for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - { - irel[i].r_offset = offset; - irel[i].r_info = 0; - irel[i].r_addend = 0; - } - if (bed->s->arch_size == 32) - irel[0].r_info = ELF32_R_INFO (indx, howto->type); - else - irel[0].r_info = ELF64_R_INFO (indx, howto->type); - - rel_hdr = reldata->hdr; - erel = rel_hdr->contents; - if (rel_hdr->sh_type == SHT_REL) - { - erel += reldata->count * bed->s->sizeof_rel; - (*bed->s->swap_reloc_out) (output_bfd, irel, erel); - } - else - { - irel[0].r_addend = addend; - erel += reldata->count * bed->s->sizeof_rela; - (*bed->s->swap_reloca_out) (output_bfd, irel, erel); - } - - ++reldata->count; - - return TRUE; -} - - -/* Get the output vma of the section pointed to by the sh_link field. */ - -static bfd_vma -elf_get_linked_section_vma (struct bfd_link_order *p) -{ - Elf_Internal_Shdr **elf_shdrp; - asection *s; - int elfsec; - - s = p->u.indirect.section; - elf_shdrp = elf_elfsections (s->owner); - elfsec = _bfd_elf_section_from_bfd_section (s->owner, s); - elfsec = elf_shdrp[elfsec]->sh_link; - /* PR 290: - The Intel C compiler generates SHT_IA_64_UNWIND with - SHF_LINK_ORDER. But it doesn't set the sh_link or - sh_info fields. Hence we could get the situation - where elfsec is 0. */ - if (elfsec == 0) - { - const struct elf_backend_data *bed - = get_elf_backend_data (s->owner); - if (bed->link_order_error_handler) - bed->link_order_error_handler - (_("%B: warning: sh_link not set for section `%A'"), s->owner, s); - return 0; - } - else - { - s = elf_shdrp[elfsec]->bfd_section; - return s->output_section->vma + s->output_offset; - } -} - - -/* Compare two sections based on the locations of the sections they are - linked to. Used by elf_fixup_link_order. */ - -static int -compare_link_order (const void * a, const void * b) -{ - bfd_vma apos; - bfd_vma bpos; - - apos = elf_get_linked_section_vma (*(struct bfd_link_order **)a); - bpos = elf_get_linked_section_vma (*(struct bfd_link_order **)b); - if (apos < bpos) - return -1; - return apos > bpos; -} - - -/* Looks for sections with SHF_LINK_ORDER set. Rearranges them into the same - order as their linked sections. Returns false if this could not be done - because an output section includes both ordered and unordered - sections. Ideally we'd do this in the linker proper. */ - -static bfd_boolean -elf_fixup_link_order (bfd *abfd, asection *o) -{ - int seen_linkorder; - int seen_other; - int n; - struct bfd_link_order *p; - bfd *sub; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - unsigned elfsec; - struct bfd_link_order **sections; - asection *s, *other_sec, *linkorder_sec; - bfd_vma offset; - - other_sec = NULL; - linkorder_sec = NULL; - seen_other = 0; - seen_linkorder = 0; - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order) - { - s = p->u.indirect.section; - sub = s->owner; - if (bfd_get_flavour (sub) == bfd_target_elf_flavour - && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass - && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) - && elfsec < elf_numsections (sub) - && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER - && elf_elfsections (sub)[elfsec]->sh_link < elf_numsections (sub)) - { - seen_linkorder++; - linkorder_sec = s; - } - else - { - seen_other++; - other_sec = s; - } - } - else - seen_other++; - - if (seen_other && seen_linkorder) - { - if (other_sec && linkorder_sec) - (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"), - o, linkorder_sec, - linkorder_sec->owner, other_sec, - other_sec->owner); - else - (*_bfd_error_handler) (_("%A has both ordered and unordered sections"), - o); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - } - - if (!seen_linkorder) - return TRUE; - - sections = (struct bfd_link_order **) - bfd_malloc (seen_linkorder * sizeof (struct bfd_link_order *)); - if (sections == NULL) - return FALSE; - seen_linkorder = 0; - - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - sections[seen_linkorder++] = p; - } - /* Sort the input sections in the order of their linked section. */ - qsort (sections, seen_linkorder, sizeof (struct bfd_link_order *), - compare_link_order); - - /* Change the offsets of the sections. */ - offset = 0; - for (n = 0; n < seen_linkorder; n++) - { - s = sections[n]->u.indirect.section; - offset &= ~(bfd_vma) 0 << s->alignment_power; - s->output_offset = offset; - sections[n]->offset = offset; - /* FIXME: octets_per_byte. */ - offset += sections[n]->size; - } - - free (sections); - return TRUE; -} - - -/* Do the final step of an ELF link. */ - -bfd_boolean -bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean dynamic; - bfd_boolean emit_relocs; - bfd *dynobj; - struct elf_final_link_info finfo; - asection *o; - struct bfd_link_order *p; - bfd *sub; - bfd_size_type max_contents_size; - bfd_size_type max_external_reloc_size; - bfd_size_type max_internal_reloc_count; - bfd_size_type max_sym_count; - bfd_size_type max_sym_shndx_count; - file_ptr off; - Elf_Internal_Sym elfsym; - unsigned int i; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symtab_shndx_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_outext_info eoinfo; - bfd_boolean merged; - size_t relativecount = 0; - asection *reldyn = 0; - bfd_size_type amt; - asection *attr_section = NULL; - bfd_vma attr_size = 0; - const char *std_attrs_section; - - if (! is_elf_hash_table (info->hash)) - return FALSE; - - if (info->shared) - abfd->flags |= DYNAMIC; - - dynamic = elf_hash_table (info)->dynamic_sections_created; - dynobj = elf_hash_table (info)->dynobj; - - emit_relocs = (info->relocatable - || info->emitrelocations); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.symstrtab = _bfd_elf_stringtab_init (); - if (finfo.symstrtab == NULL) - return FALSE; - - if (! dynamic) - { - finfo.dynsym_sec = NULL; - finfo.hash_sec = NULL; - finfo.symver_sec = NULL; - } - else - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (finfo.dynsym_sec != NULL); - finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); - /* Note that it is OK if symver_sec is NULL. */ - } - - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - finfo.external_syms = NULL; - finfo.locsym_shndx = NULL; - finfo.internal_syms = NULL; - finfo.indices = NULL; - finfo.sections = NULL; - finfo.symbuf = NULL; - finfo.symshndxbuf = NULL; - finfo.symbuf_count = 0; - finfo.shndxbuf_size = 0; - - /* The object attributes have been merged. Remove the input - sections from the link, and set the contents of the output - secton. */ - std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section; - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0) - || strcmp (o->name, ".gnu.attributes") == 0) - { - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - asection *input_section; - - if (p->type != bfd_indirect_link_order) - continue; - input_section = p->u.indirect.section; - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &= ~SEC_HAS_CONTENTS; - } - - attr_size = bfd_elf_obj_attr_size (abfd); - if (attr_size) - { - bfd_set_section_size (abfd, o, attr_size); - attr_section = o; - /* Skip this section later on. */ - o->map_head.link_order = NULL; - } - else - o->flags |= SEC_EXCLUDE; - } - } - - /* Count up the number of relocations we will output for each output - section, so that we know the sizes of the reloc sections. We - also figure out some maximum sizes. */ - max_contents_size = 0; - max_external_reloc_size = 0; - max_internal_reloc_count = 0; - max_sym_count = 0; - max_sym_shndx_count = 0; - merged = FALSE; - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - o->reloc_count = 0; - - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - unsigned int reloc_count = 0; - struct bfd_elf_section_data *esdi = NULL; - - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - reloc_count = 1; - else if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - esdi = elf_section_data (sec); - - /* Mark all sections which are to be included in the - link. This will normally be every section. We need - to do this so that we can identify any sections which - the linker has decided to not include. */ - sec->linker_mark = TRUE; - - if (sec->flags & SEC_MERGE) - merged = TRUE; - - if (info->relocatable || info->emitrelocations) - reloc_count = sec->reloc_count; - else if (bed->elf_backend_count_relocs) - reloc_count = (*bed->elf_backend_count_relocs) (info, sec); - - if (sec->rawsize > max_contents_size) - max_contents_size = sec->rawsize; - if (sec->size > max_contents_size) - max_contents_size = sec->size; - - /* We are interested in just local symbols, not all - symbols. */ - if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour - && (sec->owner->flags & DYNAMIC) == 0) - { - size_t sym_count; - - if (elf_bad_symtab (sec->owner)) - sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size - / bed->s->sizeof_sym); - else - sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; - - if (sym_count > max_sym_count) - max_sym_count = sym_count; - - if (sym_count > max_sym_shndx_count - && elf_symtab_shndx (sec->owner) != 0) - max_sym_shndx_count = sym_count; - - if ((sec->flags & SEC_RELOC) != 0) - { - size_t ext_size = 0; - - if (esdi->rel.hdr != NULL) - ext_size = esdi->rel.hdr->sh_size; - if (esdi->rela.hdr != NULL) - ext_size += esdi->rela.hdr->sh_size; - - if (ext_size > max_external_reloc_size) - max_external_reloc_size = ext_size; - if (sec->reloc_count > max_internal_reloc_count) - max_internal_reloc_count = sec->reloc_count; - } - } - } - - if (reloc_count == 0) - continue; - - o->reloc_count += reloc_count; - - if (p->type == bfd_indirect_link_order - && (info->relocatable || info->emitrelocations)) - { - if (esdi->rel.hdr) - esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr); - if (esdi->rela.hdr) - esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr); - } - else - { - if (o->use_rela_p) - esdo->rela.count += reloc_count; - else - esdo->rel.count += reloc_count; - } - } - - if (o->reloc_count > 0) - o->flags |= SEC_RELOC; - else - { - /* Explicitly clear the SEC_RELOC flag. The linker tends to - set it (this is probably a bug) and if it is set - assign_section_numbers will create a reloc section. */ - o->flags &=~ SEC_RELOC; - } - - /* If the SEC_ALLOC flag is not set, force the section VMA to - zero. This is done in elf_fake_sections as well, but forcing - the VMA to 0 here will ensure that relocs against these - sections are handled correctly. */ - if ((o->flags & SEC_ALLOC) == 0 - && ! o->user_set_vma) - o->vma = 0; - } - - if (! info->relocatable && merged) - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_link_sec_merge_syms, abfd); - - /* Figure out the file positions for everything but the symbol table - and the relocs. We set symcount to force assign_section_numbers - to create a symbol table. */ - bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1; - BFD_ASSERT (! abfd->output_has_begun); - if (! _bfd_elf_compute_section_file_positions (abfd, info)) - goto error_return; - - /* Set sizes, and assign file positions for reloc sections. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) != 0) - { - if (esdo->rel.hdr - && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel))) - goto error_return; - - if (esdo->rela.hdr - && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela))) - goto error_return; - } - - /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them - to count upwards while actually outputting the relocations. */ - esdo->rel.count = 0; - esdo->rela.count = 0; - } - - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* We have now assigned file positions for all the sections except - .symtab and .strtab. We start the .symtab section at the current - file position, and write directly to it. We build the .strtab - section in memory. */ - bfd_get_symcount (abfd) = 0; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - /* sh_name is set in prep_headers. */ - symtab_hdr->sh_type = SHT_SYMTAB; - /* sh_flags, sh_addr and sh_size all start off zero. */ - symtab_hdr->sh_entsize = bed->s->sizeof_sym; - /* sh_link is set in assign_section_numbers. */ - /* sh_info is set below. */ - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; - - off = elf_tdata (abfd)->next_file_pos; - off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE); - - /* Note that at this point elf_tdata (abfd)->next_file_pos is - incorrect. We do not yet know the size of the .symtab section. - We correct next_file_pos below, after we do know the size. */ - - /* Allocate a buffer to hold swapped out symbols. This is to avoid - continuously seeking to the right position in the file. */ - if (! info->keep_memory || max_sym_count < 20) - finfo.symbuf_size = 20; - else - finfo.symbuf_size = max_sym_count; - amt = finfo.symbuf_size; - amt *= bed->s->sizeof_sym; - finfo.symbuf = (bfd_byte *) bfd_malloc (amt); - if (finfo.symbuf == NULL) - goto error_return; - if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) - { - /* Wild guess at number of output symbols. realloc'd as needed. */ - amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; - finfo.shndxbuf_size = amt; - amt *= sizeof (Elf_External_Sym_Shndx); - finfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt); - if (finfo.symshndxbuf == NULL) - goto error_return; - } - - /* Start writing out the symbol table. The first symbol is always a - dummy symbol. */ - if (info->strip != strip_all - || emit_relocs) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = 0; - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - elfsym.st_target_internal = 0; - if (elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr, - NULL) != 1) - goto error_return; - } - - /* Output a symbol for each section. We output these even if we are - discarding local symbols, since they are used for relocs. These - symbols have no names. We store the index of each one in the - index field of the section, so that we can find it again when - outputting relocs. */ - if (info->strip != strip_all - || emit_relocs) - { - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - elfsym.st_other = 0; - elfsym.st_value = 0; - elfsym.st_target_internal = 0; - for (i = 1; i < elf_numsections (abfd); i++) - { - o = bfd_section_from_elf_index (abfd, i); - if (o != NULL) - { - o->target_index = bfd_get_symcount (abfd); - elfsym.st_shndx = i; - if (!info->relocatable) - elfsym.st_value = o->vma; - if (elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL) != 1) - goto error_return; - } - } - } - - /* Allocate some memory to hold information read in from the input - files. */ - if (max_contents_size != 0) - { - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - if (finfo.contents == NULL) - goto error_return; - } - - if (max_external_reloc_size != 0) - { - finfo.external_relocs = bfd_malloc (max_external_reloc_size); - if (finfo.external_relocs == NULL) - goto error_return; - } - - if (max_internal_reloc_count != 0) - { - amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; - amt *= sizeof (Elf_Internal_Rela); - finfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt); - if (finfo.internal_relocs == NULL) - goto error_return; - } - - if (max_sym_count != 0) - { - amt = max_sym_count * bed->s->sizeof_sym; - finfo.external_syms = (bfd_byte *) bfd_malloc (amt); - if (finfo.external_syms == NULL) - goto error_return; - - amt = max_sym_count * sizeof (Elf_Internal_Sym); - finfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt); - if (finfo.internal_syms == NULL) - goto error_return; - - amt = max_sym_count * sizeof (long); - finfo.indices = (long int *) bfd_malloc (amt); - if (finfo.indices == NULL) - goto error_return; - - amt = max_sym_count * sizeof (asection *); - finfo.sections = (asection **) bfd_malloc (amt); - if (finfo.sections == NULL) - goto error_return; - } - - if (max_sym_shndx_count != 0) - { - amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); - finfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); - if (finfo.locsym_shndx == NULL) - goto error_return; - } - - if (elf_hash_table (info)->tls_sec) - { - bfd_vma base, end = 0; - asection *sec; - - for (sec = elf_hash_table (info)->tls_sec; - sec && (sec->flags & SEC_THREAD_LOCAL); - sec = sec->next) - { - bfd_size_type size = sec->size; - - if (size == 0 - && (sec->flags & SEC_HAS_CONTENTS) == 0) - { - struct bfd_link_order *ord = sec->map_tail.link_order; - - if (ord != NULL) - size = ord->offset + ord->size; - } - end = sec->vma + size; - } - base = elf_hash_table (info)->tls_sec->vma; - /* Only align end of TLS section if static TLS doesn't have special - alignment requirements. */ - if (bed->static_tls_alignment == 1) - end = align_power (end, - elf_hash_table (info)->tls_sec->alignment_power); - elf_hash_table (info)->tls_size = end - base; - } - - /* Reorder SHF_LINK_ORDER sections. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if (!elf_fixup_link_order (abfd, o)) - return FALSE; - } - - /* Since ELF permits relocations to be against local symbols, we - must have the local symbols available when we do the relocations. - Since we would rather only read the local symbols once, and we - would rather not keep them in memory, we handle all the - relocations for a single input file at the same time. - - Unfortunately, there is no way to know the total number of local - symbols until we have seen all of them, and the local symbol - indices precede the global symbol indices. This means that when - we are generating relocatable output, and we see a reloc against - a global symbol, we can not know the symbol index until we have - finished examining all the local symbols to see which ones we are - going to output. To deal with this, we keep the relocations in - memory, and don't output them until the end of the link. This is - an unfortunate waste of memory, but I don't see a good way around - it. Fortunately, it only happens when performing a relocatable - link, which is not the common case. FIXME: If keep_memory is set - we could write the relocs out and then read them again; I don't - know how bad the memory loss will be. */ - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - sub->output_has_begun = FALSE; - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) - == bfd_target_elf_flavour) - && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) - { - if (! sub->output_has_begun) - { - if (! elf_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = TRUE; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! elf_reloc_link_order (abfd, info, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (sub) - == bfd_target_elf_flavour) - && (elf_elfheader (sub)->e_ident[EI_CLASS] - != bed->s->elfclass)) - { - const char *iclass, *oclass; - - if (bed->s->elfclass == ELFCLASS64) - { - iclass = "ELFCLASS32"; - oclass = "ELFCLASS64"; - } - else - { - iclass = "ELFCLASS64"; - oclass = "ELFCLASS32"; - } - - bfd_set_error (bfd_error_wrong_format); - (*_bfd_error_handler) - (_("%B: file class %s incompatible with %s"), - sub, iclass, oclass); - } - - goto error_return; - } - } - } - } - - /* Free symbol buffer if needed. */ - if (!info->reduce_memory_overheads) - { - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - if (bfd_get_flavour (sub) == bfd_target_elf_flavour - && elf_tdata (sub)->symbuf) - { - free (elf_tdata (sub)->symbuf); - elf_tdata (sub)->symbuf = NULL; - } - } - - /* Output any global symbols that got converted to local in a - version script or due to symbol visibility. We do this in a - separate step since ELF requires all local symbols to appear - prior to any global symbols. FIXME: We should only do this if - some global symbols were, in fact, converted to become local. - FIXME: Will this work correctly with the Irix 5 linker? */ - eoinfo.failed = FALSE; - eoinfo.finfo = &finfo; - eoinfo.localsyms = TRUE; - bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); - if (eoinfo.failed) - return FALSE; - - /* If backend needs to output some local symbols not present in the hash - table, do it now. */ - if (bed->elf_backend_output_arch_local_syms) - { - typedef int (*out_sym_func) - (void *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); - - if (! ((*bed->elf_backend_output_arch_local_syms) - (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) - return FALSE; - } - - /* That wrote out all the local symbols. Finish up the symbol table - with the global symbols. Even if we want to strip everything we - can, we still need to deal with those global symbols that got - converted to local in a version script. */ - - /* The sh_info field records the index of the first non local symbol. */ - symtab_hdr->sh_info = bfd_get_symcount (abfd); - - if (dynamic - && finfo.dynsym_sec->output_section != bfd_abs_section_ptr) - { - Elf_Internal_Sym sym; - bfd_byte *dynsym = finfo.dynsym_sec->contents; - long last_local = 0; - - /* Write out the section symbols for the output sections. */ - if (info->shared || elf_hash_table (info)->is_relocatable_executable) - { - asection *s; - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - sym.st_target_internal = 0; - - for (s = abfd->sections; s != NULL; s = s->next) - { - int indx; - bfd_byte *dest; - long dynindx; - - dynindx = elf_section_data (s)->dynindx; - if (dynindx <= 0) - continue; - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - if (! check_dynsym (abfd, &sym)) - return FALSE; - sym.st_value = s->vma; - dest = dynsym + dynindx * bed->s->sizeof_sym; - if (last_local < dynindx) - last_local = dynindx; - bed->s->swap_symbol_out (abfd, &sym, dest, 0); - } - } - - /* Write out the local dynsyms. */ - if (elf_hash_table (info)->dynlocal) - { - struct elf_link_local_dynamic_entry *e; - for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) - { - asection *s; - bfd_byte *dest; - - /* Copy the internal symbol and turn off visibility. - Note that we saved a word of storage and overwrote - the original st_name with the dynstr_index. */ - sym = e->isym; - sym.st_other &= ~ELF_ST_VISIBILITY (-1); - - s = bfd_section_from_elf_index (e->input_bfd, - e->isym.st_shndx); - if (s != NULL) - { - sym.st_shndx = - elf_section_data (s->output_section)->this_idx; - if (! check_dynsym (abfd, &sym)) - return FALSE; - sym.st_value = (s->output_section->vma - + s->output_offset - + e->isym.st_value); - } - - if (last_local < e->dynindx) - last_local = e->dynindx; - - dest = dynsym + e->dynindx * bed->s->sizeof_sym; - bed->s->swap_symbol_out (abfd, &sym, dest, 0); - } - } - - elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = - last_local + 1; - } - - /* We get the global symbols from the hash table. */ - eoinfo.failed = FALSE; - eoinfo.localsyms = FALSE; - eoinfo.finfo = &finfo; - bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); - if (eoinfo.failed) - return FALSE; - - /* If backend needs to output some symbols not present in the hash - table, do it now. */ - if (bed->elf_backend_output_arch_syms) - { - typedef int (*out_sym_func) - (void *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); - - if (! ((*bed->elf_backend_output_arch_syms) - (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) - return FALSE; - } - - /* Flush all symbols to the file. */ - if (! elf_link_flush_output_syms (&finfo, bed)) - return FALSE; - - /* Now we know the size of the symtab section. */ - off += symtab_hdr->sh_size; - - symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; - if (symtab_shndx_hdr->sh_name != 0) - { - symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; - symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); - symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); - amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); - symtab_shndx_hdr->sh_size = amt; - - off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, - off, TRUE); - - if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt)) - return FALSE; - } - - - /* Finish up and write out the symbol string table (.strtab) - section. */ - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - /* sh_name was set in prep_headers. */ - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - /* sh_offset is set just below. */ - symstrtab_hdr->sh_addralign = 1; - - off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); - elf_tdata (abfd)->next_file_pos = off; - - if (bfd_get_symcount (abfd) > 0) - { - if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) - return FALSE; - } - - /* Adjust the relocs to have the correct symbol indices. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) == 0) - continue; - - if (esdo->rel.hdr != NULL) - elf_link_adjust_relocs (abfd, &esdo->rel); - if (esdo->rela.hdr != NULL) - elf_link_adjust_relocs (abfd, &esdo->rela); - - /* Set the reloc_count field to 0 to prevent write_relocs from - trying to swap the relocs out itself. */ - o->reloc_count = 0; - } - - if (dynamic && info->combreloc && dynobj != NULL) - relativecount = elf_link_sort_relocs (abfd, info, &reldyn); - - /* If we are linking against a dynamic object, or generating a - shared library, finish up the dynamic linking information. */ - if (dynamic) - { - bfd_byte *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = o->contents; - dynconend = o->contents + o->size; - for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - bed->s->swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - continue; - case DT_NULL: - if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend) - { - switch (elf_section_data (reldyn)->this_hdr.sh_type) - { - case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; - case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; - default: continue; - } - dyn.d_un.d_val = relativecount; - relativecount = 0; - break; - } - continue; - - case DT_INIT: - name = info->init_function; - goto get_sym; - case DT_FINI: - name = info->fini_function; - get_sym: - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), name, - FALSE, FALSE, TRUE); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - dyn.d_un.d_ptr = h->root.u.def.value; - o = h->root.u.def.section; - if (o->output_section != NULL) - dyn.d_un.d_ptr += (o->output_section->vma - + o->output_offset); - else - { - /* The symbol is imported from another shared - library and does not apply to this one. */ - dyn.d_un.d_ptr = 0; - } - break; - } - } - continue; - - case DT_PREINIT_ARRAYSZ: - name = ".preinit_array"; - goto get_size; - case DT_INIT_ARRAYSZ: - name = ".init_array"; - goto get_size; - case DT_FINI_ARRAYSZ: - name = ".fini_array"; - get_size: - o = bfd_get_section_by_name (abfd, name); - if (o == NULL) - { - (*_bfd_error_handler) - (_("%B: could not find output section %s"), abfd, name); - goto error_return; - } - if (o->size == 0) - (*_bfd_error_handler) - (_("warning: %s section has zero size"), name); - dyn.d_un.d_val = o->size; - break; - - case DT_PREINIT_ARRAY: - name = ".preinit_array"; - goto get_vma; - case DT_INIT_ARRAY: - name = ".init_array"; - goto get_vma; - case DT_FINI_ARRAY: - name = ".fini_array"; - goto get_vma; - - case DT_HASH: - name = ".hash"; - goto get_vma; - case DT_GNU_HASH: - name = ".gnu.hash"; - goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; - case DT_SYMTAB: - name = ".dynsym"; - goto get_vma; - case DT_VERDEF: - name = ".gnu.version_d"; - goto get_vma; - case DT_VERNEED: - name = ".gnu.version_r"; - goto get_vma; - case DT_VERSYM: - name = ".gnu.version"; - get_vma: - o = bfd_get_section_by_name (abfd, name); - if (o == NULL) - { - (*_bfd_error_handler) - (_("%B: could not find output section %s"), abfd, name); - goto error_return; - } - if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE) - { - (*_bfd_error_handler) - (_("warning: section '%s' is being made into a note"), name); - bfd_set_error (bfd_error_nonrepresentable_section); - goto error_return; - } - dyn.d_un.d_ptr = o->vma; - break; - - case DT_REL: - case DT_RELA: - case DT_RELSZ: - case DT_RELASZ: - if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) - type = SHT_REL; - else - type = SHT_RELA; - dyn.d_un.d_val = 0; - dyn.d_un.d_ptr = 0; - for (i = 1; i < elf_numsections (abfd); i++) - { - Elf_Internal_Shdr *hdr; - - hdr = elf_elfsections (abfd)[i]; - if (hdr->sh_type == type - && (hdr->sh_flags & SHF_ALLOC) != 0) - { - if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) - dyn.d_un.d_val += hdr->sh_size; - else - { - if (dyn.d_un.d_ptr == 0 - || hdr->sh_addr < dyn.d_un.d_ptr) - dyn.d_un.d_ptr = hdr->sh_addr; - } - } - } - break; - } - bed->s->swap_dyn_out (dynobj, &dyn, dyncon); - } - } - - /* If we have created any dynamic sections, then output them. */ - if (dynobj != NULL) - { - if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) - goto error_return; - - /* Check for DT_TEXTREL (late, in case the backend removes it). */ - if ((info->warn_shared_textrel && info->shared) - || info->error_textrel) - { - bfd_byte *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = o->contents; - dynconend = o->contents + o->size; - for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - - bed->s->swap_dyn_in (dynobj, dyncon, &dyn); - - if (dyn.d_tag == DT_TEXTREL) - { - if (info->error_textrel) - info->callbacks->einfo - (_("%P%X: read-only segment has dynamic relocations.\n")); - else - info->callbacks->einfo - (_("%P: warning: creating a DT_TEXTREL in a shared object.\n")); - break; - } - } - } - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->size == 0 - || o->output_section == bfd_abs_section_ptr) - continue; - if ((o->flags & SEC_LINKER_CREATED) == 0) - { - /* At this point, we are only interested in sections - created by _bfd_elf_link_create_dynamic_sections. */ - continue; - } - if (elf_hash_table (info)->stab_info.stabstr == o) - continue; - if (elf_hash_table (info)->eh_info.hdr_sec == o) - continue; - if ((elf_section_data (o->output_section)->this_hdr.sh_type - != SHT_STRTAB) - && (strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)) - { - /* FIXME: octets_per_byte. */ - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, - (file_ptr) o->output_offset, - o->size)) - goto error_return; - } - else - { - /* The contents of the .dynstr section are actually in a - stringtab. */ - off = elf_section_data (o->output_section)->this_hdr.sh_offset; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || ! _bfd_elf_strtab_emit (abfd, - elf_hash_table (info)->dynstr)) - goto error_return; - } - } - } - - if (info->relocatable) - { - bfd_boolean failed = FALSE; - - bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); - if (failed) - goto error_return; - } - - /* If we have optimized stabs strings, output them. */ - if (elf_hash_table (info)->stab_info.stabstr != NULL) - { - if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) - goto error_return; - } - - if (info->eh_frame_hdr) - { - if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) - goto error_return; - } - - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.locsym_shndx != NULL) - free (finfo.locsym_shndx); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - if (finfo.symshndxbuf != NULL) - free (finfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL) - free (esdo->rel.hashes); - if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL) - free (esdo->rela.hashes); - } - - elf_tdata (abfd)->linker = TRUE; - - if (attr_section) - { - bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size); - if (contents == NULL) - return FALSE; /* Bail out and fail. */ - bfd_elf_set_obj_attr_contents (abfd, contents, attr_size); - bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size); - free (contents); - } - - return TRUE; - - error_return: - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.locsym_shndx != NULL) - free (finfo.locsym_shndx); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - if (finfo.symshndxbuf != NULL) - free (finfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL) - free (esdo->rel.hashes); - if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL) - free (esdo->rela.hashes); - } - - return FALSE; -} - -/* Initialize COOKIE for input bfd ABFD. */ - -static bfd_boolean -init_reloc_cookie (struct elf_reloc_cookie *cookie, - struct bfd_link_info *info, bfd *abfd) -{ - Elf_Internal_Shdr *symtab_hdr; - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (abfd); - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - - cookie->abfd = abfd; - cookie->sym_hashes = elf_sym_hashes (abfd); - cookie->bad_symtab = elf_bad_symtab (abfd); - if (cookie->bad_symtab) - { - cookie->locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - cookie->extsymoff = 0; - } - else - { - cookie->locsymcount = symtab_hdr->sh_info; - cookie->extsymoff = symtab_hdr->sh_info; - } - - if (bed->s->arch_size == 32) - cookie->r_sym_shift = 8; - else - cookie->r_sym_shift = 32; - - cookie->locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; - if (cookie->locsyms == NULL && cookie->locsymcount != 0) - { - cookie->locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, - cookie->locsymcount, 0, - NULL, NULL, NULL); - if (cookie->locsyms == NULL) - { - info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); - return FALSE; - } - if (info->keep_memory) - symtab_hdr->contents = (bfd_byte *) cookie->locsyms; - } - return TRUE; -} - -/* Free the memory allocated by init_reloc_cookie, if appropriate. */ - -static void -fini_reloc_cookie (struct elf_reloc_cookie *cookie, bfd *abfd) -{ - Elf_Internal_Shdr *symtab_hdr; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - if (cookie->locsyms != NULL - && symtab_hdr->contents != (unsigned char *) cookie->locsyms) - free (cookie->locsyms); -} - -/* Initialize the relocation information in COOKIE for input section SEC - of input bfd ABFD. */ - -static bfd_boolean -init_reloc_cookie_rels (struct elf_reloc_cookie *cookie, - struct bfd_link_info *info, bfd *abfd, - asection *sec) -{ - const struct elf_backend_data *bed; - - if (sec->reloc_count == 0) - { - cookie->rels = NULL; - cookie->relend = NULL; - } - else - { - bed = get_elf_backend_data (abfd); - - cookie->rels = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, - info->keep_memory); - if (cookie->rels == NULL) - return FALSE; - cookie->rel = cookie->rels; - cookie->relend = (cookie->rels - + sec->reloc_count * bed->s->int_rels_per_ext_rel); - } - cookie->rel = cookie->rels; - return TRUE; -} - -/* Free the memory allocated by init_reloc_cookie_rels, - if appropriate. */ - -static void -fini_reloc_cookie_rels (struct elf_reloc_cookie *cookie, - asection *sec) -{ - if (cookie->rels && elf_section_data (sec)->relocs != cookie->rels) - free (cookie->rels); -} - -/* Initialize the whole of COOKIE for input section SEC. */ - -static bfd_boolean -init_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, - struct bfd_link_info *info, - asection *sec) -{ - if (!init_reloc_cookie (cookie, info, sec->owner)) - goto error1; - if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec)) - goto error2; - return TRUE; - - error2: - fini_reloc_cookie (cookie, sec->owner); - error1: - return FALSE; -} - -/* Free the memory allocated by init_reloc_cookie_for_section, - if appropriate. */ - -static void -fini_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, - asection *sec) -{ - fini_reloc_cookie_rels (cookie, sec); - fini_reloc_cookie (cookie, sec->owner); -} - -/* Garbage collect unused sections. */ - -/* Default gc_mark_hook. */ - -asection * -_bfd_elf_gc_mark_hook (asection *sec, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h, - Elf_Internal_Sym *sym) -{ - const char *sec_name; - - if (h != NULL) - { - switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->root.u.def.section; - - case bfd_link_hash_common: - return h->root.u.c.p->section; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - /* To work around a glibc bug, keep all XXX input sections - when there is an as yet undefined reference to __start_XXX - or __stop_XXX symbols. The linker will later define such - symbols for orphan input sections that have a name - representable as a C identifier. */ - if (strncmp (h->root.root.string, "__start_", 8) == 0) - sec_name = h->root.root.string + 8; - else if (strncmp (h->root.root.string, "__stop_", 7) == 0) - sec_name = h->root.root.string + 7; - else - sec_name = NULL; - - if (sec_name && *sec_name != '\0') - { - bfd *i; - - for (i = info->input_bfds; i; i = i->link_next) - { - sec = bfd_get_section_by_name (i, sec_name); - if (sec) - sec->flags |= SEC_KEEP; - } - } - break; - - default: - break; - } - } - else - return bfd_section_from_elf_index (sec->owner, sym->st_shndx); - - return NULL; -} - -/* COOKIE->rel describes a relocation against section SEC, which is - a section we've decided to keep. Return the section that contains - the relocation symbol, or NULL if no section contains it. */ - -asection * -_bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec, - elf_gc_mark_hook_fn gc_mark_hook, - struct elf_reloc_cookie *cookie) -{ - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = cookie->rel->r_info >> cookie->r_sym_shift; - if (r_symndx == STN_UNDEF) - return NULL; - - if (r_symndx >= cookie->locsymcount - || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) - { - h = cookie->sym_hashes[r_symndx - cookie->extsymoff]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL); - } - - return (*gc_mark_hook) (sec, info, cookie->rel, NULL, - &cookie->locsyms[r_symndx]); -} - -/* COOKIE->rel describes a relocation against section SEC, which is - a section we've decided to keep. Mark the section that contains - the relocation symbol. */ - -bfd_boolean -_bfd_elf_gc_mark_reloc (struct bfd_link_info *info, - asection *sec, - elf_gc_mark_hook_fn gc_mark_hook, - struct elf_reloc_cookie *cookie) -{ - asection *rsec; - - rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie); - if (rsec && !rsec->gc_mark) - { - if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) - rsec->gc_mark = 1; - else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) - return FALSE; - } - return TRUE; -} - -/* The mark phase of garbage collection. For a given section, mark - it and any sections in this section's group, and all the sections - which define symbols to which it refers. */ - -bfd_boolean -_bfd_elf_gc_mark (struct bfd_link_info *info, - asection *sec, - elf_gc_mark_hook_fn gc_mark_hook) -{ - bfd_boolean ret; - asection *group_sec, *eh_frame; - - sec->gc_mark = 1; - - /* Mark all the sections in the group. */ - group_sec = elf_section_data (sec)->next_in_group; - if (group_sec && !group_sec->gc_mark) - if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook)) - return FALSE; - - /* Look through the section relocs. */ - ret = TRUE; - eh_frame = elf_eh_frame_section (sec->owner); - if ((sec->flags & SEC_RELOC) != 0 - && sec->reloc_count > 0 - && sec != eh_frame) - { - struct elf_reloc_cookie cookie; - - if (!init_reloc_cookie_for_section (&cookie, info, sec)) - ret = FALSE; - else - { - for (; cookie.rel < cookie.relend; cookie.rel++) - if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, &cookie)) - { - ret = FALSE; - break; - } - fini_reloc_cookie_for_section (&cookie, sec); - } - } - - if (ret && eh_frame && elf_fde_list (sec)) - { - struct elf_reloc_cookie cookie; - - if (!init_reloc_cookie_for_section (&cookie, info, eh_frame)) - ret = FALSE; - else - { - if (!_bfd_elf_gc_mark_fdes (info, sec, eh_frame, - gc_mark_hook, &cookie)) - ret = FALSE; - fini_reloc_cookie_for_section (&cookie, eh_frame); - } - } - - return ret; -} - -/* Keep debug and special sections. */ - -bfd_boolean -_bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, - elf_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED) -{ - bfd *ibfd; - - for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) - { - asection *isec; - bfd_boolean some_kept; - - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) - continue; - - /* Ensure all linker created sections are kept, and see whether - any other section is already marked. */ - some_kept = FALSE; - for (isec = ibfd->sections; isec != NULL; isec = isec->next) - { - if ((isec->flags & SEC_LINKER_CREATED) != 0) - isec->gc_mark = 1; - else if (isec->gc_mark) - some_kept = TRUE; - } - - /* If no section in this file will be kept, then we can - toss out debug sections. */ - if (!some_kept) - continue; - - /* Keep debug and special sections like .comment when they are - not part of a group, or when we have single-member groups. */ - for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if ((elf_next_in_group (isec) == NULL - || elf_next_in_group (isec) == isec) - && ((isec->flags & SEC_DEBUGGING) != 0 - || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) - isec->gc_mark = 1; - } - return TRUE; -} - -/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ - -struct elf_gc_sweep_symbol_info -{ - struct bfd_link_info *info; - void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *, - bfd_boolean); -}; - -static bfd_boolean -elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data) -{ - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && !h->root.u.def.section->gc_mark - && !(h->root.u.def.section->owner->flags & DYNAMIC)) - { - struct elf_gc_sweep_symbol_info *inf = - (struct elf_gc_sweep_symbol_info *) data; - (*inf->hide_symbol) (inf->info, h, TRUE); - } - - return TRUE; -} - -/* The sweep phase of garbage collection. Remove all garbage sections. */ - -typedef bfd_boolean (*gc_sweep_hook_fn) - (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); - -static bfd_boolean -elf_gc_sweep (bfd *abfd, struct bfd_link_info *info) -{ - bfd *sub; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook; - unsigned long section_sym_count; - struct elf_gc_sweep_symbol_info sweep_info; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - if (bfd_get_flavour (sub) != bfd_target_elf_flavour) - continue; - - for (o = sub->sections; o != NULL; o = o->next) - { - /* When any section in a section group is kept, we keep all - sections in the section group. If the first member of - the section group is excluded, we will also exclude the - group section. */ - if (o->flags & SEC_GROUP) - { - asection *first = elf_next_in_group (o); - o->gc_mark = first->gc_mark; - } - - if (o->gc_mark) - continue; - - /* Skip sweeping sections already excluded. */ - if (o->flags & SEC_EXCLUDE) - continue; - - /* Since this is early in the link process, it is simple - to remove a section from the output. */ - o->flags |= SEC_EXCLUDE; - - if (info->print_gc_sections && o->size != 0) - _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name); - - /* But we also have to update some of the relocation - info we collected before. */ - if (gc_sweep_hook - && (o->flags & SEC_RELOC) != 0 - && o->reloc_count > 0 - && !bfd_is_abs_section (o->output_section)) - { - Elf_Internal_Rela *internal_relocs; - bfd_boolean r; - - internal_relocs - = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL, - info->keep_memory); - if (internal_relocs == NULL) - return FALSE; - - r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); - - if (elf_section_data (o)->relocs != internal_relocs) - free (internal_relocs); - - if (!r) - return FALSE; - } - } - } - - /* Remove the symbols that were in the swept sections from the dynamic - symbol table. GCFIXME: Anyone know how to get them out of the - static symbol table as well? */ - sweep_info.info = info; - sweep_info.hide_symbol = bed->elf_backend_hide_symbol; - elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, - &sweep_info); - - _bfd_elf_link_renumber_dynsyms (abfd, info, §ion_sym_count); - return TRUE; -} - -/* Propagate collected vtable information. This is called through - elf_link_hash_traverse. */ - -static bfd_boolean -elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) -{ - /* Those that are not vtables. */ - if (h->vtable == NULL || h->vtable->parent == NULL) - return TRUE; - - /* Those vtables that do not have parents, we cannot merge. */ - if (h->vtable->parent == (struct elf_link_hash_entry *) -1) - return TRUE; - - /* If we've already been done, exit. */ - if (h->vtable->used && h->vtable->used[-1]) - return TRUE; - - /* Make sure the parent's table is up to date. */ - elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp); - - if (h->vtable->used == NULL) - { - /* None of this table's entries were referenced. Re-use the - parent's table. */ - h->vtable->used = h->vtable->parent->vtable->used; - h->vtable->size = h->vtable->parent->vtable->size; - } - else - { - size_t n; - bfd_boolean *cu, *pu; - - /* Or the parent's entries into ours. */ - cu = h->vtable->used; - cu[-1] = TRUE; - pu = h->vtable->parent->vtable->used; - if (pu != NULL) - { - const struct elf_backend_data *bed; - unsigned int log_file_align; - - bed = get_elf_backend_data (h->root.u.def.section->owner); - log_file_align = bed->s->log_file_align; - n = h->vtable->parent->vtable->size >> log_file_align; - while (n--) - { - if (*pu) - *cu = TRUE; - pu++; - cu++; - } - } - } - - return TRUE; -} - -static bfd_boolean -elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) -{ - asection *sec; - bfd_vma hstart, hend; - Elf_Internal_Rela *relstart, *relend, *rel; - const struct elf_backend_data *bed; - unsigned int log_file_align; - - /* Take care of both those symbols that do not describe vtables as - well as those that are not loaded. */ - if (h->vtable == NULL || h->vtable->parent == NULL) - return TRUE; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - - sec = h->root.u.def.section; - hstart = h->root.u.def.value; - hend = hstart + h->size; - - relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE); - if (!relstart) - return *(bfd_boolean *) okp = FALSE; - bed = get_elf_backend_data (sec->owner); - log_file_align = bed->s->log_file_align; - - relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; - - for (rel = relstart; rel < relend; ++rel) - if (rel->r_offset >= hstart && rel->r_offset < hend) - { - /* If the entry is in use, do nothing. */ - if (h->vtable->used - && (rel->r_offset - hstart) < h->vtable->size) - { - bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; - if (h->vtable->used[entry]) - continue; - } - /* Otherwise, kill it. */ - rel->r_offset = rel->r_info = rel->r_addend = 0; - } - - return TRUE; -} - -/* Mark sections containing dynamically referenced symbols. When - building shared libraries, we must assume that any visible symbol is - referenced. */ - -bfd_boolean -bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) -{ - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->ref_dynamic - || ((!info->executable || info->export_dynamic) - && h->def_regular - && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL - && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN - && (strchr (h->root.root.string, ELF_VER_CHR) != NULL - || !bfd_hide_sym_by_version (info->version_info, - h->root.root.string))))) - h->root.u.def.section->flags |= SEC_KEEP; - - return TRUE; -} - -/* Keep all sections containing symbols undefined on the command-line, - and the section containing the entry symbol. */ - -void -_bfd_elf_gc_keep (struct bfd_link_info *info) -{ - struct bfd_sym_chain *sym; - - for (sym = info->gc_sym_list; sym != NULL; sym = sym->next) - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), sym->name, - FALSE, FALSE, FALSE); - - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && !bfd_is_abs_section (h->root.u.def.section)) - h->root.u.def.section->flags |= SEC_KEEP; - } -} - -/* Do mark and sweep of unused sections. */ - -bfd_boolean -bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean ok = TRUE; - bfd *sub; - elf_gc_mark_hook_fn gc_mark_hook; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (!bed->can_gc_sections - || !is_elf_hash_table (info->hash)) - { - (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); - return TRUE; - } - - bed->gc_keep (info); - - /* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section - at the .eh_frame section if we can mark the FDEs individually. */ - _bfd_elf_begin_eh_frame_parsing (info); - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *sec; - struct elf_reloc_cookie cookie; - - sec = bfd_get_section_by_name (sub, ".eh_frame"); - if (sec && init_reloc_cookie_for_section (&cookie, info, sec)) - { - _bfd_elf_parse_eh_frame (sub, info, sec, &cookie); - if (elf_section_data (sec)->sec_info) - elf_eh_frame_section (sub) = sec; - fini_reloc_cookie_for_section (&cookie, sec); - } - } - _bfd_elf_end_eh_frame_parsing (info); - - /* Apply transitive closure to the vtable entry usage info. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_propagate_vtable_entries_used, - &ok); - if (!ok) - return FALSE; - - /* Kill the vtable relocations that were not used. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_smash_unused_vtentry_relocs, - &ok); - if (!ok) - return FALSE; - - /* Mark dynamically referenced symbols. */ - if (elf_hash_table (info)->dynamic_sections_created) - elf_link_hash_traverse (elf_hash_table (info), - bed->gc_mark_dynamic_ref, - info); - - /* Grovel through relocs to find out who stays ... */ - gc_mark_hook = bed->gc_mark_hook; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - if (bfd_get_flavour (sub) != bfd_target_elf_flavour) - continue; - - /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep). - Also treat note sections as a root, if the section is not part - of a group. */ - for (o = sub->sections; o != NULL; o = o->next) - if (!o->gc_mark - && (o->flags & SEC_EXCLUDE) == 0 - && ((o->flags & SEC_KEEP) != 0 - || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE - && elf_next_in_group (o) == NULL ))) - { - if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) - return FALSE; - } - } - - /* Allow the backend to mark additional target specific sections. */ - bed->gc_mark_extra_sections (info, gc_mark_hook); - - /* ... and mark SEC_EXCLUDE for those that go. */ - return elf_gc_sweep (abfd, info); -} - -/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ - -bfd_boolean -bfd_elf_gc_record_vtinherit (bfd *abfd, - asection *sec, - struct elf_link_hash_entry *h, - bfd_vma offset) -{ - struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; - struct elf_link_hash_entry **search, *child; - bfd_size_type extsymcount; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; - if (!elf_bad_symtab (abfd)) - extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; - - sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + extsymcount; - - /* Hunt down the child symbol, which is in this section at the same - offset as the relocation. */ - for (search = sym_hashes; search != sym_hashes_end; ++search) - { - if ((child = *search) != NULL - && (child->root.type == bfd_link_hash_defined - || child->root.type == bfd_link_hash_defweak) - && child->root.u.def.section == sec - && child->root.u.def.value == offset) - goto win; - } - - (*_bfd_error_handler) ("%B: %A+%lu: No symbol found for INHERIT", - abfd, sec, (unsigned long) offset); - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - - win: - if (!child->vtable) - { - child->vtable = (struct elf_link_virtual_table_entry *) - bfd_zalloc (abfd, sizeof (*child->vtable)); - if (!child->vtable) - return FALSE; - } - if (!h) - { - /* This *should* only be the absolute section. It could potentially - be that someone has defined a non-global vtable though, which - would be bad. It isn't worth paging in the local symbols to be - sure though; that case should simply be handled by the assembler. */ - - child->vtable->parent = (struct elf_link_hash_entry *) -1; - } - else - child->vtable->parent = h; - - return TRUE; -} - -/* Called from check_relocs to record the existence of a VTENTRY reloc. */ - -bfd_boolean -bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h, - bfd_vma addend) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - unsigned int log_file_align = bed->s->log_file_align; - - if (!h->vtable) - { - h->vtable = (struct elf_link_virtual_table_entry *) - bfd_zalloc (abfd, sizeof (*h->vtable)); - if (!h->vtable) - return FALSE; - } - - if (addend >= h->vtable->size) - { - size_t size, bytes, file_align; - bfd_boolean *ptr = h->vtable->used; - - /* While the symbol is undefined, we have to be prepared to handle - a zero size. */ - file_align = 1 << log_file_align; - if (h->root.type == bfd_link_hash_undefined) - size = addend + file_align; - else - { - size = h->size; - if (addend >= size) - { - /* Oops! We've got a reference past the defined end of - the table. This is probably a bug -- shall we warn? */ - size = addend + file_align; - } - } - size = (size + file_align - 1) & -file_align; - - /* Allocate one extra entry for use as a "done" flag for the - consolidation pass. */ - bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean); - - if (ptr) - { - ptr = (bfd_boolean *) bfd_realloc (ptr - 1, bytes); - - if (ptr != NULL) - { - size_t oldbytes; - - oldbytes = (((h->vtable->size >> log_file_align) + 1) - * sizeof (bfd_boolean)); - memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); - } - } - else - ptr = (bfd_boolean *) bfd_zmalloc (bytes); - - if (ptr == NULL) - return FALSE; - - /* And arrange for that done flag to be at index -1. */ - h->vtable->used = ptr + 1; - h->vtable->size = size; - } - - h->vtable->used[addend >> log_file_align] = TRUE; - - return TRUE; -} - -/* Map an ELF section header flag to its corresponding string. */ -typedef struct -{ - char *flag_name; - flagword flag_value; -} elf_flags_to_name_table; - -static elf_flags_to_name_table elf_flags_to_names [] = -{ - { "SHF_WRITE", SHF_WRITE }, - { "SHF_ALLOC", SHF_ALLOC }, - { "SHF_EXECINSTR", SHF_EXECINSTR }, - { "SHF_MERGE", SHF_MERGE }, - { "SHF_STRINGS", SHF_STRINGS }, - { "SHF_INFO_LINK", SHF_INFO_LINK}, - { "SHF_LINK_ORDER", SHF_LINK_ORDER}, - { "SHF_OS_NONCONFORMING", SHF_OS_NONCONFORMING}, - { "SHF_GROUP", SHF_GROUP }, - { "SHF_TLS", SHF_TLS }, - { "SHF_MASKOS", SHF_MASKOS }, - { "SHF_EXCLUDE", SHF_EXCLUDE }, -}; - -void -bfd_elf_lookup_section_flags (struct bfd_link_info *info, - struct flag_info *finfo) -{ - bfd *output_bfd = info->output_bfd; - const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - struct flag_info_list *tf = finfo->flag_list; - int with_hex = 0; - int without_hex = 0; - - for (tf = finfo->flag_list; tf != NULL; tf = tf->next) - { - int i; - if (bed->elf_backend_lookup_section_flags_hook) - { - flagword hexval = - (*bed->elf_backend_lookup_section_flags_hook) ((char *) tf->name); - - if (hexval != 0) - { - if (tf->with == with_flags) - with_hex |= hexval; - else if (tf->with == without_flags) - without_hex |= hexval; - tf->valid = TRUE; - continue; - } - } - for (i = 0; i < 12; i++) - { - if (!strcmp (tf->name, elf_flags_to_names[i].flag_name)) - { - if (tf->with == with_flags) - with_hex |= elf_flags_to_names[i].flag_value; - else if (tf->with == without_flags) - without_hex |= elf_flags_to_names[i].flag_value; - tf->valid = TRUE; - continue; - } - } - if (tf->valid == FALSE) - { - info->callbacks->einfo - (_("Unrecognized INPUT_SECTION_FLAG %s\n"), tf->name); - return; - } - } - finfo->flags_initialized = TRUE; - finfo->only_with_flags |= with_hex; - finfo->not_with_flags |= without_hex; - - return; -} - -struct alloc_got_off_arg { - bfd_vma gotoff; - struct bfd_link_info *info; -}; - -/* We need a special top-level link routine to convert got reference counts - to real got offsets. */ - -static bfd_boolean -elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) -{ - struct alloc_got_off_arg *gofarg = (struct alloc_got_off_arg *) arg; - bfd *obfd = gofarg->info->output_bfd; - const struct elf_backend_data *bed = get_elf_backend_data (obfd); - - if (h->got.refcount > 0) - { - h->got.offset = gofarg->gotoff; - gofarg->gotoff += bed->got_elt_size (obfd, gofarg->info, h, NULL, 0); - } - else - h->got.offset = (bfd_vma) -1; - - return TRUE; -} - -/* And an accompanying bit to work out final got entry offsets once - we're done. Should be called from final_link. */ - -bfd_boolean -bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, - struct bfd_link_info *info) -{ - bfd *i; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_vma gotoff; - struct alloc_got_off_arg gofarg; - - BFD_ASSERT (abfd == info->output_bfd); - - if (! is_elf_hash_table (info->hash)) - return FALSE; - - /* The GOT offset is relative to the .got section, but the GOT header is - put into the .got.plt section, if the backend uses it. */ - if (bed->want_got_plt) - gotoff = 0; - else - gotoff = bed->got_header_size; - - /* Do the local .got entries first. */ - for (i = info->input_bfds; i; i = i->link_next) - { - bfd_signed_vma *local_got; - bfd_size_type j, locsymcount; - Elf_Internal_Shdr *symtab_hdr; - - if (bfd_get_flavour (i) != bfd_target_elf_flavour) - continue; - - local_got = elf_local_got_refcounts (i); - if (!local_got) - continue; - - symtab_hdr = &elf_tdata (i)->symtab_hdr; - if (elf_bad_symtab (i)) - locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - else - locsymcount = symtab_hdr->sh_info; - - for (j = 0; j < locsymcount; ++j) - { - if (local_got[j] > 0) - { - local_got[j] = gotoff; - gotoff += bed->got_elt_size (abfd, info, NULL, i, j); - } - else - local_got[j] = (bfd_vma) -1; - } - } - - /* Then the global .got entries. .plt refcounts are handled by - adjust_dynamic_symbol */ - gofarg.gotoff = gotoff; - gofarg.info = info; - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_allocate_got_offsets, - &gofarg); - return TRUE; -} - -/* Many folk need no more in the way of final link than this, once - got entry reference counting is enabled. */ - -bfd_boolean -bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) -{ - if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info)) - return FALSE; - - /* Invoke the regular ELF backend linker to do all the work. */ - return bfd_elf_final_link (abfd, info); -} - -bfd_boolean -bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) -{ - struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *) cookie; - - if (rcookie->bad_symtab) - rcookie->rel = rcookie->rels; - - for (; rcookie->rel < rcookie->relend; rcookie->rel++) - { - unsigned long r_symndx; - - if (! rcookie->bad_symtab) - if (rcookie->rel->r_offset > offset) - return FALSE; - if (rcookie->rel->r_offset != offset) - continue; - - r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; - if (r_symndx == STN_UNDEF) - return TRUE; - - if (r_symndx >= rcookie->locsymcount - || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) - { - struct elf_link_hash_entry *h; - - h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (h->root.u.def.section)) - return TRUE; - else - return FALSE; - } - else - { - /* It's not a relocation against a global symbol, - but it could be a relocation against a local - symbol for a discarded section. */ - asection *isec; - Elf_Internal_Sym *isym; - - /* Need to: get the symbol; get the section. */ - isym = &rcookie->locsyms[r_symndx]; - isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); - if (isec != NULL && elf_discarded_section (isec)) - return TRUE; - } - return FALSE; - } - return FALSE; -} - -/* Discard unneeded references to discarded sections. - Returns TRUE if any section's size was changed. */ -/* This function assumes that the relocations are in sorted order, - which is true for all known assemblers. */ - -bfd_boolean -bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) -{ - struct elf_reloc_cookie cookie; - asection *stab, *eh; - const struct elf_backend_data *bed; - bfd *abfd; - bfd_boolean ret = FALSE; - - if (info->traditional_format - || !is_elf_hash_table (info->hash)) - return FALSE; - - _bfd_elf_begin_eh_frame_parsing (info); - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) - { - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - continue; - - bed = get_elf_backend_data (abfd); - - if ((abfd->flags & DYNAMIC) != 0) - continue; - - eh = NULL; - if (!info->relocatable) - { - eh = bfd_get_section_by_name (abfd, ".eh_frame"); - if (eh != NULL - && (eh->size == 0 - || bfd_is_abs_section (eh->output_section))) - eh = NULL; - } - - stab = bfd_get_section_by_name (abfd, ".stab"); - if (stab != NULL - && (stab->size == 0 - || bfd_is_abs_section (stab->output_section) - || stab->sec_info_type != ELF_INFO_TYPE_STABS)) - stab = NULL; - - if (stab == NULL - && eh == NULL - && bed->elf_backend_discard_info == NULL) - continue; - - if (!init_reloc_cookie (&cookie, info, abfd)) - return FALSE; - - if (stab != NULL - && stab->reloc_count > 0 - && init_reloc_cookie_rels (&cookie, info, abfd, stab)) - { - if (_bfd_discard_section_stabs (abfd, stab, - elf_section_data (stab)->sec_info, - bfd_elf_reloc_symbol_deleted_p, - &cookie)) - ret = TRUE; - fini_reloc_cookie_rels (&cookie, stab); - } - - if (eh != NULL - && init_reloc_cookie_rels (&cookie, info, abfd, eh)) - { - _bfd_elf_parse_eh_frame (abfd, info, eh, &cookie); - if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, - bfd_elf_reloc_symbol_deleted_p, - &cookie)) - ret = TRUE; - fini_reloc_cookie_rels (&cookie, eh); - } - - if (bed->elf_backend_discard_info != NULL - && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) - ret = TRUE; - - fini_reloc_cookie (&cookie, abfd); - } - _bfd_elf_end_eh_frame_parsing (info); - - if (info->eh_frame_hdr - && !info->relocatable - && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info)) - ret = TRUE; - - return ret; -} - -bfd_boolean -_bfd_elf_section_already_linked (bfd *abfd, - asection *sec, - struct bfd_link_info *info) -{ - flagword flags; - const char *name, *key; - struct bfd_section_already_linked *l; - struct bfd_section_already_linked_hash_entry *already_linked_list; - - if (sec->output_section == bfd_abs_section_ptr) - return FALSE; - - flags = sec->flags; - - /* Return if it isn't a linkonce section. A comdat group section - also has SEC_LINK_ONCE set. */ - if ((flags & SEC_LINK_ONCE) == 0) - return FALSE; - - /* Don't put group member sections on our list of already linked - sections. They are handled as a group via their group section. */ - if (elf_sec_group (sec) != NULL) - return FALSE; - - /* For a SHT_GROUP section, use the group signature as the key. */ - name = sec->name; - if ((flags & SEC_GROUP) != 0 - && elf_next_in_group (sec) != NULL - && elf_group_name (elf_next_in_group (sec)) != NULL) - key = elf_group_name (elf_next_in_group (sec)); - else - { - /* Otherwise we should have a .gnu.linkonce.. section. */ - if (CONST_STRNEQ (name, ".gnu.linkonce.") - && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL) - key++; - else - /* Must be a user linkonce section that doesn't follow gcc's - naming convention. In this case we won't be matching - single member groups. */ - key = name; - } - - already_linked_list = bfd_section_already_linked_table_lookup (key); - - for (l = already_linked_list->entry; l != NULL; l = l->next) - { - /* We may have 2 different types of sections on the list: group - sections with a signature of ( is some string), - and linkonce sections named .gnu.linkonce... - Match like sections. LTO plugin sections are an exception. - They are always named .gnu.linkonce.t. and match either - type of section. */ - if (((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP) - && ((flags & SEC_GROUP) != 0 - || strcmp (name, l->sec->name) == 0)) - || (l->sec->owner->flags & BFD_PLUGIN) != 0) - { - /* The section has already been linked. See if we should - issue a warning. */ - if (!_bfd_handle_already_linked (sec, l, info)) - return FALSE; - - if (flags & SEC_GROUP) - { - asection *first = elf_next_in_group (sec); - asection *s = first; - - while (s != NULL) - { - s->output_section = bfd_abs_section_ptr; - /* Record which group discards it. */ - s->kept_section = l->sec; - s = elf_next_in_group (s); - /* These lists are circular. */ - if (s == first) - break; - } - } - - return TRUE; - } - } - - /* A single member comdat group section may be discarded by a - linkonce section and vice versa. */ - if ((flags & SEC_GROUP) != 0) - { - asection *first = elf_next_in_group (sec); - - if (first != NULL && elf_next_in_group (first) == first) - /* Check this single member group against linkonce sections. */ - for (l = already_linked_list->entry; l != NULL; l = l->next) - if ((l->sec->flags & SEC_GROUP) == 0 - && bfd_elf_match_symbols_in_sections (l->sec, first, info)) - { - first->output_section = bfd_abs_section_ptr; - first->kept_section = l->sec; - sec->output_section = bfd_abs_section_ptr; - break; - } - } - else - /* Check this linkonce section against single member groups. */ - for (l = already_linked_list->entry; l != NULL; l = l->next) - if (l->sec->flags & SEC_GROUP) - { - asection *first = elf_next_in_group (l->sec); - - if (first != NULL - && elf_next_in_group (first) == first - && bfd_elf_match_symbols_in_sections (first, sec, info)) - { - sec->output_section = bfd_abs_section_ptr; - sec->kept_section = first; - break; - } - } - - /* Do not complain on unresolved relocations in `.gnu.linkonce.r.F' - referencing its discarded `.gnu.linkonce.t.F' counterpart - g++-3.4 - specific as g++-4.x is using COMDAT groups (without the `.gnu.linkonce' - prefix) instead. `.gnu.linkonce.r.*' were the `.rodata' part of its - matching `.gnu.linkonce.t.*'. If `.gnu.linkonce.r.F' is not discarded - but its `.gnu.linkonce.t.F' is discarded means we chose one-only - `.gnu.linkonce.t.F' section from a different bfd not requiring any - `.gnu.linkonce.r.F'. Thus `.gnu.linkonce.r.F' should be discarded. - The reverse order cannot happen as there is never a bfd with only the - `.gnu.linkonce.r.F' section. The order of sections in a bfd does not - matter as here were are looking only for cross-bfd sections. */ - - if ((flags & SEC_GROUP) == 0 && CONST_STRNEQ (name, ".gnu.linkonce.r.")) - for (l = already_linked_list->entry; l != NULL; l = l->next) - if ((l->sec->flags & SEC_GROUP) == 0 - && CONST_STRNEQ (l->sec->name, ".gnu.linkonce.t.")) - { - if (abfd != l->sec->owner) - sec->output_section = bfd_abs_section_ptr; - break; - } - - /* This is the first section with this name. Record it. */ - if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) - info->callbacks->einfo (_("%F%P: already_linked_table: %E\n")); - return sec->output_section == bfd_abs_section_ptr; -} - -bfd_boolean -_bfd_elf_common_definition (Elf_Internal_Sym *sym) -{ - return sym->st_shndx == SHN_COMMON; -} - -unsigned int -_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED) -{ - return SHN_COMMON; -} - -asection * -_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) -{ - return bfd_com_section_ptr; -} - -bfd_vma -_bfd_elf_default_got_elt_size (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h ATTRIBUTE_UNUSED, - bfd *ibfd ATTRIBUTE_UNUSED, - unsigned long symndx ATTRIBUTE_UNUSED) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - return bed->s->arch_size / 8; -} - -/* Routines to support the creation of dynamic relocs. */ - -/* Returns the name of the dynamic reloc section associated with SEC. */ - -static const char * -get_dynamic_reloc_section_name (bfd * abfd, - asection * sec, - bfd_boolean is_rela) -{ - char *name; - const char *old_name = bfd_get_section_name (NULL, sec); - const char *prefix = is_rela ? ".rela" : ".rel"; - - if (old_name == NULL) - return NULL; - - name = bfd_alloc (abfd, strlen (prefix) + strlen (old_name) + 1); - sprintf (name, "%s%s", prefix, old_name); - - return name; -} - -/* Returns the dynamic reloc section associated with SEC. - If necessary compute the name of the dynamic reloc section based - on SEC's name (looked up in ABFD's string table) and the setting - of IS_RELA. */ - -asection * -_bfd_elf_get_dynamic_reloc_section (bfd * abfd, - asection * sec, - bfd_boolean is_rela) -{ - asection * reloc_sec = elf_section_data (sec)->sreloc; - - if (reloc_sec == NULL) - { - const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela); - - if (name != NULL) - { - reloc_sec = bfd_get_section_by_name (abfd, name); - - if (reloc_sec != NULL) - elf_section_data (sec)->sreloc = reloc_sec; - } - } - - return reloc_sec; -} - -/* Returns the dynamic reloc section associated with SEC. If the - section does not exist it is created and attached to the DYNOBJ - bfd and stored in the SRELOC field of SEC's elf_section_data - structure. - - ALIGNMENT is the alignment for the newly created section and - IS_RELA defines whether the name should be .rela. - or .rel.. The section name is looked up in the - string table associated with ABFD. */ - -asection * -_bfd_elf_make_dynamic_reloc_section (asection * sec, - bfd * dynobj, - unsigned int alignment, - bfd * abfd, - bfd_boolean is_rela) -{ - asection * reloc_sec = elf_section_data (sec)->sreloc; - - if (reloc_sec == NULL) - { - const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela); - - if (name == NULL) - return NULL; - - reloc_sec = bfd_get_section_by_name (dynobj, name); - - if (reloc_sec == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - - reloc_sec = bfd_make_section_with_flags (dynobj, name, flags); - if (reloc_sec != NULL) - { - if (! bfd_set_section_alignment (dynobj, reloc_sec, alignment)) - reloc_sec = NULL; - } - } - - elf_section_data (sec)->sreloc = reloc_sec; - } - - return reloc_sec; -} - -/* Copy the ELF symbol type associated with a linker hash entry. */ -void -_bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hdest, - struct bfd_link_hash_entry * hsrc) -{ - struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *)hdest; - struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc; - - ehdest->type = ehsrc->type; - ehdest->target_internal = ehsrc->target_internal; -} - -/* Append a RELA relocation REL to section S in BFD. */ - -void -elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela); - BFD_ASSERT (loc + bed->s->sizeof_rela <= s->contents + s->size); - bed->s->swap_reloca_out (abfd, rel, loc); -} - -/* Append a REL relocation REL to section S in BFD. */ - -void -elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rel); - BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size); - bed->s->swap_reloca_out (abfd, rel, loc); -} diff --git a/contrib/binutils-2.22/bfd/elfxx-target.h b/contrib/binutils-2.22/bfd/elfxx-target.h deleted file mode 100644 index 96ecce308d..0000000000 --- a/contrib/binutils-2.22/bfd/elfxx-target.h +++ /dev/null @@ -1,988 +0,0 @@ -/* Target definitions for NN-bit ELF - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* This structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - -#ifndef bfd_elfNN_close_and_cleanup -#define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup -#endif -#ifndef bfd_elfNN_bfd_free_cached_info -#define bfd_elfNN_bfd_free_cached_info _bfd_free_cached_info -#endif -#ifndef bfd_elfNN_get_section_contents -#define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents -#endif - -#define bfd_elfNN_canonicalize_dynamic_symtab \ - _bfd_elf_canonicalize_dynamic_symtab -#ifndef bfd_elfNN_get_synthetic_symtab -#define bfd_elfNN_get_synthetic_symtab \ - _bfd_elf_get_synthetic_symtab -#endif -#ifndef bfd_elfNN_canonicalize_reloc -#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc -#endif -#ifndef bfd_elfNN_find_nearest_line -#define bfd_elfNN_find_nearest_line _bfd_elf_find_nearest_line -#endif -#ifndef bfd_elfNN_find_inliner_info -#define bfd_elfNN_find_inliner_info _bfd_elf_find_inliner_info -#endif -#define bfd_elfNN_read_minisymbols _bfd_elf_read_minisymbols -#define bfd_elfNN_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol -#define bfd_elfNN_get_dynamic_symtab_upper_bound \ - _bfd_elf_get_dynamic_symtab_upper_bound -#define bfd_elfNN_get_lineno _bfd_elf_get_lineno -#ifndef bfd_elfNN_get_reloc_upper_bound -#define bfd_elfNN_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound -#endif -#ifndef bfd_elfNN_get_symbol_info -#define bfd_elfNN_get_symbol_info _bfd_elf_get_symbol_info -#endif -#define bfd_elfNN_canonicalize_symtab _bfd_elf_canonicalize_symtab -#define bfd_elfNN_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound -#define bfd_elfNN_make_empty_symbol _bfd_elf_make_empty_symbol -#ifndef bfd_elfNN_new_section_hook -#define bfd_elfNN_new_section_hook _bfd_elf_new_section_hook -#endif -#define bfd_elfNN_set_arch_mach _bfd_elf_set_arch_mach -#ifndef bfd_elfNN_set_section_contents -#define bfd_elfNN_set_section_contents _bfd_elf_set_section_contents -#endif -#define bfd_elfNN_sizeof_headers _bfd_elf_sizeof_headers -#define bfd_elfNN_write_object_contents _bfd_elf_write_object_contents -#define bfd_elfNN_write_corefile_contents _bfd_elf_write_corefile_contents - -#define bfd_elfNN_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#ifndef elf_backend_can_refcount -#define elf_backend_can_refcount 0 -#endif -#ifndef elf_backend_want_got_plt -#define elf_backend_want_got_plt 0 -#endif -#ifndef elf_backend_plt_readonly -#define elf_backend_plt_readonly 0 -#endif -#ifndef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 -#endif -#ifndef elf_backend_plt_not_loaded -#define elf_backend_plt_not_loaded 0 -#endif -#ifndef elf_backend_plt_alignment -#define elf_backend_plt_alignment 2 -#endif -#ifndef elf_backend_want_dynbss -#define elf_backend_want_dynbss 1 -#endif -#ifndef elf_backend_want_p_paddr_set_to_zero -#define elf_backend_want_p_paddr_set_to_zero 0 -#endif -#ifndef elf_backend_default_execstack -#define elf_backend_default_execstack 1 -#endif - -#define bfd_elfNN_bfd_debug_info_start bfd_void -#define bfd_elfNN_bfd_debug_info_end bfd_void -#define bfd_elfNN_bfd_debug_info_accumulate \ - ((void (*) (bfd*, struct bfd_section *)) bfd_void) - -#ifndef bfd_elfNN_bfd_get_relocated_section_contents -#define bfd_elfNN_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif - -#ifndef bfd_elfNN_bfd_relax_section -#define bfd_elfNN_bfd_relax_section bfd_generic_relax_section -#endif - -#ifndef elf_backend_can_gc_sections -#define elf_backend_can_gc_sections 0 -#endif -#ifndef elf_backend_can_refcount -#define elf_backend_can_refcount 0 -#endif -#ifndef elf_backend_want_got_sym -#define elf_backend_want_got_sym 1 -#endif -#ifndef elf_backend_gc_keep -#define elf_backend_gc_keep _bfd_elf_gc_keep -#endif -#ifndef elf_backend_gc_mark_dynamic_ref -#define elf_backend_gc_mark_dynamic_ref bfd_elf_gc_mark_dynamic_ref_symbol -#endif -#ifndef elf_backend_gc_mark_hook -#define elf_backend_gc_mark_hook _bfd_elf_gc_mark_hook -#endif -#ifndef elf_backend_gc_mark_extra_sections -#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections -#endif -#ifndef elf_backend_gc_sweep_hook -#define elf_backend_gc_sweep_hook NULL -#endif -#ifndef bfd_elfNN_bfd_gc_sections -#define bfd_elfNN_bfd_gc_sections bfd_elf_gc_sections -#endif - -#ifndef bfd_elfNN_bfd_merge_sections -#define bfd_elfNN_bfd_merge_sections \ - _bfd_elf_merge_sections -#endif - -#ifndef bfd_elfNN_bfd_is_group_section -#define bfd_elfNN_bfd_is_group_section bfd_elf_is_group_section -#endif - -#ifndef bfd_elfNN_bfd_discard_group -#define bfd_elfNN_bfd_discard_group bfd_generic_discard_group -#endif - -#ifndef bfd_elfNN_section_already_linked -#define bfd_elfNN_section_already_linked \ - _bfd_elf_section_already_linked -#endif - -#ifndef bfd_elfNN_bfd_define_common_symbol -#define bfd_elfNN_bfd_define_common_symbol bfd_generic_define_common_symbol -#endif - -#ifndef bfd_elfNN_bfd_lookup_section_flags -#define bfd_elfNN_bfd_lookup_section_flags bfd_elf_lookup_section_flags -#endif - -#ifndef bfd_elfNN_bfd_make_debug_symbol -#define bfd_elfNN_bfd_make_debug_symbol \ - ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr) -#endif - -#ifndef bfd_elfNN_bfd_copy_private_symbol_data -#define bfd_elfNN_bfd_copy_private_symbol_data \ - _bfd_elf_copy_private_symbol_data -#endif - -#ifndef bfd_elfNN_bfd_copy_private_section_data -#define bfd_elfNN_bfd_copy_private_section_data \ - _bfd_elf_copy_private_section_data -#endif -#ifndef bfd_elfNN_bfd_copy_private_header_data -#define bfd_elfNN_bfd_copy_private_header_data \ - _bfd_elf_copy_private_header_data -#endif -#ifndef bfd_elfNN_bfd_copy_private_bfd_data -#define bfd_elfNN_bfd_copy_private_bfd_data \ - _bfd_elf_copy_private_bfd_data -#endif -#ifndef bfd_elfNN_bfd_print_private_bfd_data -#define bfd_elfNN_bfd_print_private_bfd_data \ - _bfd_elf_print_private_bfd_data -#endif -#ifndef bfd_elfNN_bfd_merge_private_bfd_data -#define bfd_elfNN_bfd_merge_private_bfd_data \ - ((bfd_boolean (*) (bfd *, bfd *)) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_set_private_flags -#define bfd_elfNN_bfd_set_private_flags \ - ((bfd_boolean (*) (bfd *, flagword)) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_is_local_label_name -#define bfd_elfNN_bfd_is_local_label_name _bfd_elf_is_local_label_name -#endif -#ifndef bfd_elfNN_bfd_is_target_special_symbol -#define bfd_elfNN_bfd_is_target_special_symbol \ - ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#endif - -#ifndef bfd_elfNN_get_dynamic_reloc_upper_bound -#define bfd_elfNN_get_dynamic_reloc_upper_bound \ - _bfd_elf_get_dynamic_reloc_upper_bound -#endif -#ifndef bfd_elfNN_canonicalize_dynamic_reloc -#define bfd_elfNN_canonicalize_dynamic_reloc \ - _bfd_elf_canonicalize_dynamic_reloc -#endif - -#ifndef bfd_elfNN_bfd_link_hash_table_free -#define bfd_elfNN_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#endif - -#ifdef elf_backend_relocate_section -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create -#endif -#ifndef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols bfd_elf_link_add_symbols -#endif -#ifndef bfd_elfNN_bfd_final_link -#define bfd_elfNN_bfd_final_link bfd_elf_final_link -#endif -#else /* ! defined (elf_backend_relocate_section) */ -/* If no backend relocate_section routine, use the generic linker. - Note - this will prevent the port from being able to use some of - the other features of the ELF linker, because the generic hash structure - does not have the fields needed by the ELF linker. In particular it - means that linking directly to S-records will not work. */ -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#endif -#ifndef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols -#endif -#ifndef bfd_elfNN_bfd_final_link -#define bfd_elfNN_bfd_final_link _bfd_generic_final_link -#endif -#endif /* ! defined (elf_backend_relocate_section) */ - -#ifndef bfd_elfNN_bfd_link_just_syms -#define bfd_elfNN_bfd_link_just_syms _bfd_elf_link_just_syms -#endif - -#ifndef bfd_elfNN_bfd_copy_link_hash_symbol_type -#define bfd_elfNN_bfd_copy_link_hash_symbol_type \ - _bfd_elf_copy_link_hash_symbol_type -#endif - -#ifndef bfd_elfNN_bfd_link_split_section -#define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section -#endif - -#ifndef bfd_elfNN_archive_p -#define bfd_elfNN_archive_p bfd_generic_archive_p -#endif - -#ifndef bfd_elfNN_write_archive_contents -#define bfd_elfNN_write_archive_contents _bfd_write_archive_contents -#endif - -#ifndef bfd_elfNN_mkobject -#define bfd_elfNN_mkobject bfd_elf_make_object -#endif - -#ifndef bfd_elfNN_mkcorefile -#define bfd_elfNN_mkcorefile bfd_elf_mkcorefile -#endif - -#ifndef bfd_elfNN_mkarchive -#define bfd_elfNN_mkarchive _bfd_generic_mkarchive -#endif - -#ifndef bfd_elfNN_print_symbol -#define bfd_elfNN_print_symbol bfd_elf_print_symbol -#endif - -#ifndef elf_symbol_leading_char -#define elf_symbol_leading_char 0 -#endif - -#ifndef elf_info_to_howto -#define elf_info_to_howto 0 -#endif - -#ifndef elf_info_to_howto_rel -#define elf_info_to_howto_rel 0 -#endif - -#ifndef elf_backend_arch_data -#define elf_backend_arch_data NULL -#endif - -#ifndef ELF_TARGET_ID -#define ELF_TARGET_ID GENERIC_ELF_DATA -#endif - -#ifndef ELF_OSABI -#define ELF_OSABI ELFOSABI_NONE -#endif - -#ifndef ELF_MAXPAGESIZE -# error ELF_MAXPAGESIZE is not defined -#define ELF_MAXPAGESIZE 1 -#endif - -#ifndef ELF_COMMONPAGESIZE -#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE -#endif - -#ifndef ELF_MINPAGESIZE -#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE -#endif - -#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE -# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE -#endif -#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE -# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE -#endif - -#ifndef ELF_DYNAMIC_SEC_FLAGS -/* Note that we set the SEC_IN_MEMORY flag for these sections. */ -#define ELF_DYNAMIC_SEC_FLAGS \ - (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS \ - | SEC_IN_MEMORY | SEC_LINKER_CREATED) -#endif - -#ifndef elf_backend_collect -#define elf_backend_collect FALSE -#endif -#ifndef elf_backend_type_change_ok -#define elf_backend_type_change_ok FALSE -#endif - -#ifndef elf_backend_sym_is_global -#define elf_backend_sym_is_global 0 -#endif -#ifndef elf_backend_object_p -#define elf_backend_object_p 0 -#endif -#ifndef elf_backend_symbol_processing -#define elf_backend_symbol_processing 0 -#endif -#ifndef elf_backend_symbol_table_processing -#define elf_backend_symbol_table_processing 0 -#endif -#ifndef elf_backend_get_symbol_type -#define elf_backend_get_symbol_type 0 -#endif -#ifndef elf_backend_archive_symbol_lookup -#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup -#endif -#ifndef elf_backend_name_local_section_symbols -#define elf_backend_name_local_section_symbols 0 -#endif -#ifndef elf_backend_section_processing -#define elf_backend_section_processing 0 -#endif -#ifndef elf_backend_section_from_shdr -#define elf_backend_section_from_shdr _bfd_elf_make_section_from_shdr -#endif -#ifndef elf_backend_section_flags -#define elf_backend_section_flags 0 -#endif -#ifndef elf_backend_get_sec_type_attr -#define elf_backend_get_sec_type_attr _bfd_elf_get_sec_type_attr -#endif -#ifndef elf_backend_section_from_phdr -#define elf_backend_section_from_phdr _bfd_elf_make_section_from_phdr -#endif -#ifndef elf_backend_fake_sections -#define elf_backend_fake_sections 0 -#endif -#ifndef elf_backend_section_from_bfd_section -#define elf_backend_section_from_bfd_section 0 -#endif -#ifndef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook 0 -#endif -#ifndef elf_backend_link_output_symbol_hook -#define elf_backend_link_output_symbol_hook 0 -#endif -#ifndef elf_backend_create_dynamic_sections -#define elf_backend_create_dynamic_sections 0 -#endif -#ifndef elf_backend_omit_section_dynsym -#define elf_backend_omit_section_dynsym _bfd_elf_link_omit_section_dynsym -#endif -#ifndef elf_backend_relocs_compatible -#define elf_backend_relocs_compatible _bfd_elf_default_relocs_compatible -#endif -#ifndef elf_backend_check_relocs -#define elf_backend_check_relocs 0 -#endif -#ifndef elf_backend_check_directives -#define elf_backend_check_directives 0 -#endif -#ifndef elf_backend_as_needed_cleanup -#define elf_backend_as_needed_cleanup 0 -#endif -#ifndef elf_backend_adjust_dynamic_symbol -#define elf_backend_adjust_dynamic_symbol 0 -#endif -#ifndef elf_backend_always_size_sections -#define elf_backend_always_size_sections 0 -#endif -#ifndef elf_backend_size_dynamic_sections -#define elf_backend_size_dynamic_sections 0 -#endif -#ifndef elf_backend_init_index_section -#define elf_backend_init_index_section \ - ((void (*) (bfd *, struct bfd_link_info *)) bfd_void) -#endif -#ifndef elf_backend_relocate_section -#define elf_backend_relocate_section 0 -#endif -#ifndef elf_backend_finish_dynamic_symbol -#define elf_backend_finish_dynamic_symbol 0 -#endif -#ifndef elf_backend_finish_dynamic_sections -#define elf_backend_finish_dynamic_sections 0 -#endif -#ifndef elf_backend_begin_write_processing -#define elf_backend_begin_write_processing 0 -#endif -#ifndef elf_backend_final_write_processing -#define elf_backend_final_write_processing 0 -#endif -#ifndef elf_backend_additional_program_headers -#define elf_backend_additional_program_headers 0 -#endif -#ifndef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map 0 -#endif -#ifndef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers 0 -#endif -#ifndef elf_backend_ecoff_debug_swap -#define elf_backend_ecoff_debug_swap 0 -#endif -#ifndef elf_backend_bfd_from_remote_memory -#define elf_backend_bfd_from_remote_memory _bfd_elfNN_bfd_from_remote_memory -#endif -#ifndef elf_backend_got_header_size -#define elf_backend_got_header_size 0 -#endif -#ifndef elf_backend_got_elt_size -#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size -#endif -#ifndef elf_backend_obj_attrs_vendor -#define elf_backend_obj_attrs_vendor NULL -#endif -#ifndef elf_backend_obj_attrs_section -#define elf_backend_obj_attrs_section NULL -#endif -#ifndef elf_backend_obj_attrs_arg_type -#define elf_backend_obj_attrs_arg_type NULL -#endif -#ifndef elf_backend_obj_attrs_section_type -#define elf_backend_obj_attrs_section_type SHT_GNU_ATTRIBUTES -#endif -#ifndef elf_backend_obj_attrs_order -#define elf_backend_obj_attrs_order NULL -#endif -#ifndef elf_backend_obj_attrs_handle_unknown -#define elf_backend_obj_attrs_handle_unknown NULL -#endif -#ifndef elf_backend_static_tls_alignment -#define elf_backend_static_tls_alignment 1 -#endif -#ifndef elf_backend_post_process_headers -#define elf_backend_post_process_headers NULL -#endif -#ifndef elf_backend_print_symbol_all -#define elf_backend_print_symbol_all NULL -#endif -#ifndef elf_backend_output_arch_local_syms -#define elf_backend_output_arch_local_syms NULL -#endif -#ifndef elf_backend_output_arch_syms -#define elf_backend_output_arch_syms NULL -#endif -#ifndef elf_backend_copy_indirect_symbol -#define elf_backend_copy_indirect_symbol _bfd_elf_link_hash_copy_indirect -#endif -#ifndef elf_backend_hide_symbol -#define elf_backend_hide_symbol _bfd_elf_link_hash_hide_symbol -#endif -#ifndef elf_backend_fixup_symbol -#define elf_backend_fixup_symbol NULL -#endif -#ifndef elf_backend_merge_symbol_attribute -#define elf_backend_merge_symbol_attribute NULL -#endif -#ifndef elf_backend_get_target_dtag -#define elf_backend_get_target_dtag NULL -#endif -#ifndef elf_backend_ignore_undef_symbol -#define elf_backend_ignore_undef_symbol NULL -#endif -#ifndef elf_backend_emit_relocs -#define elf_backend_emit_relocs _bfd_elf_link_output_relocs -#endif -#ifndef elf_backend_count_relocs -#define elf_backend_count_relocs NULL -#endif -#ifndef elf_backend_grok_prstatus -#define elf_backend_grok_prstatus NULL -#endif -#ifndef elf_backend_grok_psinfo -#define elf_backend_grok_psinfo NULL -#endif -#ifndef elf_backend_write_core_note -#define elf_backend_write_core_note NULL -#endif -#ifndef elf_backend_lookup_section_flags_hook -#define elf_backend_lookup_section_flags_hook NULL -#endif -#ifndef elf_backend_reloc_type_class -#define elf_backend_reloc_type_class _bfd_elf_reloc_type_class -#endif -#ifndef elf_backend_discard_info -#define elf_backend_discard_info NULL -#endif -#ifndef elf_backend_ignore_discarded_relocs -#define elf_backend_ignore_discarded_relocs NULL -#endif -#ifndef elf_backend_action_discarded -#define elf_backend_action_discarded _bfd_elf_default_action_discarded -#endif -#ifndef elf_backend_eh_frame_address_size -#define elf_backend_eh_frame_address_size _bfd_elf_eh_frame_address_size -#endif -#ifndef elf_backend_can_make_relative_eh_frame -#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative -#endif -#ifndef elf_backend_can_make_lsda_relative_eh_frame -#define elf_backend_can_make_lsda_relative_eh_frame _bfd_elf_can_make_relative -#endif -#ifndef elf_backend_encode_eh_address -#define elf_backend_encode_eh_address _bfd_elf_encode_eh_address -#endif -#ifndef elf_backend_write_section -#define elf_backend_write_section NULL -#endif -#ifndef elf_backend_mips_irix_compat -#define elf_backend_mips_irix_compat NULL -#endif -#ifndef elf_backend_mips_rtype_to_howto -#define elf_backend_mips_rtype_to_howto NULL -#endif - -/* Previously, backends could only use SHT_REL or SHT_RELA relocation - sections, but not both. They defined USE_REL to indicate SHT_REL - sections, and left it undefined to indicated SHT_RELA sections. - For backwards compatibility, we still support this usage. */ -#ifndef USE_REL -#define USE_REL 0 -#endif - -/* Use these in new code. */ -#ifndef elf_backend_may_use_rel_p -#define elf_backend_may_use_rel_p USE_REL -#endif -#ifndef elf_backend_may_use_rela_p -#define elf_backend_may_use_rela_p !USE_REL -#endif -#ifndef elf_backend_default_use_rela_p -#define elf_backend_default_use_rela_p !USE_REL -#endif -#ifndef elf_backend_rela_plts_and_copies_p -#define elf_backend_rela_plts_and_copies_p elf_backend_default_use_rela_p -#endif - -#ifndef elf_backend_rela_normal -#define elf_backend_rela_normal 0 -#endif - -#ifndef elf_backend_plt_sym_val -#define elf_backend_plt_sym_val NULL -#endif -#ifndef elf_backend_relplt_name -#define elf_backend_relplt_name NULL -#endif - -#ifndef ELF_MACHINE_ALT1 -#define ELF_MACHINE_ALT1 0 -#endif - -#ifndef ELF_MACHINE_ALT2 -#define ELF_MACHINE_ALT2 0 -#endif - -#ifndef elf_backend_size_info -#define elf_backend_size_info _bfd_elfNN_size_info -#endif - -#ifndef elf_backend_special_sections -#define elf_backend_special_sections NULL -#endif - -#ifndef elf_backend_sign_extend_vma -#define elf_backend_sign_extend_vma 0 -#endif - -#ifndef elf_backend_link_order_error_handler -#define elf_backend_link_order_error_handler _bfd_default_error_handler -#endif - -#ifndef elf_backend_common_definition -#define elf_backend_common_definition _bfd_elf_common_definition -#endif - -#ifndef elf_backend_common_section_index -#define elf_backend_common_section_index _bfd_elf_common_section_index -#endif - -#ifndef elf_backend_common_section -#define elf_backend_common_section _bfd_elf_common_section -#endif - -#ifndef elf_backend_merge_symbol -#define elf_backend_merge_symbol NULL -#endif - -#ifndef elf_backend_hash_symbol -#define elf_backend_hash_symbol _bfd_elf_hash_symbol -#endif - -#ifndef elf_backend_is_function_type -#define elf_backend_is_function_type _bfd_elf_is_function_type -#endif - -#ifndef elf_match_priority -#define elf_match_priority \ - (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0) -#endif - -extern const struct elf_size_info _bfd_elfNN_size_info; - -static struct elf_backend_data elfNN_bed = -{ - ELF_ARCH, /* arch */ - ELF_TARGET_ID, /* target_id */ - ELF_MACHINE_CODE, /* elf_machine_code */ - ELF_OSABI, /* elf_osabi */ - ELF_MAXPAGESIZE, /* maxpagesize */ - ELF_MINPAGESIZE, /* minpagesize */ - ELF_COMMONPAGESIZE, /* commonpagesize */ - ELF_DYNAMIC_SEC_FLAGS, /* dynamic_sec_flags */ - elf_backend_arch_data, - elf_info_to_howto, - elf_info_to_howto_rel, - elf_backend_sym_is_global, - elf_backend_object_p, - elf_backend_symbol_processing, - elf_backend_symbol_table_processing, - elf_backend_get_symbol_type, - elf_backend_archive_symbol_lookup, - elf_backend_name_local_section_symbols, - elf_backend_section_processing, - elf_backend_section_from_shdr, - elf_backend_section_flags, - elf_backend_get_sec_type_attr, - elf_backend_section_from_phdr, - elf_backend_fake_sections, - elf_backend_section_from_bfd_section, - elf_backend_add_symbol_hook, - elf_backend_link_output_symbol_hook, - elf_backend_create_dynamic_sections, - elf_backend_omit_section_dynsym, - elf_backend_relocs_compatible, - elf_backend_check_relocs, - elf_backend_check_directives, - elf_backend_as_needed_cleanup, - elf_backend_adjust_dynamic_symbol, - elf_backend_always_size_sections, - elf_backend_size_dynamic_sections, - elf_backend_init_index_section, - elf_backend_relocate_section, - elf_backend_finish_dynamic_symbol, - elf_backend_finish_dynamic_sections, - elf_backend_begin_write_processing, - elf_backend_final_write_processing, - elf_backend_additional_program_headers, - elf_backend_modify_segment_map, - elf_backend_modify_program_headers, - elf_backend_gc_keep, - elf_backend_gc_mark_dynamic_ref, - elf_backend_gc_mark_hook, - elf_backend_gc_mark_extra_sections, - elf_backend_gc_sweep_hook, - elf_backend_post_process_headers, - elf_backend_print_symbol_all, - elf_backend_output_arch_local_syms, - elf_backend_output_arch_syms, - elf_backend_copy_indirect_symbol, - elf_backend_hide_symbol, - elf_backend_fixup_symbol, - elf_backend_merge_symbol_attribute, - elf_backend_get_target_dtag, - elf_backend_ignore_undef_symbol, - elf_backend_emit_relocs, - elf_backend_count_relocs, - elf_backend_grok_prstatus, - elf_backend_grok_psinfo, - elf_backend_write_core_note, - elf_backend_lookup_section_flags_hook, - elf_backend_reloc_type_class, - elf_backend_discard_info, - elf_backend_ignore_discarded_relocs, - elf_backend_action_discarded, - elf_backend_eh_frame_address_size, - elf_backend_can_make_relative_eh_frame, - elf_backend_can_make_lsda_relative_eh_frame, - elf_backend_encode_eh_address, - elf_backend_write_section, - elf_backend_mips_irix_compat, - elf_backend_mips_rtype_to_howto, - elf_backend_ecoff_debug_swap, - elf_backend_bfd_from_remote_memory, - elf_backend_plt_sym_val, - elf_backend_common_definition, - elf_backend_common_section_index, - elf_backend_common_section, - elf_backend_merge_symbol, - elf_backend_hash_symbol, - elf_backend_is_function_type, - elf_backend_link_order_error_handler, - elf_backend_relplt_name, - ELF_MACHINE_ALT1, - ELF_MACHINE_ALT2, - &elf_backend_size_info, - elf_backend_special_sections, - elf_backend_got_header_size, - elf_backend_got_elt_size, - elf_backend_obj_attrs_vendor, - elf_backend_obj_attrs_section, - elf_backend_obj_attrs_arg_type, - elf_backend_obj_attrs_section_type, - elf_backend_obj_attrs_order, - elf_backend_obj_attrs_handle_unknown, - elf_backend_static_tls_alignment, - elf_backend_collect, - elf_backend_type_change_ok, - elf_backend_may_use_rel_p, - elf_backend_may_use_rela_p, - elf_backend_default_use_rela_p, - elf_backend_rela_plts_and_copies_p, - elf_backend_rela_normal, - elf_backend_sign_extend_vma, - elf_backend_want_got_plt, - elf_backend_plt_readonly, - elf_backend_want_plt_sym, - elf_backend_plt_not_loaded, - elf_backend_plt_alignment, - elf_backend_can_gc_sections, - elf_backend_can_refcount, - elf_backend_want_got_sym, - elf_backend_want_dynbss, - elf_backend_want_p_paddr_set_to_zero, - elf_backend_default_execstack -}; - -/* Forward declaration for use when initialising alternative_target field. */ -#ifdef TARGET_LITTLE_SYM -extern const bfd_target TARGET_LITTLE_SYM; -#endif - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is big endian */ - BFD_ENDIAN_BIG, - - /* header_byteorder: header is also big endian */ - BFD_ENDIAN_BIG, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY - | SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES - | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. The System V ABI, - Chapter 7 (Formats & Protocols), Archive section sets this as 15. */ - 15, - - elf_match_priority, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elfNN_object_p, /* assembler/linker output (object file) */ - bfd_elfNN_archive_p, /* an archive */ - bfd_elfNN_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elfNN_mkobject, - bfd_elfNN_mkarchive, - bfd_elfNN_mkcorefile - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - bfd_elfNN_write_archive_contents, - bfd_elfNN_write_corefile_contents, - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), -#ifdef bfd_elfNN_archive_functions - BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive), -#else - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), -#endif - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* Alternative endian target. */ -#ifdef TARGET_LITTLE_SYM - & TARGET_LITTLE_SYM, -#else - NULL, -#endif - - /* backend_data: */ - &elfNN_bed -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is little endian */ - BFD_ENDIAN_LITTLE, - - /* header_byteorder: header is also little endian */ - BFD_ENDIAN_LITTLE, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY - | SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES - | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. The System V ABI, - Chapter 7 (Formats & Protocols), Archive section sets this as 15. */ - 15, - - elf_match_priority, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elfNN_object_p, /* assembler/linker output (object file) */ - bfd_elfNN_archive_p, /* an archive */ - bfd_elfNN_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elfNN_mkobject, - bfd_elfNN_mkarchive, - bfd_elfNN_mkcorefile - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - bfd_elfNN_write_archive_contents, - bfd_elfNN_write_corefile_contents, - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), -#ifdef bfd_elfNN_archive_functions - BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive), -#else - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), -#endif - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* Alternative endian target. */ -#ifdef TARGET_BIG_SYM - & TARGET_BIG_SYM, -#else - NULL, -#endif - - /* backend_data: */ - &elfNN_bed -}; -#endif diff --git a/contrib/binutils-2.22/bfd/format.c b/contrib/binutils-2.22/bfd/format.c deleted file mode 100644 index 66b9051efe..0000000000 --- a/contrib/binutils-2.22/bfd/format.c +++ /dev/null @@ -1,429 +0,0 @@ -/* Generic BFD support for file formats. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002, - 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* -SECTION - File formats - - A format is a BFD concept of high level file contents type. The - formats supported by BFD are: - - o <> - - The BFD may contain data, symbols, relocations and debug info. - - o <> - - The BFD contains other BFDs and an optional index. - - o <> - - The BFD contains the result of an executable core dump. - -SUBSECTION - File format functions -*/ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -/* IMPORT from targets.c. */ -extern const size_t _bfd_target_vector_entries; - -/* -FUNCTION - bfd_check_format - -SYNOPSIS - bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); - -DESCRIPTION - Verify if the file attached to the BFD @var{abfd} is compatible - with the format @var{format} (i.e., one of <>, - <> or <>). - - If the BFD has been set to a specific target before the - call, only the named target and format combination is - checked. If the target has not been set, or has been set to - <>, then all the known target backends is - interrogated to determine a match. If the default target - matches, it is used. If not, exactly one target must recognize - the file, or an error results. - - The function returns <> on success, otherwise <> - with one of the following error codes: - - o <> - - if <> is not one of <>, <> or - <>. - - o <> - - if an error occured during a read - even some file mismatches - can cause bfd_error_system_calls. - - o <> - - none of the backends recognised the file format. - - o <> - - more than one backend recognised the file format. -*/ - -bfd_boolean -bfd_check_format (bfd *abfd, bfd_format format) -{ - return bfd_check_format_matches (abfd, format, NULL); -} - -/* -FUNCTION - bfd_check_format_matches - -SYNOPSIS - bfd_boolean bfd_check_format_matches - (bfd *abfd, bfd_format format, char ***matching); - -DESCRIPTION - Like <>, except when it returns FALSE with - <> set to <>. In that - case, if @var{matching} is not NULL, it will be filled in with - a NULL-terminated list of the names of the formats that matched, - allocated with <>. - Then the user may choose a format and try again. - - When done with the list that @var{matching} points to, the caller - should free it. -*/ - -bfd_boolean -bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) -{ - extern const bfd_target binary_vec; - const bfd_target * const *target; - const bfd_target **matching_vector = NULL; - const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ; - int match_count, best_count, best_match; - int ar_match_index; - - if (matching != NULL) - *matching = NULL; - - if (!bfd_read_p (abfd) - || (unsigned int) abfd->format >= (unsigned int) bfd_type_end) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - if (abfd->format != bfd_unknown) - return abfd->format == format; - - /* Since the target type was defaulted, check them - all in the hope that one will be uniquely recognized. */ - save_targ = abfd->xvec; - match_count = 0; - ar_match_index = _bfd_target_vector_entries; - - if (matching != NULL || *bfd_associated_vector != NULL) - { - bfd_size_type amt; - - amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries; - matching_vector = (const bfd_target **) bfd_malloc (amt); - if (!matching_vector) - return FALSE; - } - - right_targ = 0; - ar_right_targ = 0; - match_targ = 0; - best_match = 256; - best_count = 0; - - /* Presume the answer is yes. */ - abfd->format = format; - - /* If the target type was explicitly specified, just check that target. */ - if (!abfd->target_defaulted) - { - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */ - goto err_ret; - - right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - - if (right_targ) - goto ok_ret; - - /* For a long time the code has dropped through to check all - targets if the specified target was wrong. I don't know why, - and I'm reluctant to change it. However, in the case of an - archive, it can cause problems. If the specified target does - not permit archives (e.g., the binary target), then we should - not allow some other target to recognize it as an archive, but - should instead allow the specified target to recognize it as an - object. When I first made this change, it broke the PE target, - because the specified pei-i386 target did not recognize the - actual pe-i386 archive. Since there may be other problems of - this sort, I changed this test to check only for the binary - target. */ - if (format == bfd_archive && save_targ == &binary_vec) - goto err_unrecog; - } - - for (target = bfd_target_vector; *target != NULL; target++) - { - const bfd_target *temp; - bfd_error_type err; - - /* Don't check the default target twice. */ - if (*target == &binary_vec - || (!abfd->target_defaulted && *target == save_targ) - || (*target)->match_priority > best_match) - continue; - - abfd->xvec = *target; /* Change BFD's target temporarily. */ - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto err_ret; - - /* If _bfd_check_format neglects to set bfd_error, assume - bfd_error_wrong_format. We didn't used to even pay any - attention to bfd_error, so I suspect that some - _bfd_check_format might have this problem. */ - bfd_set_error (bfd_error_wrong_format); - - temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (temp) - match_targ = temp; - - if (temp && (abfd->format != bfd_archive || bfd_has_map (abfd))) - { - /* This format checks out as ok! */ - right_targ = temp; - - /* If this is the default target, accept it, even if other - targets might match. People who want those other targets - have to set the GNUTARGET variable. */ - if (temp == bfd_default_vector[0]) - goto ok_ret; - - if (matching_vector) - matching_vector[match_count] = temp; - match_count++; - - if (temp->match_priority < best_match) - { - best_match = temp->match_priority; - best_count = 0; - } - best_count++; - } - else if (temp - || (err = bfd_get_error ()) == bfd_error_wrong_object_format - || err == bfd_error_file_ambiguously_recognized) - { - /* An archive with no armap or objects of the wrong type, - or an ambiguous match. We want this target to match - if we get no better matches. */ - if (ar_right_targ != bfd_default_vector[0]) - ar_right_targ = *target; - if (matching_vector) - matching_vector[ar_match_index] = *target; - ar_match_index++; - } - else if (err != bfd_error_wrong_format) - goto err_ret; - } - - if (best_count == 1) - match_count = 1; - - if (match_count == 0) - { - /* Try partial matches. */ - right_targ = ar_right_targ; - - if (right_targ == bfd_default_vector[0]) - { - match_count = 1; - } - else - { - match_count = ar_match_index - _bfd_target_vector_entries; - - if (matching_vector && match_count > 1) - memcpy (matching_vector, - matching_vector + _bfd_target_vector_entries, - sizeof (*matching_vector) * match_count); - } - } - - if (match_count > 1) - { - const bfd_target * const *assoc = bfd_associated_vector; - - while ((right_targ = *assoc++) != NULL) - { - int i = match_count; - - while (--i >= 0) - if (matching_vector[i] == right_targ) - break; - - if (i >= 0) - { - match_count = 1; - break; - } - } - } - - if (match_count == 1) - { - abfd->xvec = right_targ; - /* If we come out of the loop knowing that the last target that - matched is the one we want, then ABFD should still be in a usable - state (except possibly for XVEC). */ - if (match_targ != right_targ) - { - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto err_ret; - match_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - } - - ok_ret: - /* If the file was opened for update, then `output_has_begun' - some time ago when the file was created. Do not recompute - sections sizes or alignments in _bfd_set_section_contents. - We can not set this flag until after checking the format, - because it will interfere with creation of BFD sections. */ - if (abfd->direction == both_direction) - abfd->output_has_begun = TRUE; - - if (matching_vector) - free (matching_vector); - return TRUE; /* File position has moved, BTW. */ - } - - if (match_count == 0) - { - err_unrecog: - bfd_set_error (bfd_error_file_not_recognized); - err_ret: - abfd->xvec = save_targ; - abfd->format = bfd_unknown; - if (matching_vector) - free (matching_vector); - return FALSE; - } - - abfd->xvec = save_targ; /* Restore original target type. */ - abfd->format = bfd_unknown; /* Restore original format. */ - bfd_set_error (bfd_error_file_ambiguously_recognized); - - if (matching) - { - *matching = (char **) matching_vector; - matching_vector[match_count] = NULL; - /* Return target names. This is a little nasty. Maybe we - should do another bfd_malloc? */ - while (--match_count >= 0) - { - const char *name = matching_vector[match_count]->name; - *(const char **) &matching_vector[match_count] = name; - } - } - return FALSE; -} - -/* -FUNCTION - bfd_set_format - -SYNOPSIS - bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); - -DESCRIPTION - This function sets the file format of the BFD @var{abfd} to the - format @var{format}. If the target set in the BFD does not - support the format requested, the format is invalid, or the BFD - is not open for writing, then an error occurs. -*/ - -bfd_boolean -bfd_set_format (bfd *abfd, bfd_format format) -{ - if (bfd_read_p (abfd) - || (unsigned int) abfd->format >= (unsigned int) bfd_type_end) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - if (abfd->format != bfd_unknown) - return abfd->format == format; - - /* Presume the answer is yes. */ - abfd->format = format; - - if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) - { - abfd->format = bfd_unknown; - return FALSE; - } - - return TRUE; -} - -/* -FUNCTION - bfd_format_string - -SYNOPSIS - const char *bfd_format_string (bfd_format format); - -DESCRIPTION - Return a pointer to a const string - <>, <>, <>, <>, or <>, - depending upon the value of @var{format}. -*/ - -const char * -bfd_format_string (bfd_format format) -{ - if (((int) format < (int) bfd_unknown) - || ((int) format >= (int) bfd_type_end)) - return "invalid"; - - switch (format) - { - case bfd_object: - return "object"; /* Linker/assembler/compiler output. */ - case bfd_archive: - return "archive"; /* Object archive file. */ - case bfd_core: - return "core"; /* Core dump. */ - default: - return "unknown"; - } -} diff --git a/contrib/binutils-2.22/bfd/genlink.h b/contrib/binutils-2.22/bfd/genlink.h deleted file mode 100644 index 8fb59a5ba7..0000000000 --- a/contrib/binutils-2.22/bfd/genlink.h +++ /dev/null @@ -1,110 +0,0 @@ -/* genlink.h -- interface to the BFD generic linker - Copyright 1993, 1994, 1996, 2002, 2005, 2007 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef GENLINK_H -#define GENLINK_H - -/* This header file is internal to BFD. It describes the internal - structures and functions used by the BFD generic linker, in case - any of the more specific linkers want to use or call them. Note - that some functions, such as _bfd_generic_link_hash_table_create, - are declared in libbfd.h, because they are expected to be widely - used. The functions and structures in this file will probably only - be used by a few files besides linker.c itself. In fact, this file - is not particularly complete; I have only put in the interfaces I - actually needed. */ - -/* The generic linker uses a hash table which is a derived class of - the standard linker hash table, just as the other backend specific - linkers do. Do not confuse the generic linker hash table with the - standard BFD linker hash table it is built upon. */ - -/* Generic linker hash table entries. */ - -struct generic_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Whether this symbol has been written out. */ - bfd_boolean written; - /* Symbol from input BFD. */ - asymbol *sym; -}; - -/* Generic linker hash table. */ - -struct generic_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in a generic link hash table. */ - -#define _bfd_generic_link_hash_lookup(table, string, create, copy, follow) \ - ((struct generic_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse a generic link hash table. */ - -#define _bfd_generic_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ - (info))) - -/* Get the generic link hash table from the info structure. This is - just a cast. */ - -#define _bfd_generic_hash_table(p) \ - ((struct generic_link_hash_table *) ((p)->hash)) - -/* The generic linker reads in the asymbol structures for an input BFD - and keeps them in the outsymbol and symcount fields. */ - -#define _bfd_generic_link_get_symbols(abfd) ((abfd)->outsymbols) -#define _bfd_generic_link_get_symcount(abfd) ((abfd)->symcount) - -/* Add the symbols of input_bfd to the symbols being built for - output_bfd. */ -extern bfd_boolean _bfd_generic_link_output_symbols - (bfd *, bfd *, struct bfd_link_info *, size_t *); - -/* This structure is used to pass information to - _bfd_generic_link_write_global_symbol, which may be called via - _bfd_generic_link_hash_traverse. */ - -struct generic_write_global_symbol_info -{ - struct bfd_link_info *info; - bfd *output_bfd; - size_t *psymalloc; -}; - -/* Write out a single global symbol. This is expected to be called - via _bfd_generic_link_hash_traverse. The second argument must - actually be a struct generic_write_global_symbol_info *. */ -extern bfd_boolean _bfd_generic_link_write_global_symbol - (struct generic_link_hash_entry *, void *); - -/* Generic link hash table entry creation routine. */ -struct bfd_hash_entry *_bfd_generic_link_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); - -#endif diff --git a/contrib/binutils-2.22/bfd/hash.c b/contrib/binutils-2.22/bfd/hash.c deleted file mode 100644 index 1de2c2a85b..0000000000 --- a/contrib/binutils-2.22/bfd/hash.c +++ /dev/null @@ -1,909 +0,0 @@ -/* hash.c -- hash table routines for BFD - Copyright 1993, 1994, 1995, 1997, 1999, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. - Written by Steve Chamberlain - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "objalloc.h" -#include "libiberty.h" - -/* -SECTION - Hash Tables - -@cindex Hash tables - BFD provides a simple set of hash table functions. Routines - are provided to initialize a hash table, to free a hash table, - to look up a string in a hash table and optionally create an - entry for it, and to traverse a hash table. There is - currently no routine to delete an string from a hash table. - - The basic hash table does not permit any data to be stored - with a string. However, a hash table is designed to present a - base class from which other types of hash tables may be - derived. These derived types may store additional information - with the string. Hash tables were implemented in this way, - rather than simply providing a data pointer in a hash table - entry, because they were designed for use by the linker back - ends. The linker may create thousands of hash table entries, - and the overhead of allocating private data and storing and - following pointers becomes noticeable. - - The basic hash table code is in <>. - -@menu -@* Creating and Freeing a Hash Table:: -@* Looking Up or Entering a String:: -@* Traversing a Hash Table:: -@* Deriving a New Hash Table Type:: -@end menu - -INODE -Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables -SUBSECTION - Creating and freeing a hash table - -@findex bfd_hash_table_init -@findex bfd_hash_table_init_n - To create a hash table, create an instance of a <> (defined in <>) and call - <> (if you know approximately how many - entries you will need, the function <>, - which takes a @var{size} argument, may be used). - <> returns <> if some sort of - error occurs. - -@findex bfd_hash_newfunc - The function <> take as an argument a - function to use to create new entries. For a basic hash - table, use the function <>. @xref{Deriving - a New Hash Table Type}, for why you would want to use a - different value for this argument. - -@findex bfd_hash_allocate - <> will create an objalloc which will be - used to allocate new entries. You may allocate memory on this - objalloc using <>. - -@findex bfd_hash_table_free - Use <> to free up all the memory that has - been allocated for a hash table. This will not free up the - <> itself, which you must provide. - -@findex bfd_hash_set_default_size - Use <> to set the default size of - hash table to use. - -INODE -Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables -SUBSECTION - Looking up or entering a string - -@findex bfd_hash_lookup - The function <> is used both to look up a - string in the hash table and to create a new entry. - - If the @var{create} argument is <>, <> - will look up a string. If the string is found, it will - returns a pointer to a <>. If the - string is not found in the table <> will - return <>. You should not modify any of the fields in - the returns <>. - - If the @var{create} argument is <>, the string will be - entered into the hash table if it is not already there. - Either way a pointer to a <> will be - returned, either to the existing structure or to a newly - created one. In this case, a <> return means that an - error occurred. - - If the @var{create} argument is <>, and a new entry is - created, the @var{copy} argument is used to decide whether to - copy the string onto the hash table objalloc or not. If - @var{copy} is passed as <>, you must be careful not to - deallocate or modify the string as long as the hash table - exists. - -INODE -Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables -SUBSECTION - Traversing a hash table - -@findex bfd_hash_traverse - The function <> may be used to traverse a - hash table, calling a function on each element. The traversal - is done in a random order. - - <> takes as arguments a function and a - generic <> pointer. The function is called with a - hash table entry (a <>) and the - generic pointer passed to <>. The function - must return a <> value, which indicates whether to - continue traversing the hash table. If the function returns - <>, <> will stop the traversal and - return immediately. - -INODE -Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables -SUBSECTION - Deriving a new hash table type - - Many uses of hash tables want to store additional information - which each entry in the hash table. Some also find it - convenient to store additional information with the hash table - itself. This may be done using a derived hash table. - - Since C is not an object oriented language, creating a derived - hash table requires sticking together some boilerplate - routines with a few differences specific to the type of hash - table you want to create. - - An example of a derived hash table is the linker hash table. - The structures for this are defined in <>. The - functions are in <>. - - You may also derive a hash table from an already derived hash - table. For example, the a.out linker backend code uses a hash - table derived from the linker hash table. - -@menu -@* Define the Derived Structures:: -@* Write the Derived Creation Routine:: -@* Write Other Derived Routines:: -@end menu - -INODE -Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type -SUBSUBSECTION - Define the derived structures - - You must define a structure for an entry in the hash table, - and a structure for the hash table itself. - - The first field in the structure for an entry in the hash - table must be of the type used for an entry in the hash table - you are deriving from. If you are deriving from a basic hash - table this is <>, which is defined in - <>. The first field in the structure for the hash - table itself must be of the type of the hash table you are - deriving from itself. If you are deriving from a basic hash - table, this is <>. - - For example, the linker hash table defines <> (in <>). The first field, - <>, is of type <>. Similarly, - the first field in <>, <>, - is of type <>. - -INODE -Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type -SUBSUBSECTION - Write the derived creation routine - - You must write a routine which will create and initialize an - entry in the hash table. This routine is passed as the - function argument to <>. - - In order to permit other hash tables to be derived from the - hash table you are creating, this routine must be written in a - standard way. - - The first argument to the creation routine is a pointer to a - hash table entry. This may be <>, in which case the - routine should allocate the right amount of space. Otherwise - the space has already been allocated by a hash table type - derived from this one. - - After allocating space, the creation routine must call the - creation routine of the hash table type it is derived from, - passing in a pointer to the space it just allocated. This - will initialize any fields used by the base hash table. - - Finally the creation routine must initialize any local fields - for the new hash table type. - - Here is a boilerplate example of a creation routine. - @var{function_name} is the name of the routine. - @var{entry_type} is the type of an entry in the hash table you - are creating. @var{base_newfunc} is the name of the creation - routine of the hash table type your hash table is derived - from. - -EXAMPLE - -.struct bfd_hash_entry * -.@var{function_name} (struct bfd_hash_entry *entry, -. struct bfd_hash_table *table, -. const char *string) -.{ -. struct @var{entry_type} *ret = (@var{entry_type} *) entry; -. -. {* Allocate the structure if it has not already been allocated by a -. derived class. *} -. if (ret == NULL) -. { -. ret = bfd_hash_allocate (table, sizeof (* ret)); -. if (ret == NULL) -. return NULL; -. } -. -. {* Call the allocation method of the base class. *} -. ret = ((@var{entry_type} *) -. @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); -. -. {* Initialize the local fields here. *} -. -. return (struct bfd_hash_entry *) ret; -.} - -DESCRIPTION - The creation routine for the linker hash table, which is in - <>, looks just like this example. - @var{function_name} is <<_bfd_link_hash_newfunc>>. - @var{entry_type} is <>. - @var{base_newfunc} is <>, the creation - routine for a basic hash table. - - <<_bfd_link_hash_newfunc>> also initializes the local fields - in a linker hash table entry: <>, <> and - <>. - -INODE -Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type -SUBSUBSECTION - Write other derived routines - - You will want to write other routines for your new hash table, - as well. - - You will want an initialization routine which calls the - initialization routine of the hash table you are deriving from - and initializes any other local fields. For the linker hash - table, this is <<_bfd_link_hash_table_init>> in <>. - - You will want a lookup routine which calls the lookup routine - of the hash table you are deriving from and casts the result. - The linker hash table uses <> in - <> (this actually takes an additional argument which - it uses to decide how to return the looked up value). - - You may want a traversal routine. This should just call the - traversal routine of the hash table you are deriving from with - appropriate casts. The linker hash table uses - <> in <>. - - These routines may simply be defined as macros. For example, - the a.out backend linker hash table, which is derived from the - linker hash table, uses macros for the lookup and traversal - routines. These are <> and - <> in aoutx.h. -*/ - -/* The default number of entries to use when creating a hash table. */ -#define DEFAULT_SIZE 4051 - -/* The following function returns a nearest prime number which is - greater than N, and near a power of two. Copied from libiberty. - Returns zero for ridiculously large N to signify an error. */ - -static unsigned long -higher_prime_number (unsigned long n) -{ - /* These are primes that are near, but slightly smaller than, a - power of two. */ - static const unsigned long primes[] = - { - (unsigned long) 31, - (unsigned long) 61, - (unsigned long) 127, - (unsigned long) 251, - (unsigned long) 509, - (unsigned long) 1021, - (unsigned long) 2039, - (unsigned long) 4093, - (unsigned long) 8191, - (unsigned long) 16381, - (unsigned long) 32749, - (unsigned long) 65521, - (unsigned long) 131071, - (unsigned long) 262139, - (unsigned long) 524287, - (unsigned long) 1048573, - (unsigned long) 2097143, - (unsigned long) 4194301, - (unsigned long) 8388593, - (unsigned long) 16777213, - (unsigned long) 33554393, - (unsigned long) 67108859, - (unsigned long) 134217689, - (unsigned long) 268435399, - (unsigned long) 536870909, - (unsigned long) 1073741789, - (unsigned long) 2147483647, - /* 4294967291L */ - ((unsigned long) 2147483647) + ((unsigned long) 2147483644), - }; - - const unsigned long *low = &primes[0]; - const unsigned long *high = &primes[sizeof (primes) / sizeof (primes[0])]; - - while (low != high) - { - const unsigned long *mid = low + (high - low) / 2; - if (n >= *mid) - low = mid + 1; - else - high = mid; - } - - if (n >= *low) - return 0; - - return *low; -} - -static unsigned long bfd_default_hash_table_size = DEFAULT_SIZE; - -/* Create a new hash table, given a number of entries. */ - -bfd_boolean -bfd_hash_table_init_n (struct bfd_hash_table *table, - struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int entsize, - unsigned int size) -{ - unsigned long alloc; - - alloc = size; - alloc *= sizeof (struct bfd_hash_entry *); - if (alloc / sizeof (struct bfd_hash_entry *) != size) - { - bfd_set_error (bfd_error_no_memory); - return FALSE; - } - - table->memory = (void *) objalloc_create (); - if (table->memory == NULL) - { - bfd_set_error (bfd_error_no_memory); - return FALSE; - } - table->table = (struct bfd_hash_entry **) - objalloc_alloc ((struct objalloc *) table->memory, alloc); - if (table->table == NULL) - { - bfd_set_error (bfd_error_no_memory); - return FALSE; - } - memset ((void *) table->table, 0, alloc); - table->size = size; - table->entsize = entsize; - table->count = 0; - table->frozen = 0; - table->newfunc = newfunc; - return TRUE; -} - -/* Create a new hash table with the default number of entries. */ - -bfd_boolean -bfd_hash_table_init (struct bfd_hash_table *table, - struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int entsize) -{ - return bfd_hash_table_init_n (table, newfunc, entsize, - bfd_default_hash_table_size); -} - -/* Free a hash table. */ - -void -bfd_hash_table_free (struct bfd_hash_table *table) -{ - objalloc_free ((struct objalloc *) table->memory); - table->memory = NULL; -} - -static inline unsigned long -bfd_hash_hash (const char *string, unsigned int *lenp) -{ - const unsigned char *s; - unsigned long hash; - unsigned int len; - unsigned int c; - - hash = 0; - len = 0; - s = (const unsigned char *) string; - while ((c = *s++) != '\0') - { - hash += c + (c << 17); - hash ^= hash >> 2; - } - len = (s - (const unsigned char *) string) - 1; - hash += len + (len << 17); - hash ^= hash >> 2; - if (lenp != NULL) - *lenp = len; - return hash; -} - -/* Look up a string in a hash table. */ - -struct bfd_hash_entry * -bfd_hash_lookup (struct bfd_hash_table *table, - const char *string, - bfd_boolean create, - bfd_boolean copy) -{ - unsigned long hash; - struct bfd_hash_entry *hashp; - unsigned int len; - unsigned int _index; - - hash = bfd_hash_hash (string, &len); - _index = hash % table->size; - for (hashp = table->table[_index]; - hashp != NULL; - hashp = hashp->next) - { - if (hashp->hash == hash - && strcmp (hashp->string, string) == 0) - return hashp; - } - - if (! create) - return NULL; - - if (copy) - { - char *new_string; - - new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory, - len + 1); - if (!new_string) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - memcpy (new_string, string, len + 1); - string = new_string; - } - - return bfd_hash_insert (table, string, hash); -} - -/* Insert an entry in a hash table. */ - -struct bfd_hash_entry * -bfd_hash_insert (struct bfd_hash_table *table, - const char *string, - unsigned long hash) -{ - struct bfd_hash_entry *hashp; - unsigned int _index; - - hashp = (*table->newfunc) (NULL, table, string); - if (hashp == NULL) - return NULL; - hashp->string = string; - hashp->hash = hash; - _index = hash % table->size; - hashp->next = table->table[_index]; - table->table[_index] = hashp; - table->count++; - - if (!table->frozen && table->count > table->size * 3 / 4) - { - unsigned long newsize = higher_prime_number (table->size); - struct bfd_hash_entry **newtable; - unsigned int hi; - unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *); - - /* If we can't find a higher prime, or we can't possibly alloc - that much memory, don't try to grow the table. */ - if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize) - { - table->frozen = 1; - return hashp; - } - - newtable = ((struct bfd_hash_entry **) - objalloc_alloc ((struct objalloc *) table->memory, alloc)); - if (newtable == NULL) - { - table->frozen = 1; - return hashp; - } - memset ((PTR) newtable, 0, alloc); - - for (hi = 0; hi < table->size; hi ++) - while (table->table[hi]) - { - struct bfd_hash_entry *chain = table->table[hi]; - struct bfd_hash_entry *chain_end = chain; - - while (chain_end->next && chain_end->next->hash == chain->hash) - chain_end = chain_end->next; - - table->table[hi] = chain_end->next; - _index = chain->hash % newsize; - chain_end->next = newtable[_index]; - newtable[_index] = chain; - } - table->table = newtable; - table->size = newsize; - } - - return hashp; -} - -/* Rename an entry in a hash table. */ - -void -bfd_hash_rename (struct bfd_hash_table *table, - const char *string, - struct bfd_hash_entry *ent) -{ - unsigned int _index; - struct bfd_hash_entry **pph; - - _index = ent->hash % table->size; - for (pph = &table->table[_index]; *pph != NULL; pph = &(*pph)->next) - if (*pph == ent) - break; - if (*pph == NULL) - abort (); - - *pph = ent->next; - ent->string = string; - ent->hash = bfd_hash_hash (string, NULL); - _index = ent->hash % table->size; - ent->next = table->table[_index]; - table->table[_index] = ent; -} - -/* Replace an entry in a hash table. */ - -void -bfd_hash_replace (struct bfd_hash_table *table, - struct bfd_hash_entry *old, - struct bfd_hash_entry *nw) -{ - unsigned int _index; - struct bfd_hash_entry **pph; - - _index = old->hash % table->size; - for (pph = &table->table[_index]; - (*pph) != NULL; - pph = &(*pph)->next) - { - if (*pph == old) - { - *pph = nw; - return; - } - } - - abort (); -} - -/* Allocate space in a hash table. */ - -void * -bfd_hash_allocate (struct bfd_hash_table *table, - unsigned int size) -{ - void * ret; - - ret = objalloc_alloc ((struct objalloc *) table->memory, size); - if (ret == NULL && size != 0) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -/* Base method for creating a new hash table entry. */ - -struct bfd_hash_entry * -bfd_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string ATTRIBUTE_UNUSED) -{ - if (entry == NULL) - entry = (struct bfd_hash_entry *) bfd_hash_allocate (table, - sizeof (* entry)); - return entry; -} - -/* Traverse a hash table. */ - -void -bfd_hash_traverse (struct bfd_hash_table *table, - bfd_boolean (*func) (struct bfd_hash_entry *, void *), - void * info) -{ - unsigned int i; - - table->frozen = 1; - for (i = 0; i < table->size; i++) - { - struct bfd_hash_entry *p; - - for (p = table->table[i]; p != NULL; p = p->next) - if (! (*func) (p, info)) - goto out; - } - out: - table->frozen = 0; -} - -unsigned long -bfd_hash_set_default_size (unsigned long hash_size) -{ - /* Extend this prime list if you want more granularity of hash table size. */ - static const unsigned long hash_size_primes[] = - { - 31, 61, 127, 251, 509, 1021, 2039, 4091, 8191, 16381, 32749, 65537 - }; - unsigned int _index; - - /* Work out best prime number near the hash_size. */ - for (_index = 0; _index < ARRAY_SIZE (hash_size_primes) - 1; ++_index) - if (hash_size <= hash_size_primes[_index]) - break; - - bfd_default_hash_table_size = hash_size_primes[_index]; - return bfd_default_hash_table_size; -} - -/* A few different object file formats (a.out, COFF, ELF) use a string - table. These functions support adding strings to a string table, - returning the byte offset, and writing out the table. - - Possible improvements: - + look for strings matching trailing substrings of other strings - + better data structures? balanced trees? - + look at reducing memory use elsewhere -- maybe if we didn't have - to construct the entire symbol table at once, we could get by - with smaller amounts of VM? (What effect does that have on the - string table reductions?) */ - -/* An entry in the strtab hash table. */ - -struct strtab_hash_entry -{ - struct bfd_hash_entry root; - /* Index in string table. */ - bfd_size_type index; - /* Next string in strtab. */ - struct strtab_hash_entry *next; -}; - -/* The strtab hash table. */ - -struct bfd_strtab_hash -{ - struct bfd_hash_table table; - /* Size of strtab--also next available index. */ - bfd_size_type size; - /* First string in strtab. */ - struct strtab_hash_entry *first; - /* Last string in strtab. */ - struct strtab_hash_entry *last; - /* Whether to precede strings with a two byte length, as in the - XCOFF .debug section. */ - bfd_boolean xcoff; -}; - -/* Routine to create an entry in a strtab. */ - -static struct bfd_hash_entry * -strtab_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = (struct strtab_hash_entry *) bfd_hash_allocate (table, - sizeof (* ret)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = (struct strtab_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string); - - if (ret) - { - /* Initialize the local fields. */ - ret->index = (bfd_size_type) -1; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in an strtab. */ - -#define strtab_hash_lookup(t, string, create, copy) \ - ((struct strtab_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Create a new strtab. */ - -struct bfd_strtab_hash * -_bfd_stringtab_init (void) -{ - struct bfd_strtab_hash *table; - bfd_size_type amt = sizeof (* table); - - table = (struct bfd_strtab_hash *) bfd_malloc (amt); - if (table == NULL) - return NULL; - - if (!bfd_hash_table_init (&table->table, strtab_hash_newfunc, - sizeof (struct strtab_hash_entry))) - { - free (table); - return NULL; - } - - table->size = 0; - table->first = NULL; - table->last = NULL; - table->xcoff = FALSE; - - return table; -} - -/* Create a new strtab in which the strings are output in the format - used in the XCOFF .debug section: a two byte length precedes each - string. */ - -struct bfd_strtab_hash * -_bfd_xcoff_stringtab_init (void) -{ - struct bfd_strtab_hash *ret; - - ret = _bfd_stringtab_init (); - if (ret != NULL) - ret->xcoff = TRUE; - return ret; -} - -/* Free a strtab. */ - -void -_bfd_stringtab_free (struct bfd_strtab_hash *table) -{ - bfd_hash_table_free (&table->table); - free (table); -} - -/* Get the index of a string in a strtab, adding it if it is not - already present. If HASH is FALSE, we don't really use the hash - table, and we don't eliminate duplicate strings. */ - -bfd_size_type -_bfd_stringtab_add (struct bfd_strtab_hash *tab, - const char *str, - bfd_boolean hash, - bfd_boolean copy) -{ - struct strtab_hash_entry *entry; - - if (hash) - { - entry = strtab_hash_lookup (tab, str, TRUE, copy); - if (entry == NULL) - return (bfd_size_type) -1; - } - else - { - entry = (struct strtab_hash_entry *) bfd_hash_allocate (&tab->table, - sizeof (* entry)); - if (entry == NULL) - return (bfd_size_type) -1; - if (! copy) - entry->root.string = str; - else - { - char *n; - - n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1); - if (n == NULL) - return (bfd_size_type) -1; - entry->root.string = n; - } - entry->index = (bfd_size_type) -1; - entry->next = NULL; - } - - if (entry->index == (bfd_size_type) -1) - { - entry->index = tab->size; - tab->size += strlen (str) + 1; - if (tab->xcoff) - { - entry->index += 2; - tab->size += 2; - } - if (tab->first == NULL) - tab->first = entry; - else - tab->last->next = entry; - tab->last = entry; - } - - return entry->index; -} - -/* Get the number of bytes in a strtab. */ - -bfd_size_type -_bfd_stringtab_size (struct bfd_strtab_hash *tab) -{ - return tab->size; -} - -/* Write out a strtab. ABFD must already be at the right location in - the file. */ - -bfd_boolean -_bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab) -{ - bfd_boolean xcoff; - struct strtab_hash_entry *entry; - - xcoff = tab->xcoff; - - for (entry = tab->first; entry != NULL; entry = entry->next) - { - const char *str; - size_t len; - - str = entry->root.string; - len = strlen (str) + 1; - - if (xcoff) - { - bfd_byte buf[2]; - - /* The output length includes the null byte. */ - bfd_put_16 (abfd, (bfd_vma) len, buf); - if (bfd_bwrite ((void *) buf, (bfd_size_type) 2, abfd) != 2) - return FALSE; - } - - if (bfd_bwrite ((void *) str, (bfd_size_type) len, abfd) != len) - return FALSE; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/ihex.c b/contrib/binutils-2.22/bfd/ihex.c deleted file mode 100644 index 09f756a1c2..0000000000 --- a/contrib/binutils-2.22/bfd/ihex.c +++ /dev/null @@ -1,1001 +0,0 @@ -/* BFD back-end for Intel Hex objects. - Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2009, 2011 Free Software Foundation, Inc. - Written by Ian Lance Taylor of Cygnus Support . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* This is what Intel Hex files look like: - -1. INTEL FORMATS - -A. Intel 1 - - 16-bit address-field format, for files 64k bytes in length or less. - - DATA RECORD - Byte 1 Header = colon(:) - 2..3 The number of data bytes in hex notation - 4..5 High byte of the record load address - 6..7 Low byte of the record load address - 8..9 Record type, must be "00" - 10..x Data bytes in hex notation: - x = (number of bytes - 1) * 2 + 11 - x+1..x+2 Checksum in hex notation - x+3..x+4 Carriage return, line feed - - END RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "00" - 4..7 Transfer-address (usually "0000") - the jump-to address, execution start address - 8..9 Record type, must be "01" - 10..11 Checksum, in hex notation - 12..13 Carriage return, line feed - -B. INTEL 2 - - MCS-86 format, using a 20-bit address for files larger than 64K bytes. - - DATA RECORD - Byte 1 Header = colon (:) - 2..3 The byte count of this record, hex notation - 4..5 High byte of the record load address - 6..7 Low byte of the record load address - 8..9 Record type, must be "00" - 10..x The data bytes in hex notation: - x = (number of data bytes - 1) * 2 + 11 - x+1..x+2 Checksum in hex notation - x+3..x+4 Carriage return, line feed - - EXTENDED ADDRESS RECORD - Byte 1 Header = colon(:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "02" - 10..11 High byte of the offset address - 12..13 Low byte of the offset address - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed - - The checksums are the two's complement of the 8-bit sum - without carry of the byte count, offset address, and the - record type. - - START ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "04" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "03" - 10..13 8086 CS value - 14..17 8086 IP value - 18..19 Checksum in hex notation - 20..21 Carriage return, line feed - -Another document reports these additional types: - - EXTENDED LINEAR ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "04" - 10..13 Upper 16 bits of address of subsequent records - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed - - START LINEAR ADDRESS RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "02" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "05" - 10..13 Upper 16 bits of start address - 14..15 Checksum in hex notation - 16..17 Carriage return, line feed - -The MRI compiler uses this, which is a repeat of type 5: - - EXTENDED START RECORD - Byte 1 Header = colon (:) - 2..3 The byte count, must be "04" - 4..7 Load address, must be "0000" - 8..9 Record type, must be "05" - 10..13 Upper 16 bits of start address - 14..17 Lower 16 bits of start address - 18..19 Checksum in hex notation - 20..21 Carriage return, line feed. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "libiberty.h" -#include "safe-ctype.h" - -/* The number of bytes we put on one line during output. */ - -#define CHUNK 16 - -/* Macros for converting between hex and binary. */ - -#define NIBBLE(x) (hex_value (x)) -#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1])) -#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2)) -#define ISHEX(x) (hex_p (x)) - -/* When we write out an ihex value, the values can not be output as - they are seen. Instead, we hold them in memory in this structure. */ - -struct ihex_data_list -{ - struct ihex_data_list *next; - bfd_byte *data; - bfd_vma where; - bfd_size_type size; -}; - -/* The ihex tdata information. */ - -struct ihex_data_struct -{ - struct ihex_data_list *head; - struct ihex_data_list *tail; -}; - -/* Initialize by filling in the hex conversion array. */ - -static void -ihex_init (void) -{ - static bfd_boolean inited; - - if (! inited) - { - inited = TRUE; - hex_init (); - } -} - -/* Create an ihex object. */ - -static bfd_boolean -ihex_mkobject (bfd *abfd) -{ - struct ihex_data_struct *tdata; - - tdata = (struct ihex_data_struct *) bfd_alloc (abfd, sizeof (* tdata)); - if (tdata == NULL) - return FALSE; - - abfd->tdata.ihex_data = tdata; - tdata->head = NULL; - tdata->tail = NULL; - return TRUE; -} - -/* Read a byte from a BFD. Set *ERRORPTR if an error occurred. - Return EOF on error or end of file. */ - -static INLINE int -ihex_get_byte (bfd *abfd, bfd_boolean *errorptr) -{ - bfd_byte c; - - if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1) - { - if (bfd_get_error () != bfd_error_file_truncated) - *errorptr = TRUE; - return EOF; - } - - return (int) (c & 0xff); -} - -/* Report a problem in an Intel Hex file. */ - -static void -ihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bfd_boolean error) -{ - if (c == EOF) - { - if (! error) - bfd_set_error (bfd_error_file_truncated); - } - else - { - char buf[10]; - - if (! ISPRINT (c)) - sprintf (buf, "\\%03o", (unsigned int) c); - else - { - buf[0] = c; - buf[1] = '\0'; - } - (*_bfd_error_handler) - (_("%B:%d: unexpected character `%s' in Intel Hex file"), - abfd, lineno, buf); - bfd_set_error (bfd_error_bad_value); - } -} - -/* Read an Intel hex file and turn it into sections. We create a new - section for each contiguous set of bytes. */ - -static bfd_boolean -ihex_scan (bfd *abfd) -{ - bfd_vma segbase; - bfd_vma extbase; - asection *sec; - unsigned int lineno; - bfd_boolean error; - bfd_byte *buf = NULL; - size_t bufsize; - int c; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - abfd->start_address = 0; - - segbase = 0; - extbase = 0; - sec = NULL; - lineno = 1; - error = FALSE; - bufsize = 0; - - while ((c = ihex_get_byte (abfd, &error)) != EOF) - { - if (c == '\r') - continue; - else if (c == '\n') - { - ++lineno; - continue; - } - else if (c != ':') - { - ihex_bad_byte (abfd, lineno, c, error); - goto error_return; - } - else - { - file_ptr pos; - char hdr[8]; - unsigned int i; - unsigned int len; - bfd_vma addr; - unsigned int type; - unsigned int chars; - unsigned int chksum; - - /* This is a data record. */ - pos = bfd_tell (abfd) - 1; - - /* Read the header bytes. */ - if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8) - goto error_return; - - for (i = 0; i < 8; i++) - { - if (! ISHEX (hdr[i])) - { - ihex_bad_byte (abfd, lineno, hdr[i], error); - goto error_return; - } - } - - len = HEX2 (hdr); - addr = HEX4 (hdr + 2); - type = HEX2 (hdr + 6); - - /* Read the data bytes. */ - chars = len * 2 + 2; - if (chars >= bufsize) - { - buf = (bfd_byte *) bfd_realloc (buf, (bfd_size_type) chars); - if (buf == NULL) - goto error_return; - bufsize = chars; - } - - if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars) - goto error_return; - - for (i = 0; i < chars; i++) - { - if (! ISHEX (buf[i])) - { - ihex_bad_byte (abfd, lineno, hdr[i], error); - goto error_return; - } - } - - /* Check the checksum. */ - chksum = len + addr + (addr >> 8) + type; - for (i = 0; i < len; i++) - chksum += HEX2 (buf + 2 * i); - if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i)) - { - (*_bfd_error_handler) - (_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"), - abfd, lineno, - (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i)); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - switch (type) - { - case 0: - /* This is a data record. */ - if (sec != NULL - && sec->vma + sec->size == extbase + segbase + addr) - { - /* This data goes at the end of the section we are - currently building. */ - sec->size += len; - } - else if (len > 0) - { - char secbuf[20]; - char *secname; - bfd_size_type amt; - flagword flags; - - sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); - amt = strlen (secbuf) + 1; - secname = (char *) bfd_alloc (abfd, amt); - if (secname == NULL) - goto error_return; - strcpy (secname, secbuf); - flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - sec = bfd_make_section_with_flags (abfd, secname, flags); - if (sec == NULL) - goto error_return; - sec->vma = extbase + segbase + addr; - sec->lma = extbase + segbase + addr; - sec->size = len; - sec->filepos = pos; - } - break; - - case 1: - /* An end record. */ - if (abfd->start_address == 0) - abfd->start_address = addr; - if (buf != NULL) - free (buf); - return TRUE; - - case 2: - /* An extended address record. */ - if (len != 2) - { - (*_bfd_error_handler) - (_("%B:%u: bad extended address record length in Intel Hex file"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - segbase = HEX4 (buf) << 4; - - sec = NULL; - - break; - - case 3: - /* An extended start address record. */ - if (len != 4) - { - (*_bfd_error_handler) - (_("%B:%u: bad extended start address length in Intel Hex file"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4); - - sec = NULL; - - break; - - case 4: - /* An extended linear address record. */ - if (len != 2) - { - (*_bfd_error_handler) - (_("%B:%u: bad extended linear address record length in Intel Hex file"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - extbase = HEX4 (buf) << 16; - - sec = NULL; - - break; - - case 5: - /* An extended linear start address record. */ - if (len != 2 && len != 4) - { - (*_bfd_error_handler) - (_("%B:%u: bad extended linear start address length in Intel Hex file"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (len == 2) - abfd->start_address += HEX4 (buf) << 16; - else - abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4); - - sec = NULL; - - break; - - default: - (*_bfd_error_handler) - (_("%B:%u: unrecognized ihex type %u in Intel Hex file"), - abfd, lineno, type); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - } - } - - if (error) - goto error_return; - - if (buf != NULL) - free (buf); - - return TRUE; - - error_return: - if (buf != NULL) - free (buf); - return FALSE; -} - -/* Try to recognize an Intel Hex file. */ - -static const bfd_target * -ihex_object_p (bfd *abfd) -{ - void * tdata_save; - bfd_byte b[9]; - unsigned int i; - unsigned int type; - - ihex_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return NULL; - if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9) - { - if (bfd_get_error () == bfd_error_file_truncated) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (b[0] != ':') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - for (i = 1; i < 9; i++) - { - if (! ISHEX (b[i])) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - } - - type = HEX2 (b + 7); - if (type > 5) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* OK, it looks like it really is an Intel Hex file. */ - tdata_save = abfd->tdata.any; - if (! ihex_mkobject (abfd) || ! ihex_scan (abfd)) - { - if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) - bfd_release (abfd, abfd->tdata.any); - abfd->tdata.any = tdata_save; - return NULL; - } - - return abfd->xvec; -} - -/* Read the contents of a section in an Intel Hex file. */ - -static bfd_boolean -ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents) -{ - int c; - bfd_byte *p; - bfd_byte *buf = NULL; - size_t bufsize; - bfd_boolean error; - - if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0) - goto error_return; - - p = contents; - bufsize = 0; - error = FALSE; - while ((c = ihex_get_byte (abfd, &error)) != EOF) - { - char hdr[8]; - unsigned int len; - unsigned int type; - unsigned int i; - - if (c == '\r' || c == '\n') - continue; - - /* This is called after ihex_scan has succeeded, so we ought to - know the exact format. */ - BFD_ASSERT (c == ':'); - - if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8) - goto error_return; - - len = HEX2 (hdr); - type = HEX2 (hdr + 6); - - /* We should only see type 0 records here. */ - if (type != 0) - { - (*_bfd_error_handler) - (_("%B: internal error in ihex_read_section"), abfd); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (len * 2 > bufsize) - { - buf = (bfd_byte *) bfd_realloc (buf, (bfd_size_type) len * 2); - if (buf == NULL) - goto error_return; - bufsize = len * 2; - } - - if (bfd_bread (buf, (bfd_size_type) len * 2, abfd) != len * 2) - goto error_return; - - for (i = 0; i < len; i++) - *p++ = HEX2 (buf + 2 * i); - if ((bfd_size_type) (p - contents) >= section->size) - { - /* We've read everything in the section. */ - if (buf != NULL) - free (buf); - return TRUE; - } - - /* Skip the checksum. */ - if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2) - goto error_return; - } - - if ((bfd_size_type) (p - contents) < section->size) - { - (*_bfd_error_handler) - (_("%B: bad section length in ihex_read_section"), abfd); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (buf != NULL) - free (buf); - - return TRUE; - - error_return: - if (buf != NULL) - free (buf); - return FALSE; -} - -/* Get the contents of a section in an Intel Hex file. */ - -static bfd_boolean -ihex_get_section_contents (bfd *abfd, - asection *section, - void * location, - file_ptr offset, - bfd_size_type count) -{ - if (section->used_by_bfd == NULL) - { - section->used_by_bfd = bfd_alloc (abfd, section->size); - if (section->used_by_bfd == NULL) - return FALSE; - if (! ihex_read_section (abfd, section, - (bfd_byte *) section->used_by_bfd)) - return FALSE; - } - - memcpy (location, (bfd_byte *) section->used_by_bfd + offset, - (size_t) count); - - return TRUE; -} - -/* Set the contents of a section in an Intel Hex file. */ - -static bfd_boolean -ihex_set_section_contents (bfd *abfd, - asection *section, - const void * location, - file_ptr offset, - bfd_size_type count) -{ - struct ihex_data_list *n; - bfd_byte *data; - struct ihex_data_struct *tdata; - - if (count == 0 - || (section->flags & SEC_ALLOC) == 0 - || (section->flags & SEC_LOAD) == 0) - return TRUE; - - n = (struct ihex_data_list *) bfd_alloc (abfd, sizeof (* n)); - if (n == NULL) - return FALSE; - - data = (bfd_byte *) bfd_alloc (abfd, count); - if (data == NULL) - return FALSE; - memcpy (data, location, (size_t) count); - - n->data = data; - n->where = section->lma + offset; - n->size = count; - - /* Sort the records by address. Optimize for the common case of - adding a record to the end of the list. */ - tdata = abfd->tdata.ihex_data; - if (tdata->tail != NULL - && n->where >= tdata->tail->where) - { - tdata->tail->next = n; - n->next = NULL; - tdata->tail = n; - } - else - { - struct ihex_data_list **pp; - - for (pp = &tdata->head; - *pp != NULL && (*pp)->where < n->where; - pp = &(*pp)->next) - ; - n->next = *pp; - *pp = n; - if (n->next == NULL) - tdata->tail = n; - } - - return TRUE; -} - -/* Write a record out to an Intel Hex file. */ - -static bfd_boolean -ihex_write_record (bfd *abfd, - size_t count, - unsigned int addr, - unsigned int type, - bfd_byte *data) -{ - static const char digs[] = "0123456789ABCDEF"; - char buf[9 + CHUNK * 2 + 4]; - char *p; - unsigned int chksum; - unsigned int i; - size_t total; - -#define TOHEX(buf, v) \ - ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf]) - - buf[0] = ':'; - TOHEX (buf + 1, count); - TOHEX (buf + 3, (addr >> 8) & 0xff); - TOHEX (buf + 5, addr & 0xff); - TOHEX (buf + 7, type); - - chksum = count + addr + (addr >> 8) + type; - - for (i = 0, p = buf + 9; i < count; i++, p += 2, data++) - { - TOHEX (p, *data); - chksum += *data; - } - - TOHEX (p, (- chksum) & 0xff); - p[2] = '\r'; - p[3] = '\n'; - - total = 9 + count * 2 + 4; - if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total) - return FALSE; - - return TRUE; -} - -/* Write out an Intel Hex file. */ - -static bfd_boolean -ihex_write_object_contents (bfd *abfd) -{ - bfd_vma segbase; - bfd_vma extbase; - struct ihex_data_list *l; - - segbase = 0; - extbase = 0; - for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next) - { - bfd_vma where; - bfd_byte *p; - bfd_size_type count; - - where = l->where; - p = l->data; - count = l->size; - - while (count > 0) - { - size_t now; - unsigned int rec_addr; - - now = count; - if (count > CHUNK) - now = CHUNK; - - if (where > segbase + extbase + 0xffff) - { - bfd_byte addr[2]; - - /* We need a new base address. */ - if (where <= 0xfffff) - { - /* The addresses should be sorted. */ - BFD_ASSERT (extbase == 0); - - segbase = where & 0xf0000; - addr[0] = (bfd_byte)(segbase >> 12) & 0xff; - addr[1] = (bfd_byte)(segbase >> 4) & 0xff; - if (! ihex_write_record (abfd, 2, 0, 2, addr)) - return FALSE; - } - else - { - /* The extended address record and the extended - linear address record are combined, at least by - some readers. We need an extended linear address - record here, so if we've already written out an - extended address record, zero it out to avoid - confusion. */ - if (segbase != 0) - { - addr[0] = 0; - addr[1] = 0; - if (! ihex_write_record (abfd, 2, 0, 2, addr)) - return FALSE; - segbase = 0; - } - - extbase = where & 0xffff0000; - if (where > extbase + 0xffff) - { - char buf[20]; - - sprintf_vma (buf, where); - (*_bfd_error_handler) - (_("%s: address 0x%s out of range for Intel Hex file"), - bfd_get_filename (abfd), buf); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - addr[0] = (bfd_byte)(extbase >> 24) & 0xff; - addr[1] = (bfd_byte)(extbase >> 16) & 0xff; - if (! ihex_write_record (abfd, 2, 0, 4, addr)) - return FALSE; - } - } - - rec_addr = where - (extbase + segbase); - - /* Output records shouldn't cross 64K boundaries. */ - if (rec_addr + now > 0xffff) - now = 0x10000 - rec_addr; - - if (! ihex_write_record (abfd, now, rec_addr, 0, p)) - return FALSE; - - where += now; - p += now; - count -= now; - } - } - - if (abfd->start_address != 0) - { - bfd_vma start; - bfd_byte startbuf[4]; - - start = abfd->start_address; - - if (start <= 0xfffff) - { - startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff; - startbuf[1] = 0; - startbuf[2] = (bfd_byte)(start >> 8) & 0xff; - startbuf[3] = (bfd_byte)start & 0xff; - if (! ihex_write_record (abfd, 4, 0, 3, startbuf)) - return FALSE; - } - else - { - startbuf[0] = (bfd_byte)(start >> 24) & 0xff; - startbuf[1] = (bfd_byte)(start >> 16) & 0xff; - startbuf[2] = (bfd_byte)(start >> 8) & 0xff; - startbuf[3] = (bfd_byte)start & 0xff; - if (! ihex_write_record (abfd, 4, 0, 5, startbuf)) - return FALSE; - } - } - - if (! ihex_write_record (abfd, 0, 0, 1, NULL)) - return FALSE; - - return TRUE; -} - -/* Set the architecture for the output file. The architecture is - irrelevant, so we ignore errors about unknown architectures. */ - -static bfd_boolean -ihex_set_arch_mach (bfd *abfd, - enum bfd_architecture arch, - unsigned long mach) -{ - if (! bfd_default_set_arch_mach (abfd, arch, mach)) - { - if (arch != bfd_arch_unknown) - return FALSE; - } - return TRUE; -} - -/* Get the size of the headers, for the linker. */ - -static int -ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - return 0; -} - -/* Some random definitions for the target vector. */ - -#define ihex_close_and_cleanup _bfd_generic_close_and_cleanup -#define ihex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define ihex_new_section_hook _bfd_generic_new_section_hook -#define ihex_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define ihex_get_symtab_upper_bound bfd_0l -#define ihex_canonicalize_symtab ((long (*) (bfd *, asymbol **)) bfd_0l) -#define ihex_make_empty_symbol _bfd_generic_make_empty_symbol -#define ihex_print_symbol _bfd_nosymbols_print_symbol -#define ihex_get_symbol_info _bfd_nosymbols_get_symbol_info -#define ihex_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define ihex_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name -#define ihex_get_lineno _bfd_nosymbols_get_lineno -#define ihex_find_nearest_line _bfd_nosymbols_find_nearest_line -#define ihex_find_inliner_info _bfd_nosymbols_find_inliner_info -#define ihex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define ihex_read_minisymbols _bfd_nosymbols_read_minisymbols -#define ihex_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol -#define ihex_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define ihex_bfd_relax_section bfd_generic_relax_section -#define ihex_bfd_gc_sections bfd_generic_gc_sections -#define ihex_bfd_lookup_section_flags bfd_generic_lookup_section_flags -#define ihex_bfd_merge_sections bfd_generic_merge_sections -#define ihex_bfd_is_group_section bfd_generic_is_group_section -#define ihex_bfd_discard_group bfd_generic_discard_group -#define ihex_section_already_linked _bfd_generic_section_already_linked -#define ihex_bfd_define_common_symbol bfd_generic_define_common_symbol -#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define ihex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define ihex_bfd_link_just_syms _bfd_generic_link_just_syms -#define ihex_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -#define ihex_bfd_final_link _bfd_generic_final_link -#define ihex_bfd_link_split_section _bfd_generic_link_split_section - -/* The Intel Hex target vector. */ - -const bfd_target ihex_vec = -{ - "ihex", /* Name. */ - bfd_target_ihex_flavour, - BFD_ENDIAN_UNKNOWN, /* Target byte order. */ - BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ - 0, /* Object flags. */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* Section flags. */ - 0, /* Leading underscore. */ - ' ', /* AR_pad_char. */ - 16, /* AR_max_namelen. */ - 0, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ - - { - _bfd_dummy_target, - ihex_object_p, /* bfd_check_format. */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - ihex_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents. */ - bfd_false, - ihex_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (ihex), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (ihex), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (ihex), - BFD_JUMP_TABLE_LINK (ihex), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; diff --git a/contrib/binutils-2.22/bfd/init.c b/contrib/binutils-2.22/bfd/init.c deleted file mode 100644 index a023fb6878..0000000000 --- a/contrib/binutils-2.22/bfd/init.c +++ /dev/null @@ -1,55 +0,0 @@ -/* bfd initialization stuff - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 2003, 2005, 2007 - Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -/* -SECTION - Initialization - -SUBSECTION - Initialization functions - - These are the functions that handle initializing a BFD. -*/ - -/* -FUNCTION - bfd_init - -SYNOPSIS - void bfd_init (void); - -DESCRIPTION - This routine must be called before any other BFD function to - initialize magical internal data structures. -*/ - -/* Actually, there is currently nothing for this function to do. - However, someday it may be needed, so keep it around. */ - -void -bfd_init (void) -{ -} diff --git a/contrib/binutils-2.22/bfd/libaout.h b/contrib/binutils-2.22/bfd/libaout.h deleted file mode 100644 index ed2ec45a5d..0000000000 --- a/contrib/binutils-2.22/bfd/libaout.h +++ /dev/null @@ -1,691 +0,0 @@ -/* BFD back-end data structures for a.out (and similar) files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef LIBAOUT_H -#define LIBAOUT_H - -/* We try to encapsulate the differences in the various a.out file - variants in a few routines, and otherwise share large masses of code. - This means we only have to fix bugs in one place, most of the time. */ - -#include "bfdlink.h" - -/* Macros for accessing components in an aout header. */ - -#define H_PUT_64 bfd_h_put_64 -#define H_PUT_32 bfd_h_put_32 -#define H_PUT_16 bfd_h_put_16 -#define H_PUT_8 bfd_h_put_8 -#define H_PUT_S64 bfd_h_put_signed_64 -#define H_PUT_S32 bfd_h_put_signed_32 -#define H_PUT_S16 bfd_h_put_signed_16 -#define H_PUT_S8 bfd_h_put_signed_8 -#define H_GET_64 bfd_h_get_64 -#define H_GET_32 bfd_h_get_32 -#define H_GET_16 bfd_h_get_16 -#define H_GET_8 bfd_h_get_8 -#define H_GET_S64 bfd_h_get_signed_64 -#define H_GET_S32 bfd_h_get_signed_32 -#define H_GET_S16 bfd_h_get_signed_16 -#define H_GET_S8 bfd_h_get_signed_8 - -/* Parameterize the a.out code based on whether it is being built - for a 32-bit architecture or a 64-bit architecture. */ -/* Do not "beautify" the CONCAT* macro args. Traditional C will not - remove whitespace added here, and thus will fail to concatenate - the tokens. */ -#if ARCH_SIZE==64 -#define GET_WORD H_GET_64 -#define GET_SWORD H_GET_S64 -#define GET_MAGIC H_GET_32 -#define PUT_WORD H_PUT_64 -#define PUT_MAGIC H_PUT_32 -#ifndef NAME -#define NAME(x,y) CONCAT3 (x,_64_,y) -#endif -#define JNAME(x) CONCAT2 (x,_64) -#define BYTES_IN_WORD 8 -#else -#if ARCH_SIZE==16 -#define GET_WORD H_GET_16 -#define GET_SWORD H_GET_S16 -#define GET_MAGIC H_GET_16 -#define PUT_WORD H_PUT_16 -#define PUT_MAGIC H_PUT_16 -#ifndef NAME -#define NAME(x,y) CONCAT3 (x,_16_,y) -#endif -#define JNAME(x) CONCAT2 (x,_16) -#define BYTES_IN_WORD 2 -#else /* ARCH_SIZE == 32 */ -#define GET_WORD H_GET_32 -#define GET_SWORD H_GET_S32 -#define GET_MAGIC H_GET_32 -#define PUT_WORD H_PUT_32 -#define PUT_MAGIC H_PUT_32 -#ifndef NAME -#define NAME(x,y) CONCAT3 (x,_32_,y) -#endif -#define JNAME(x) CONCAT2 (x,_32) -#define BYTES_IN_WORD 4 -#endif /* ARCH_SIZE==32 */ -#endif /* ARCH_SIZE==64 */ - -/* Declare at file level, since used in parameter lists, which have - weird scope. */ -struct external_exec; -struct external_nlist; -struct reloc_ext_external; -struct reloc_std_external; - -/* a.out backend linker hash table entries. */ - -struct aout_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Whether this symbol has been written out. */ - bfd_boolean written; - /* Symbol index in output file. */ - int indx; -}; - -/* a.out backend linker hash table. */ - -struct aout_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in an a.out link hash table. */ - -#define aout_link_hash_lookup(table, string, create, copy, follow) \ - ((struct aout_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an a.out link hash table. */ - -#define aout_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ - (info))) - -/* Get the a.out link hash table from the info structure. This is - just a cast. */ - -#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash)) - -/* Back-end information for various a.out targets. */ -struct aout_backend_data -{ - /* Are ZMAGIC files mapped contiguously? If so, the text section may - need more padding, if the segment size (granularity for memory access - control) is larger than the page size. */ - unsigned char zmagic_mapped_contiguous; - /* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the - text section, which starts immediately after the file header. - If not, the text section starts on the next page. */ - unsigned char text_includes_header; - - /* If this flag is set, then if the entry address is not in the - first SEGMENT_SIZE bytes of the text section, it is taken to be - the address of the start of the text section. This can be useful - for kernels. */ - unsigned char entry_is_text_address; - - /* The value to pass to N_SET_FLAGS. */ - unsigned char exec_hdr_flags; - - /* If the text section VMA isn't specified, and we need an absolute - address, use this as the default. If we're producing a relocatable - file, zero is always used. */ - /* ?? Perhaps a callback would be a better choice? Will this do anything - reasonable for a format that handles multiple CPUs with different - load addresses for each? */ - bfd_vma default_text_vma; - - /* Callback for setting the page and segment sizes, if they can't be - trivially determined from the architecture. */ - bfd_boolean (*set_sizes) (bfd *); - - /* zmagic files only. For go32, the length of the exec header contributes - to the size of the text section in the file for alignment purposes but - does *not* get counted in the length of the text section. */ - unsigned char exec_header_not_counted; - - /* Callback from the add symbols phase of the linker code to handle - a dynamic object. */ - bfd_boolean (*add_dynamic_symbols) - (bfd *, struct bfd_link_info *, struct external_nlist **, - bfd_size_type *, char **); - - /* Callback from the add symbols phase of the linker code to handle - adding a single symbol to the global linker hash table. */ - bfd_boolean (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, - struct bfd_link_hash_entry **); - - /* Called to handle linking a dynamic object. */ - bfd_boolean (*link_dynamic_object) - (struct bfd_link_info *, bfd *); - - /* Called for each global symbol being written out by the linker. - This should write out the dynamic symbol information. */ - bfd_boolean (*write_dynamic_symbol) - (bfd *, struct bfd_link_info *, struct aout_link_hash_entry *); - - /* If this callback is not NULL, the linker calls it for each reloc. - RELOC is a pointer to the unswapped reloc. If *SKIP is set to - TRUE, the reloc will be skipped. *RELOCATION may be changed to - change the effects of the relocation. */ - bfd_boolean (*check_dynamic_reloc) - (struct bfd_link_info *info, bfd *input_bfd, - asection *input_section, struct aout_link_hash_entry *h, - void * reloc, bfd_byte *contents, bfd_boolean *skip, - bfd_vma *relocation); - - /* Called at the end of a link to finish up any dynamic linking - information. */ - bfd_boolean (*finish_dynamic_link) (bfd *, struct bfd_link_info *); -}; -#define aout_backend_info(abfd) \ - ((const struct aout_backend_data *)((abfd)->xvec->backend_data)) - -/* This is the layout in memory of a "struct exec" while we process it. - All 'lengths' are given as a number of bytes. - All 'alignments' are for relinkable files only; an alignment of - 'n' indicates the corresponding segment must begin at an - address that is a multiple of (2**n). */ - -struct internal_exec -{ - long a_info; /* Magic number and flags, packed. */ - bfd_vma a_text; /* Length of text, in bytes. */ - bfd_vma a_data; /* Length of data, in bytes. */ - bfd_vma a_bss; /* Length of uninitialized data area in mem. */ - bfd_vma a_syms; /* Length of symbol table data in file. */ - bfd_vma a_entry; /* Start address. */ - bfd_vma a_trsize; /* Length of text's relocation info, in bytes. */ - bfd_vma a_drsize; /* Length of data's relocation info, in bytes. */ - /* Added for i960 */ - bfd_vma a_tload; /* Text runtime load address. */ - bfd_vma a_dload; /* Data runtime load address. */ - unsigned char a_talign; /* Alignment of text segment. */ - unsigned char a_dalign; /* Alignment of data segment. */ - unsigned char a_balign; /* Alignment of bss segment. */ - char a_relaxable; /* Enough info for linker relax. */ -}; - -/* Magic number is written - < MSB > - 3130292827262524232221201918171615141312111009080706050403020100 - < FLAGS >< MACHINE TYPE >< MAGIC NUMBER > */ - -/* Magic number for NetBSD is - - 3130292827262524232221201918171615141312111009080706050403020100 - < FLAGS >< MACHINE TYPE >< MAGIC NUMBER > */ - -enum machine_type -{ - M_UNKNOWN = 0, - M_68010 = 1, - M_68020 = 2, - M_SPARC = 3, - /* Skip a bunch so we don't run into any of SUN's numbers. */ - /* Make these up for the ns32k. */ - M_NS32032 = (64), /* NS32032 running ? */ - M_NS32532 = (64 + 5), /* NS32532 running mach. */ - M_386 = 100, - M_29K = 101, /* AMD 29000. */ - M_386_DYNIX = 102, /* Sequent running dynix. */ - M_ARM = 103, /* Advanced Risc Machines ARM. */ - M_SPARCLET = 131, /* SPARClet = M_SPARC + 128. */ - M_386_NETBSD = 134, /* NetBSD/i386 binary. */ - M_68K_NETBSD = 135, /* NetBSD/m68k binary. */ - M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary. */ - M_532_NETBSD = 137, /* NetBSD/ns32k binary. */ - M_SPARC_NETBSD = 138, /* NetBSD/sparc binary. */ - M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary. */ - M_VAX_NETBSD = 140, /* NetBSD/vax binary. */ - M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary. */ - M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary. */ - M_SPARCLET_1 = 147, /* 0x93, reserved. */ - M_POWERPC_NETBSD = 149, /* NetBSD/powerpc (big-endian) binary. */ - M_VAX4K_NETBSD = 150, /* NetBSD/vax 4K pages binary. */ - M_MIPS1 = 151, /* MIPS R2000/R3000 binary. */ - M_MIPS2 = 152, /* MIPS R4000/R6000 binary. */ - M_88K_OPENBSD = 153, /* OpenBSD/m88k binary. */ - M_HPPA_OPENBSD = 154, /* OpenBSD/hppa binary. */ - M_SPARC64_NETBSD = 156, /* NetBSD/sparc64 binary. */ - M_X86_64_NETBSD = 157, /* NetBSD/amd64 binary. */ - M_SPARCLET_2 = 163, /* 0xa3, reserved. */ - M_SPARCLET_3 = 179, /* 0xb3, reserved. */ - M_SPARCLET_4 = 195, /* 0xc3, reserved. */ - M_HP200 = 200, /* HP 200 (68010) BSD binary. */ - M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary. */ - M_HPUX = (0x20c % 256), /* HP 200/300 HPUX binary. */ - M_SPARCLET_5 = 211, /* 0xd3, reserved. */ - M_SPARCLET_6 = 227, /* 0xe3, reserved. */ -/*M_SPARCLET_7 = 243 / * 0xf3, reserved. */ - M_SPARCLITE_LE = 243, - M_CRIS = 255 /* Axis CRIS binary. */ -}; - -#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000) - -#ifndef N_MAGIC -# define N_MAGIC(exec) ((exec).a_info & 0xffff) -#endif - -#ifndef N_MACHTYPE -# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff)) -#endif - -#ifndef N_FLAGS -# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) -#endif - -#ifndef N_SET_INFO -# define N_SET_INFO(exec, magic, type, flags) \ -((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0xff) << 16) \ - | (((flags) & 0xff) << 24)) -#endif - -#ifndef N_SET_DYNAMIC -# define N_SET_DYNAMIC(exec, dynamic) \ -((exec).a_info = (dynamic) ? (long) ((exec).a_info | 0x80000000) : \ -((exec).a_info & 0x7fffffff)) -#endif - -#ifndef N_SET_MAGIC -# define N_SET_MAGIC(exec, magic) \ -((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) -#endif - -#ifndef N_SET_MACHTYPE -# define N_SET_MACHTYPE(exec, machtype) \ -((exec).a_info = \ - ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) -#endif - -#ifndef N_SET_FLAGS -# define N_SET_FLAGS(exec, flags) \ -((exec).a_info = \ - ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) -#endif - -typedef struct aout_symbol -{ - asymbol symbol; - short desc; - char other; - unsigned char type; -} aout_symbol_type; - -/* The `tdata' struct for all a.out-like object file formats. - Various things depend on this struct being around any time an a.out - file is being handled. An example is dbxread.c in GDB. */ - -enum aout_subformat { - default_format = 0, - /* Used on HP 9000/300 running HP/UX. See hp300hpux.c. */ - gnu_encap_format, - /* Used on Linux, 386BSD, etc. See include/aout/aout64.h. */ - q_magic_format -}; - -enum aout_magic { - undecided_magic = 0, - z_magic, - o_magic, - n_magic -}; - -struct aoutdata -{ - struct internal_exec *hdr; /* Exec file header. */ - aout_symbol_type *symbols; /* Symtab for input bfd. */ - - /* For ease, we do this. */ - asection *textsec; - asection *datasec; - asection *bsssec; - - /* We remember these offsets so that after check_file_format, we have - no dependencies on the particular format of the exec_hdr. */ - file_ptr sym_filepos; - file_ptr str_filepos; - - /* Size of a relocation entry in external form. */ - unsigned reloc_entry_size; - - /* Size of a symbol table entry in external form. */ - unsigned symbol_entry_size; - - /* Page size - needed for alignment of demand paged files. */ - unsigned long page_size; - - /* Segment size - needed for alignment of demand paged files. */ - unsigned long segment_size; - - /* Zmagic disk block size - need to align the start of the text - section in ZMAGIC binaries. Normally the same as page_size. */ - unsigned long zmagic_disk_block_size; - - unsigned exec_bytes_size; - unsigned vma_adjusted : 1; - - /* Used when a bfd supports several highly similar formats. */ - enum aout_subformat subformat; - - enum aout_magic magic; - - /* A buffer for find_nearest_line. */ - char *line_buf; - - /* The external symbol information. */ - struct external_nlist *external_syms; - bfd_size_type external_sym_count; - bfd_window sym_window; - char *external_strings; - bfd_size_type external_string_size; - bfd_window string_window; - struct aout_link_hash_entry **sym_hashes; - - /* A pointer for shared library information. */ - void * dynamic_info; - - /* A mapping from local symbols to offsets into the global offset - table, used when linking on SunOS. This is indexed by the symbol - index. */ - bfd_vma *local_got_offsets; -}; - -struct aout_data_struct -{ - struct aoutdata a; - struct internal_exec e; -}; - -#define adata(bfd) ((bfd)->tdata.aout_data->a) -#define exec_hdr(bfd) (adata (bfd).hdr) -#define obj_aout_symbols(bfd) (adata (bfd).symbols) -#define obj_textsec(bfd) (adata (bfd).textsec) -#define obj_datasec(bfd) (adata (bfd).datasec) -#define obj_bsssec(bfd) (adata (bfd).bsssec) -#define obj_sym_filepos(bfd) (adata (bfd).sym_filepos) -#define obj_str_filepos(bfd) (adata (bfd).str_filepos) -#define obj_reloc_entry_size(bfd) (adata (bfd).reloc_entry_size) -#define obj_symbol_entry_size(bfd) (adata (bfd).symbol_entry_size) -#define obj_aout_subformat(bfd) (adata (bfd).subformat) -#define obj_aout_external_syms(bfd) (adata (bfd).external_syms) -#define obj_aout_external_sym_count(bfd) (adata (bfd).external_sym_count) -#define obj_aout_sym_window(bfd) (adata (bfd).sym_window) -#define obj_aout_external_strings(bfd) (adata (bfd).external_strings) -#define obj_aout_external_string_size(bfd) (adata (bfd).external_string_size) -#define obj_aout_string_window(bfd) (adata (bfd).string_window) -#define obj_aout_sym_hashes(bfd) (adata (bfd).sym_hashes) -#define obj_aout_dynamic_info(bfd) (adata (bfd).dynamic_info) - -/* We take the address of the first element of an asymbol to ensure that the - macro is only ever applied to an asymbol. */ -#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd)) - -/* Information we keep for each a.out section. This is currently only - used by the a.out backend linker. */ - -struct aout_section_data_struct -{ - /* The unswapped relocation entries for this section. */ - void * relocs; -}; - -#define aout_section_data(s) \ - ((struct aout_section_data_struct *) (s)->used_by_bfd) - -#define set_aout_section_data(s,v) \ - ((s)->used_by_bfd = (void *)&(v)->relocs) - -/* Prototype declarations for functions defined in aoutx.h. */ - -extern bfd_boolean NAME (aout, squirt_out_relocs) - (bfd *, asection *); - -extern bfd_boolean NAME (aout, make_sections) - (bfd *); - -extern const bfd_target * NAME (aout, some_aout_object_p) - (bfd *, struct internal_exec *, const bfd_target *(*) (bfd *)); - -extern bfd_boolean NAME (aout, mkobject) - (bfd *); - -extern enum machine_type NAME (aout, machine_type) - (enum bfd_architecture, unsigned long, bfd_boolean *); - -extern bfd_boolean NAME (aout, set_arch_mach) - (bfd *, enum bfd_architecture, unsigned long); - -extern bfd_boolean NAME (aout, new_section_hook) - (bfd *, asection *); - -extern bfd_boolean NAME (aout, set_section_contents) - (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); - -extern asymbol * NAME (aout, make_empty_symbol) - (bfd *); - -extern bfd_boolean NAME (aout, translate_symbol_table) - (bfd *, aout_symbol_type *, struct external_nlist *, bfd_size_type, - char *, bfd_size_type, bfd_boolean); - -extern bfd_boolean NAME (aout, slurp_symbol_table) - (bfd *); - -extern bfd_boolean NAME (aout, write_syms) - (bfd *); - -extern void NAME (aout, reclaim_symbol_table) - (bfd *); - -extern long NAME (aout, get_symtab_upper_bound) - (bfd *); - -extern long NAME (aout, canonicalize_symtab) - (bfd *, asymbol **); - -extern void NAME (aout, swap_ext_reloc_in) - (bfd *, struct reloc_ext_external *, arelent *, asymbol **, - bfd_size_type); - -extern void NAME (aout, swap_std_reloc_in) - (bfd *, struct reloc_std_external *, arelent *, asymbol **, - bfd_size_type); - -extern reloc_howto_type * NAME (aout, reloc_type_lookup) - (bfd *, bfd_reloc_code_real_type); - -extern reloc_howto_type * NAME (aout, reloc_name_lookup) - (bfd *, const char *); - -extern bfd_boolean NAME (aout, slurp_reloc_table) - (bfd *, sec_ptr, asymbol **); - -extern long NAME (aout, canonicalize_reloc) - (bfd *, sec_ptr, arelent **, asymbol **); - -extern long NAME (aout, get_reloc_upper_bound) - (bfd *, sec_ptr); - -extern void NAME (aout, reclaim_reloc) - (bfd *, sec_ptr); - -extern alent * NAME (aout, get_lineno) - (bfd *, asymbol *); - -extern void NAME (aout, print_symbol) - (bfd *, void *, asymbol *, bfd_print_symbol_type); - -extern void NAME (aout, get_symbol_info) - (bfd *, asymbol *, symbol_info *); - -extern bfd_boolean NAME (aout, find_nearest_line) - (bfd *, asection *, asymbol **, bfd_vma, const char **, - const char **, unsigned int *); - -extern long NAME (aout, read_minisymbols) - (bfd *, bfd_boolean, void * *, unsigned int *); - -extern asymbol * NAME (aout, minisymbol_to_symbol) - (bfd *, bfd_boolean, const void *, asymbol *); - -extern int NAME (aout, sizeof_headers) - (bfd *, struct bfd_link_info *); - -extern bfd_boolean NAME (aout, adjust_sizes_and_vmas) - (bfd *, bfd_size_type *, file_ptr *); - -extern void NAME (aout, swap_exec_header_in) - (bfd *, struct external_exec *, struct internal_exec *); - -extern void NAME (aout, swap_exec_header_out) - (bfd *, struct internal_exec *, struct external_exec *); - -extern struct bfd_hash_entry * NAME (aout, link_hash_newfunc) - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); - -extern bfd_boolean NAME (aout, link_hash_table_init) - (struct aout_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int); - -extern struct bfd_link_hash_table * NAME (aout, link_hash_table_create) - (bfd *); - -extern bfd_boolean NAME (aout, link_add_symbols) - (bfd *, struct bfd_link_info *); - -extern bfd_boolean NAME (aout, final_link) - (bfd *, struct bfd_link_info *, - void (*) (bfd *, file_ptr *, file_ptr *, file_ptr *)); - -extern bfd_boolean NAME (aout, bfd_free_cached_info) - (bfd *); - -#define aout_32_find_inliner_info _bfd_nosymbols_find_inliner_info -#if 0 /* Are these needed? */ -#define aout_16_find_inliner_info _bfd_nosymbols_find_inliner_info -#define aout_64_find_inliner_info _bfd_nosymbols_find_inliner_info -#endif - -/* A.out uses the generic versions of these routines... */ - -#define aout_16_get_section_contents _bfd_generic_get_section_contents - -#define aout_32_get_section_contents _bfd_generic_get_section_contents - -#define aout_64_get_section_contents _bfd_generic_get_section_contents -#ifndef NO_WRITE_HEADER_KLUDGE -#define NO_WRITE_HEADER_KLUDGE 0 -#endif - -#ifndef aout_32_bfd_is_local_label_name -#define aout_32_bfd_is_local_label_name bfd_generic_is_local_label_name -#endif - -#ifndef aout_32_bfd_is_target_special_symbol -#define aout_32_bfd_is_target_special_symbol \ - ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#endif - -#ifndef WRITE_HEADERS -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* Dummy vars. */ \ - file_ptr text_end; \ - \ - if (adata(abfd).magic == undecided_magic) \ - NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \ - || bfd_bwrite (& exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \ - abfd) != EXEC_BYTES_SIZE) \ - return FALSE; \ - /* Now write out reloc info, followed by syms and strings. */ \ - \ - if (bfd_get_outsymbols (abfd) != NULL \ - && bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)\ - return FALSE; \ - \ - if (! NAME (aout, write_syms) (abfd)) \ - return FALSE; \ - } \ - \ - if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0) \ - return FALSE; \ - if (!NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))) \ - return FALSE; \ - \ - if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0) \ - return FALSE; \ - if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd))) \ - return FALSE; \ - } -#endif - -/* Test if a read-only section can be merged with .text. This is - possible if: - - 1. Section has file contents and is read-only. - 2. The VMA of the section is after the end of .text and before - the start of .data. - 3. The image is demand-pageable (otherwise, a_text in the header - will not reflect the gap between .text and .data). */ - -#define aout_section_merge_with_text_p(abfd, sec) \ - (((sec)->flags & (SEC_HAS_CONTENTS | SEC_READONLY)) == \ - (SEC_HAS_CONTENTS | SEC_READONLY) \ - && obj_textsec (abfd) != NULL \ - && obj_datasec (abfd) != NULL \ - && (sec)->vma >= (obj_textsec (abfd)->vma + \ - obj_textsec (abfd)->size) \ - && ((sec)->vma + (sec)->size) <= obj_datasec (abfd)->vma \ - && ((abfd)->flags & D_PAGED) != 0) - -#endif /* ! defined (LIBAOUT_H) */ diff --git a/contrib/binutils-2.22/bfd/libbfd.c b/contrib/binutils-2.22/bfd/libbfd.c deleted file mode 100644 index 44651cf9c3..0000000000 --- a/contrib/binutils-2.22/bfd/libbfd.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* Assorted BFD support routines, only used internally. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" - -#ifndef HAVE_GETPAGESIZE -#define getpagesize() 2048 -#endif - -/* -SECTION - Implementation details - -SUBSECTION - Internal functions - -DESCRIPTION - These routines are used within BFD. - They are not intended for export, but are documented here for - completeness. -*/ - -/* A routine which is used in target vectors for unsupported - operations. */ - -bfd_boolean -bfd_false (bfd *ignore ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -} - -/* A routine which is used in target vectors for supported operations - which do not actually do anything. */ - -bfd_boolean -bfd_true (bfd *ignore ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* A routine which is used in target vectors for unsupported - operations which return a pointer value. */ - -void * -bfd_nullvoidptr (bfd *ignore ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return NULL; -} - -int -bfd_0 (bfd *ignore ATTRIBUTE_UNUSED) -{ - return 0; -} - -unsigned int -bfd_0u (bfd *ignore ATTRIBUTE_UNUSED) -{ - return 0; -} - -long -bfd_0l (bfd *ignore ATTRIBUTE_UNUSED) -{ - return 0; -} - -/* A routine which is used in target vectors for unsupported - operations which return -1 on error. */ - -long -_bfd_n1 (bfd *ignore_abfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - -void -bfd_void (bfd *ignore ATTRIBUTE_UNUSED) -{ -} - -long -_bfd_norelocs_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED) -{ - return sizeof (arelent *); -} - -long -_bfd_norelocs_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED, - arelent **relptr, - asymbol **symbols ATTRIBUTE_UNUSED) -{ - *relptr = NULL; - return 0; -} - -bfd_boolean -_bfd_nocore_core_file_matches_executable_p - (bfd *ignore_core_bfd ATTRIBUTE_UNUSED, - bfd *ignore_exec_bfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return FALSE; -} - -/* Routine to handle core_file_failing_command entry point for targets - without core file support. */ - -char * -_bfd_nocore_core_file_failing_command (bfd *ignore_abfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return NULL; -} - -/* Routine to handle core_file_failing_signal entry point for targets - without core file support. */ - -int -_bfd_nocore_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return 0; -} - -/* Routine to handle the core_file_pid entry point for targets without - core file support. */ - -int -_bfd_nocore_core_file_pid (bfd *ignore_abfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_invalid_operation); - return 0; -} - -const bfd_target * -_bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED) -{ - bfd_set_error (bfd_error_wrong_format); - return 0; -} - -/* Allocate memory using malloc. */ - -void * -bfd_malloc (bfd_size_type size) -{ - void *ptr; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ptr = malloc ((size_t) size); - if (ptr == NULL && (size_t) size != 0) - bfd_set_error (bfd_error_no_memory); - - return ptr; -} - -/* Allocate memory using malloc, nmemb * size with overflow checking. */ - -void * -bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size) -{ - void *ptr; - - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE - && size != 0 - && nmemb > ~(bfd_size_type) 0 / size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - size *= nmemb; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ptr = malloc ((size_t) size); - if (ptr == NULL && (size_t) size != 0) - bfd_set_error (bfd_error_no_memory); - - return ptr; -} - -/* Reallocate memory using realloc. */ - -void * -bfd_realloc (void *ptr, bfd_size_type size) -{ - void *ret; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - if (ptr == NULL) - ret = malloc ((size_t) size); - else - ret = realloc (ptr, (size_t) size); - - if (ret == NULL && (size_t) size != 0) - bfd_set_error (bfd_error_no_memory); - - return ret; -} - -/* Reallocate memory using realloc, nmemb * size with overflow checking. */ - -void * -bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size) -{ - void *ret; - - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE - && size != 0 - && nmemb > ~(bfd_size_type) 0 / size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - size *= nmemb; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - if (ptr == NULL) - ret = malloc ((size_t) size); - else - ret = realloc (ptr, (size_t) size); - - if (ret == NULL && (size_t) size != 0) - bfd_set_error (bfd_error_no_memory); - - return ret; -} - -/* Reallocate memory using realloc. - If this fails the pointer is freed before returning. */ - -void * -bfd_realloc_or_free (void *ptr, bfd_size_type size) -{ - size_t amount = (size_t) size; - void *ret; - - if (size != amount) - ret = NULL; - else if (ptr == NULL) - ret = malloc (amount); - else - ret = realloc (ptr, amount); - - if (ret == NULL) - { - if (amount > 0) - bfd_set_error (bfd_error_no_memory); - - if (ptr != NULL) - free (ptr); - } - - return ret; -} - -/* Allocate memory using malloc and clear it. */ - -void * -bfd_zmalloc (bfd_size_type size) -{ - void *ptr; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ptr = malloc ((size_t) size); - - if ((size_t) size != 0) - { - if (ptr == NULL) - bfd_set_error (bfd_error_no_memory); - else - memset (ptr, 0, (size_t) size); - } - - return ptr; -} - -/* Allocate memory using malloc (nmemb * size) with overflow checking - and clear it. */ - -void * -bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size) -{ - void *ptr; - - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE - && size != 0 - && nmemb > ~(bfd_size_type) 0 / size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - size *= nmemb; - - if (size != (size_t) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ptr = malloc ((size_t) size); - - if ((size_t) size != 0) - { - if (ptr == NULL) - bfd_set_error (bfd_error_no_memory); - else - memset (ptr, 0, (size_t) size); - } - - return ptr; -} - -/* -INTERNAL_FUNCTION - bfd_write_bigendian_4byte_int - -SYNOPSIS - bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); - -DESCRIPTION - Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big - endian order regardless of what else is going on. This is useful in - archives. - -*/ -bfd_boolean -bfd_write_bigendian_4byte_int (bfd *abfd, unsigned int i) -{ - bfd_byte buffer[4]; - bfd_putb32 ((bfd_vma) i, buffer); - return bfd_bwrite (buffer, (bfd_size_type) 4, abfd) == 4; -} - - -/** The do-it-yourself (byte) sex-change kit */ - -/* The middle letter e.g. getshort indicates Big or Little endian - target machine. It doesn't matter what the byte order of the host - machine is; these routines work for either. */ - -/* FIXME: Should these take a count argument? - Answer (gnu@cygnus.com): No, but perhaps they should be inline - functions in swap.h #ifdef __GNUC__. - Gprof them later and find out. */ - -/* -FUNCTION - bfd_put_size -FUNCTION - bfd_get_size - -DESCRIPTION - These macros as used for reading and writing raw data in - sections; each access (except for bytes) is vectored through - the target format of the BFD and mangled accordingly. The - mangling performs any necessary endian translations and - removes alignment restrictions. Note that types accepted and - returned by these macros are identical so they can be swapped - around in macros---for example, @file{libaout.h} defines <> - to either <> or <>. - - In the put routines, @var{val} must be a <>. If we are on a - system without prototypes, the caller is responsible for making - sure that is true, with a cast if necessary. We don't cast - them in the macro definitions because that would prevent <> - or <> from detecting sins such as passing a pointer. - To detect calling these with less than a <>, use - <> on a host with 64 bit <>'s. - -. -.{* Byte swapping macros for user section data. *} -. -.#define bfd_put_8(abfd, val, ptr) \ -. ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) -.#define bfd_put_signed_8 \ -. bfd_put_8 -.#define bfd_get_8(abfd, ptr) \ -. (*(const unsigned char *) (ptr) & 0xff) -.#define bfd_get_signed_8(abfd, ptr) \ -. (((*(const unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) -. -.#define bfd_put_16(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) -.#define bfd_put_signed_16 \ -. bfd_put_16 -.#define bfd_get_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx16, (ptr)) -.#define bfd_get_signed_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) -. -.#define bfd_put_32(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) -.#define bfd_put_signed_32 \ -. bfd_put_32 -.#define bfd_get_32(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx32, (ptr)) -.#define bfd_get_signed_32(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) -. -.#define bfd_put_64(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) -.#define bfd_put_signed_64 \ -. bfd_put_64 -.#define bfd_get_64(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx64, (ptr)) -.#define bfd_get_signed_64(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) -. -.#define bfd_get(bits, abfd, ptr) \ -. ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ -. : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ -. : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ -. : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ -. : (abort (), (bfd_vma) - 1)) -. -.#define bfd_put(bits, abfd, val, ptr) \ -. ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ -. : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ -. : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ -. : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ -. : (abort (), (void) 0)) -. -*/ - -/* -FUNCTION - bfd_h_put_size - bfd_h_get_size - -DESCRIPTION - These macros have the same function as their <> - brethren, except that they are used for removing information - for the header records of object files. Believe it or not, - some object files keep their header records in big endian - order and their data in little endian order. -. -.{* Byte swapping macros for file header data. *} -. -.#define bfd_h_put_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_put_signed_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_get_8(abfd, ptr) \ -. bfd_get_8 (abfd, ptr) -.#define bfd_h_get_signed_8(abfd, ptr) \ -. bfd_get_signed_8 (abfd, ptr) -. -.#define bfd_h_put_16(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) -.#define bfd_h_put_signed_16 \ -. bfd_h_put_16 -.#define bfd_h_get_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx16, (ptr)) -.#define bfd_h_get_signed_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) -. -.#define bfd_h_put_32(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) -.#define bfd_h_put_signed_32 \ -. bfd_h_put_32 -.#define bfd_h_get_32(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx32, (ptr)) -.#define bfd_h_get_signed_32(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) -. -.#define bfd_h_put_64(abfd, val, ptr) \ -. BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) -.#define bfd_h_put_signed_64 \ -. bfd_h_put_64 -.#define bfd_h_get_64(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx64, (ptr)) -.#define bfd_h_get_signed_64(abfd, ptr) \ -. BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) -. -.{* Aliases for the above, which should eventually go away. *} -. -.#define H_PUT_64 bfd_h_put_64 -.#define H_PUT_32 bfd_h_put_32 -.#define H_PUT_16 bfd_h_put_16 -.#define H_PUT_8 bfd_h_put_8 -.#define H_PUT_S64 bfd_h_put_signed_64 -.#define H_PUT_S32 bfd_h_put_signed_32 -.#define H_PUT_S16 bfd_h_put_signed_16 -.#define H_PUT_S8 bfd_h_put_signed_8 -.#define H_GET_64 bfd_h_get_64 -.#define H_GET_32 bfd_h_get_32 -.#define H_GET_16 bfd_h_get_16 -.#define H_GET_8 bfd_h_get_8 -.#define H_GET_S64 bfd_h_get_signed_64 -.#define H_GET_S32 bfd_h_get_signed_32 -.#define H_GET_S16 bfd_h_get_signed_16 -.#define H_GET_S8 bfd_h_get_signed_8 -. -.*/ - -/* Sign extension to bfd_signed_vma. */ -#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) -#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000) -#define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63) -#define COERCE64(x) \ - (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) - -bfd_vma -bfd_getb16 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - return (addr[0] << 8) | addr[1]; -} - -bfd_vma -bfd_getl16 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - return (addr[1] << 8) | addr[0]; -} - -bfd_signed_vma -bfd_getb_signed_16 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - return COERCE16 ((addr[0] << 8) | addr[1]); -} - -bfd_signed_vma -bfd_getl_signed_16 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - return COERCE16 ((addr[1] << 8) | addr[0]); -} - -void -bfd_putb16 (bfd_vma data, void *p) -{ - bfd_byte *addr = (bfd_byte *) p; - addr[0] = (data >> 8) & 0xff; - addr[1] = data & 0xff; -} - -void -bfd_putl16 (bfd_vma data, void *p) -{ - bfd_byte *addr = (bfd_byte *) p; - addr[0] = data & 0xff; - addr[1] = (data >> 8) & 0xff; -} - -bfd_vma -bfd_getb32 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - unsigned long v; - - v = (unsigned long) addr[0] << 24; - v |= (unsigned long) addr[1] << 16; - v |= (unsigned long) addr[2] << 8; - v |= (unsigned long) addr[3]; - return v; -} - -bfd_vma -bfd_getl32 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - unsigned long v; - - v = (unsigned long) addr[0]; - v |= (unsigned long) addr[1] << 8; - v |= (unsigned long) addr[2] << 16; - v |= (unsigned long) addr[3] << 24; - return v; -} - -bfd_signed_vma -bfd_getb_signed_32 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - unsigned long v; - - v = (unsigned long) addr[0] << 24; - v |= (unsigned long) addr[1] << 16; - v |= (unsigned long) addr[2] << 8; - v |= (unsigned long) addr[3]; - return COERCE32 (v); -} - -bfd_signed_vma -bfd_getl_signed_32 (const void *p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - unsigned long v; - - v = (unsigned long) addr[0]; - v |= (unsigned long) addr[1] << 8; - v |= (unsigned long) addr[2] << 16; - v |= (unsigned long) addr[3] << 24; - return COERCE32 (v); -} - -bfd_uint64_t -bfd_getb64 (const void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - const bfd_byte *addr = (const bfd_byte *) p; - bfd_uint64_t v; - - v = addr[0]; v <<= 8; - v |= addr[1]; v <<= 8; - v |= addr[2]; v <<= 8; - v |= addr[3]; v <<= 8; - v |= addr[4]; v <<= 8; - v |= addr[5]; v <<= 8; - v |= addr[6]; v <<= 8; - v |= addr[7]; - - return v; -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_uint64_t -bfd_getl64 (const void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - const bfd_byte *addr = (const bfd_byte *) p; - bfd_uint64_t v; - - v = addr[7]; v <<= 8; - v |= addr[6]; v <<= 8; - v |= addr[5]; v <<= 8; - v |= addr[4]; v <<= 8; - v |= addr[3]; v <<= 8; - v |= addr[2]; v <<= 8; - v |= addr[1]; v <<= 8; - v |= addr[0]; - - return v; -#else - BFD_FAIL(); - return 0; -#endif - -} - -bfd_int64_t -bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - const bfd_byte *addr = (const bfd_byte *) p; - bfd_uint64_t v; - - v = addr[0]; v <<= 8; - v |= addr[1]; v <<= 8; - v |= addr[2]; v <<= 8; - v |= addr[3]; v <<= 8; - v |= addr[4]; v <<= 8; - v |= addr[5]; v <<= 8; - v |= addr[6]; v <<= 8; - v |= addr[7]; - - return COERCE64 (v); -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_int64_t -bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - const bfd_byte *addr = (const bfd_byte *) p; - bfd_uint64_t v; - - v = addr[7]; v <<= 8; - v |= addr[6]; v <<= 8; - v |= addr[5]; v <<= 8; - v |= addr[4]; v <<= 8; - v |= addr[3]; v <<= 8; - v |= addr[2]; v <<= 8; - v |= addr[1]; v <<= 8; - v |= addr[0]; - - return COERCE64 (v); -#else - BFD_FAIL(); - return 0; -#endif -} - -void -bfd_putb32 (bfd_vma data, void *p) -{ - bfd_byte *addr = (bfd_byte *) p; - addr[0] = (data >> 24) & 0xff; - addr[1] = (data >> 16) & 0xff; - addr[2] = (data >> 8) & 0xff; - addr[3] = data & 0xff; -} - -void -bfd_putl32 (bfd_vma data, void *p) -{ - bfd_byte *addr = (bfd_byte *) p; - addr[0] = data & 0xff; - addr[1] = (data >> 8) & 0xff; - addr[2] = (data >> 16) & 0xff; - addr[3] = (data >> 24) & 0xff; -} - -void -bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - bfd_byte *addr = (bfd_byte *) p; - addr[0] = (data >> (7*8)) & 0xff; - addr[1] = (data >> (6*8)) & 0xff; - addr[2] = (data >> (5*8)) & 0xff; - addr[3] = (data >> (4*8)) & 0xff; - addr[4] = (data >> (3*8)) & 0xff; - addr[5] = (data >> (2*8)) & 0xff; - addr[6] = (data >> (1*8)) & 0xff; - addr[7] = (data >> (0*8)) & 0xff; -#else - BFD_FAIL(); -#endif -} - -void -bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED) -{ -#ifdef BFD_HOST_64_BIT - bfd_byte *addr = (bfd_byte *) p; - addr[7] = (data >> (7*8)) & 0xff; - addr[6] = (data >> (6*8)) & 0xff; - addr[5] = (data >> (5*8)) & 0xff; - addr[4] = (data >> (4*8)) & 0xff; - addr[3] = (data >> (3*8)) & 0xff; - addr[2] = (data >> (2*8)) & 0xff; - addr[1] = (data >> (1*8)) & 0xff; - addr[0] = (data >> (0*8)) & 0xff; -#else - BFD_FAIL(); -#endif -} - -void -bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p) -{ - bfd_byte *addr = (bfd_byte *) p; - int i; - int bytes; - - if (bits % 8 != 0) - abort (); - - bytes = bits / 8; - for (i = 0; i < bytes; i++) - { - int addr_index = big_p ? bytes - i - 1 : i; - - addr[addr_index] = data & 0xff; - data >>= 8; - } -} - -bfd_uint64_t -bfd_get_bits (const void *p, int bits, bfd_boolean big_p) -{ - const bfd_byte *addr = (const bfd_byte *) p; - bfd_uint64_t data; - int i; - int bytes; - - if (bits % 8 != 0) - abort (); - - data = 0; - bytes = bits / 8; - for (i = 0; i < bytes; i++) - { - int addr_index = big_p ? i : bytes - i - 1; - - data = (data << 8) | addr[addr_index]; - } - - return data; -} - -/* Default implementation */ - -bfd_boolean -_bfd_generic_get_section_contents (bfd *abfd, - sec_ptr section, - void *location, - file_ptr offset, - bfd_size_type count) -{ - bfd_size_type sz; - if (count == 0) - return TRUE; - - if (section->compress_status != COMPRESS_SECTION_NONE) - { - (*_bfd_error_handler) - (_("%B: unable to get decompressed section %A"), - abfd, section); - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* We do allow reading of a section after bfd_final_link has - written the contents out to disk. In that situation, rawsize is - just a stale version of size, so ignore it. Otherwise we must be - reading an input section, where rawsize, if different to size, - is the on-disk size. */ - if (abfd->direction != write_direction && section->rawsize != 0) - sz = section->rawsize; - else - sz = section->size; - if (offset + count < count - || offset + count > sz) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 - || bfd_bread (location, count, abfd) != count) - return FALSE; - - return TRUE; -} - -bfd_boolean -_bfd_generic_get_section_contents_in_window - (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr section ATTRIBUTE_UNUSED, - bfd_window *w ATTRIBUTE_UNUSED, - file_ptr offset ATTRIBUTE_UNUSED, - bfd_size_type count ATTRIBUTE_UNUSED) -{ -#ifdef USE_MMAP - bfd_size_type sz; - - if (count == 0) - return TRUE; - if (abfd->xvec->_bfd_get_section_contents - != _bfd_generic_get_section_contents) - { - /* We don't know what changes the bfd's get_section_contents - method may have to make. So punt trying to map the file - window, and let get_section_contents do its thing. */ - /* @@ FIXME : If the internal window has a refcount of 1 and was - allocated with malloc instead of mmap, just reuse it. */ - bfd_free_window (w); - w->i = bfd_zmalloc (sizeof (bfd_window_internal)); - if (w->i == NULL) - return FALSE; - w->i->data = bfd_malloc (count); - if (w->i->data == NULL) - { - free (w->i); - w->i = NULL; - return FALSE; - } - w->i->mapped = 0; - w->i->refcount = 1; - w->size = w->i->size = count; - w->data = w->i->data; - return bfd_get_section_contents (abfd, section, w->data, offset, count); - } - if (abfd->direction != write_direction && section->rawsize != 0) - sz = section->rawsize; - else - sz = section->size; - if (offset + count > sz - || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, - TRUE)) - return FALSE; - return TRUE; -#else - abort (); -#endif -} - -/* This generic function can only be used in implementations where creating - NEW sections is disallowed. It is useful in patching existing sections - in read-write files, though. See other set_section_contents functions - to see why it doesn't work for new sections. */ -bfd_boolean -_bfd_generic_set_section_contents (bfd *abfd, - sec_ptr section, - const void *location, - file_ptr offset, - bfd_size_type count) -{ - if (count == 0) - return TRUE; - - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 - || bfd_bwrite (location, count, abfd) != count) - return FALSE; - - return TRUE; -} - -/* -INTERNAL_FUNCTION - bfd_log2 - -SYNOPSIS - unsigned int bfd_log2 (bfd_vma x); - -DESCRIPTION - Return the log base 2 of the value supplied, rounded up. E.g., an - @var{x} of 1025 returns 11. A @var{x} of 0 returns 0. -*/ - -unsigned int -bfd_log2 (bfd_vma x) -{ - unsigned int result = 0; - - if (x <= 1) - return result; - --x; - do - ++result; - while ((x >>= 1) != 0); - return result; -} - -bfd_boolean -bfd_generic_is_local_label_name (bfd *abfd, const char *name) -{ - char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.'; - - return name[0] == locals_prefix; -} - -/* Can be used from / for bfd_merge_private_bfd_data to check that - endianness matches between input and output file. Returns - TRUE for a match, otherwise returns FALSE and emits an error. */ -bfd_boolean -_bfd_generic_verify_endian_match (bfd *ibfd, bfd *obfd) -{ - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - { - const char *msg; - - if (bfd_big_endian (ibfd)) - msg = _("%B: compiled for a big endian system and target is little endian"); - else - msg = _("%B: compiled for a little endian system and target is big endian"); - - (*_bfd_error_handler) (msg, ibfd); - - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - return TRUE; -} - -/* Give a warning at runtime if someone compiles code which calls - old routines. */ - -void -warn_deprecated (const char *what, - const char *file, - int line, - const char *func) -{ - /* Poor man's tracking of functions we've already warned about. */ - static size_t mask = 0; - - if (~(size_t) func & ~mask) - { - fflush (stdout); - /* Note: separate sentences in order to allow - for translation into other languages. */ - if (func) - fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"), - what, file, line, func); - else - fprintf (stderr, _("Deprecated %s called\n"), what); - fflush (stderr); - mask |= ~(size_t) func; - } -} - -/* Helper function for reading uleb128 encoded data. */ - -bfd_vma -read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - bfd_byte *buf, - unsigned int *bytes_read_ptr) -{ - bfd_vma result; - unsigned int num_read; - unsigned int shift; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - do - { - byte = bfd_get_8 (abfd, buf); - buf++; - num_read++; - result |= (((bfd_vma) byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - *bytes_read_ptr = num_read; - return result; -} - -/* Helper function for reading sleb128 encoded data. */ - -bfd_signed_vma -read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED, - bfd_byte *buf, - unsigned int *bytes_read_ptr) -{ - bfd_vma result; - unsigned int shift; - unsigned int num_read; - unsigned char byte; - - result = 0; - shift = 0; - num_read = 0; - do - { - byte = bfd_get_8 (abfd, buf); - buf ++; - num_read ++; - result |= (((bfd_vma) byte & 0x7f) << shift); - shift += 7; - } - while (byte & 0x80); - if (shift < 8 * sizeof (result) && (byte & 0x40)) - result |= (((bfd_vma) -1) << shift); - *bytes_read_ptr = num_read; - return result; -} - -bfd_boolean -_bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED, - asymbol **symbols ATTRIBUTE_UNUSED, - asymbol *symbol ATTRIBUTE_UNUSED, - const char **filename_ptr ATTRIBUTE_UNUSED, - unsigned int *linenumber_ptr ATTRIBUTE_UNUSED) -{ - return FALSE; -} - -bfd_boolean -_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, - asection *isec ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, - asection *osec ATTRIBUTE_UNUSED, - struct bfd_link_info *link_info ATTRIBUTE_UNUSED) -{ - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/libbfd.h b/contrib/binutils-2.22/bfd/libbfd.h deleted file mode 100644 index 200a6fad31..0000000000 --- a/contrib/binutils-2.22/bfd/libbfd.h +++ /dev/null @@ -1,2520 +0,0 @@ -/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically - generated from "libbfd-in.h", "init.c", "libbfd.c", "bfdio.c", - "bfdwin.c", "cache.c", "reloc.c", "archures.c" and "elf.c". - Run "make headers" in your build bfd/ to regenerate. */ - -/* libbfd.h -- Declarations used by bfd library *implementation*. - (This include file is not for users of the library.) - - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2011 - Free Software Foundation, Inc. - - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "hashtab.h" - -/* Align an address upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. Take care never - to wrap around if the address is within boundary-1 of the end of the - address space. */ -#define BFD_ALIGN(this, boundary) \ - ((((bfd_vma) (this) + (boundary) - 1) >= (bfd_vma) (this)) \ - ? (((bfd_vma) (this) + ((boundary) - 1)) & ~ (bfd_vma) ((boundary)-1)) \ - : ~ (bfd_vma) 0) - -/* If you want to read and write large blocks, you might want to do it - in quanta of this amount */ -#define DEFAULT_BUFFERSIZE 8192 - -/* Set a tdata field. Can't use the other macros for this, since they - do casts, and casting to the left of assignment isn't portable. */ -#define set_tdata(bfd, v) ((bfd)->tdata.any = (v)) - -/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points - to an instance of this structure. */ - -struct bfd_in_memory -{ - /* Size of buffer. */ - bfd_size_type size; - /* Buffer holding contents of BFD. */ - bfd_byte *buffer; -}; - -struct section_hash_entry -{ - struct bfd_hash_entry root; - asection section; -}; - -/* tdata for an archive. For an input archive, cache - needs to be free()'d. For an output archive, symdefs do. */ - -struct artdata { - file_ptr first_file_filepos; - /* Speed up searching the armap */ - htab_t cache; - bfd *archive_head; /* Only interesting in output routines */ - carsym *symdefs; /* the symdef entries */ - symindex symdef_count; /* how many there are */ - char *extended_names; /* clever intel extension */ - bfd_size_type extended_names_size; /* Size of extended names */ - /* when more compilers are standard C, this can be a time_t */ - long armap_timestamp; /* Timestamp value written into armap. - This is used for BSD archives to check - that the timestamp is recent enough - for the BSD linker to not complain, - just before we finish writing an - archive. */ - file_ptr armap_datepos; /* Position within archive to seek to - rewrite the date field. */ - void *tdata; /* Backend specific information. */ -}; - -#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data) - -/* Goes in bfd's arelt_data slot */ -struct areltdata { - char * arch_header; /* it's actually a string */ - unsigned int parsed_size; /* octets of filesize not including ar_hdr */ - unsigned int extra_size; /* BSD4.4: extra bytes after the header. */ - char *filename; /* null-terminated */ - file_ptr origin; /* for element of a thin archive */ -}; - -#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size) - -extern void *bfd_malloc - (bfd_size_type); -extern void *bfd_realloc - (void *, bfd_size_type); -extern void *bfd_realloc_or_free - (void *, bfd_size_type); -extern void *bfd_zmalloc - (bfd_size_type); -extern void *bfd_malloc2 - (bfd_size_type, bfd_size_type); -extern void *bfd_realloc2 - (void *, bfd_size_type, bfd_size_type); -extern void *bfd_zmalloc2 - (bfd_size_type, bfd_size_type); - -extern void _bfd_default_error_handler (const char *s, ...); -extern bfd_error_handler_type _bfd_error_handler; - -/* These routines allocate and free things on the BFD's objalloc. */ - -extern void *bfd_alloc2 - (bfd *, bfd_size_type, bfd_size_type); -extern void *bfd_zalloc2 - (bfd *, bfd_size_type, bfd_size_type); -extern void bfd_release - (bfd *, void *); - -bfd * _bfd_create_empty_archive_element_shell - (bfd *obfd); -bfd * _bfd_look_for_bfd_in_cache - (bfd *, file_ptr); -bfd_boolean _bfd_add_bfd_to_archive_cache - (bfd *, file_ptr, bfd *); -bfd_boolean _bfd_generic_mkarchive - (bfd *abfd); -char *_bfd_append_relative_path - (bfd *arch, char *elt_name); -const bfd_target *bfd_generic_archive_p - (bfd *abfd); -bfd_boolean bfd_slurp_armap - (bfd *abfd); -bfd_boolean bfd_slurp_bsd_armap_f2 - (bfd *abfd); -#define bfd_slurp_bsd_armap bfd_slurp_armap -#define bfd_slurp_coff_armap bfd_slurp_armap -bfd_boolean _bfd_slurp_extended_name_table - (bfd *abfd); -extern bfd_boolean _bfd_construct_extended_name_table - (bfd *, bfd_boolean, char **, bfd_size_type *); -bfd_boolean _bfd_write_archive_contents - (bfd *abfd); -bfd_boolean _bfd_compute_and_write_armap - (bfd *, unsigned int elength); -bfd *_bfd_get_elt_at_filepos - (bfd *archive, file_ptr filepos); -extern bfd *_bfd_generic_get_elt_at_index - (bfd *, symindex); -bfd * _bfd_new_bfd - (void); -void _bfd_delete_bfd - (bfd *); -bfd_boolean _bfd_free_cached_info - (bfd *); - -bfd_boolean bfd_false - (bfd *ignore); -bfd_boolean bfd_true - (bfd *ignore); -void *bfd_nullvoidptr - (bfd *ignore); -int bfd_0 - (bfd *ignore); -unsigned int bfd_0u - (bfd *ignore); -long bfd_0l - (bfd *ignore); -long _bfd_n1 - (bfd *ignore); -void bfd_void - (bfd *ignore); - -bfd *_bfd_new_bfd_contained_in - (bfd *); -const bfd_target *_bfd_dummy_target - (bfd *abfd); - -void bfd_dont_truncate_arname - (bfd *abfd, const char *filename, char *hdr); -void bfd_bsd_truncate_arname - (bfd *abfd, const char *filename, char *hdr); -void bfd_gnu_truncate_arname - (bfd *abfd, const char *filename, char *hdr); - -bfd_boolean bsd_write_armap - (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, - int stridx); - -bfd_boolean coff_write_armap - (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, - int stridx); - -extern void *_bfd_generic_read_ar_hdr - (bfd *); -extern void _bfd_ar_spacepad - (char *, size_t, const char *, long); - -extern void *_bfd_generic_read_ar_hdr_mag - (bfd *, const char *); - -extern bfd_boolean _bfd_generic_write_ar_hdr - (bfd *, bfd *); - -extern bfd_boolean _bfd_bsd44_write_ar_hdr - (bfd *, bfd *); - -bfd * bfd_generic_openr_next_archived_file - (bfd *archive, bfd *last_file); - -int bfd_generic_stat_arch_elt - (bfd *, struct stat *); - -#define _bfd_read_ar_hdr(abfd) \ - BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd)) -#define _bfd_write_ar_hdr(archive, abfd) \ - BFD_SEND (abfd, _bfd_write_ar_hdr_fn, (archive, abfd)) - -/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use - BFD_JUMP_TABLE_GENERIC (_bfd_generic). */ - -#define _bfd_generic_close_and_cleanup bfd_true -#define _bfd_generic_bfd_free_cached_info bfd_true -extern bfd_boolean _bfd_generic_new_section_hook - (bfd *, asection *); -extern bfd_boolean _bfd_generic_get_section_contents - (bfd *, asection *, void *, file_ptr, bfd_size_type); -extern bfd_boolean _bfd_generic_get_section_contents_in_window - (bfd *, asection *, bfd_window *, file_ptr, bfd_size_type); - -/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use - BFD_JUMP_TABLE_COPY (_bfd_generic). */ - -#define _bfd_generic_bfd_copy_private_bfd_data \ - ((bfd_boolean (*) (bfd *, bfd *)) bfd_true) -#define _bfd_generic_bfd_merge_private_bfd_data \ - ((bfd_boolean (*) (bfd *, bfd *)) bfd_true) -#define _bfd_generic_bfd_set_private_flags \ - ((bfd_boolean (*) (bfd *, flagword)) bfd_true) -#define _bfd_generic_bfd_copy_private_section_data \ - ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true) -#define _bfd_generic_bfd_copy_private_symbol_data \ - ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true) -#define _bfd_generic_bfd_copy_private_header_data \ - ((bfd_boolean (*) (bfd *, bfd *)) bfd_true) -#define _bfd_generic_bfd_print_private_bfd_data \ - ((bfd_boolean (*) (bfd *, void *)) bfd_true) - -extern bfd_boolean _bfd_generic_init_private_section_data - (bfd *, asection *, bfd *, asection *, struct bfd_link_info *); - -/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file - support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ - -extern char *_bfd_nocore_core_file_failing_command - (bfd *); -extern int _bfd_nocore_core_file_failing_signal - (bfd *); -extern bfd_boolean _bfd_nocore_core_file_matches_executable_p - (bfd *, bfd *); -extern int _bfd_nocore_core_file_pid - (bfd *); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive - file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */ - -#define _bfd_noarchive_slurp_armap bfd_false -#define _bfd_noarchive_slurp_extended_name_table bfd_false -#define _bfd_noarchive_construct_extended_name_table \ - ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) \ - bfd_false) -#define _bfd_noarchive_truncate_arname \ - ((void (*) (bfd *, const char *, char *)) bfd_void) -#define _bfd_noarchive_write_armap \ - ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) \ - bfd_false) -#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr -#define _bfd_noarchive_write_ar_hdr \ - ((bfd_boolean (*) (bfd *, bfd *)) bfd_false) -#define _bfd_noarchive_openr_next_archived_file \ - ((bfd *(*) (bfd *, bfd *)) bfd_nullvoidptr) -#define _bfd_noarchive_get_elt_at_index \ - ((bfd *(*) (bfd *, symindex)) bfd_nullvoidptr) -#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_noarchive_update_armap_timestamp bfd_false - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */ - -#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern bfd_boolean _bfd_archive_bsd_construct_extended_name_table - (bfd *, char **, bfd_size_type *, const char **); -#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd_write_armap bsd_write_armap -#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_bsd_write_ar_hdr _bfd_generic_write_ar_hdr -#define _bfd_archive_bsd_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_bsd_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -extern bfd_boolean _bfd_archive_bsd_update_armap_timestamp - (bfd *); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */ - -#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap -#define _bfd_archive_coff_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern bfd_boolean _bfd_archive_coff_construct_extended_name_table - (bfd *, char **, bfd_size_type *, const char **); -#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname -#define _bfd_archive_coff_write_armap coff_write_armap -#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_coff_write_ar_hdr _bfd_generic_write_ar_hdr -#define _bfd_archive_coff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_coff_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -#define _bfd_archive_coff_update_armap_timestamp bfd_true - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD4.4 style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd44). */ - -#define _bfd_archive_bsd44_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd44_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern bfd_boolean _bfd_archive_bsd44_construct_extended_name_table - (bfd *, char **, bfd_size_type *, const char **); -#define _bfd_archive_bsd44_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd44_write_armap bsd_write_armap -#define _bfd_archive_bsd44_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_bsd44_write_ar_hdr _bfd_bsd44_write_ar_hdr -#define _bfd_archive_bsd44_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd44_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_bsd44_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -#define _bfd_archive_bsd44_update_armap_timestamp \ - _bfd_archive_bsd_update_armap_timestamp - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get VMS style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib). Some of them - are irrelevant and never called, so defined as NULL. */ - -extern bfd_boolean _bfd_vms_lib_write_archive_contents (bfd *arch); -#define _bfd_vms_lib_slurp_armap NULL -#define _bfd_vms_lib_slurp_extended_name_table NULL -#define _bfd_vms_lib_construct_extended_name_table NULL -#define _bfd_vms_lib_truncate_arname NULL -#define _bfd_vms_lib_write_armap NULL -#define _bfd_vms_lib_read_ar_hdr NULL -#define _bfd_vms_lib_write_ar_hdr NULL -extern bfd *_bfd_vms_lib_openr_next_archived_file (bfd *, bfd *); -extern bfd *_bfd_vms_lib_get_elt_at_index (bfd *, symindex); -extern int _bfd_vms_lib_generic_stat_arch_elt (bfd *, struct stat *); -#define _bfd_vms_lib_update_armap_timestamp bfd_true - -/* Extra routines for VMS style archives. */ - -extern symindex _bfd_vms_lib_find_symbol (bfd *, const char *); -extern bfd *_bfd_vms_lib_get_imagelib_file (bfd *); -extern const bfd_target *_bfd_vms_lib_alpha_archive_p (bfd *abfd); -extern const bfd_target *_bfd_vms_lib_ia64_archive_p (bfd *abfd); -extern bfd_boolean _bfd_vms_lib_alpha_mkarchive (bfd *abfd); -extern bfd_boolean _bfd_vms_lib_ia64_mkarchive (bfd *abfd); - -/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol - support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */ - -#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1 -#define _bfd_nosymbols_canonicalize_symtab \ - ((long (*) (bfd *, asymbol **)) _bfd_n1) -#define _bfd_nosymbols_make_empty_symbol _bfd_generic_make_empty_symbol -#define _bfd_nosymbols_print_symbol \ - ((void (*) (bfd *, void *, asymbol *, bfd_print_symbol_type)) bfd_void) -#define _bfd_nosymbols_get_symbol_info \ - ((void (*) (bfd *, asymbol *, symbol_info *)) bfd_void) -#define _bfd_nosymbols_bfd_is_local_label_name \ - ((bfd_boolean (*) (bfd *, const char *)) bfd_false) -#define _bfd_nosymbols_bfd_is_target_special_symbol \ - ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define _bfd_nosymbols_get_lineno \ - ((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr) -#define _bfd_nosymbols_find_nearest_line \ - ((bfd_boolean (*) (bfd *, asection *, asymbol **, bfd_vma, const char **, \ - const char **, unsigned int *)) \ - bfd_false) -#define _bfd_nosymbols_find_inliner_info \ - ((bfd_boolean (*) (bfd *, const char **, const char **, unsigned int *)) \ - bfd_false) -#define _bfd_nosymbols_bfd_make_debug_symbol \ - ((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr) -#define _bfd_nosymbols_read_minisymbols \ - ((long (*) (bfd *, bfd_boolean, void **, unsigned int *)) _bfd_n1) -#define _bfd_nosymbols_minisymbol_to_symbol \ - ((asymbol *(*) (bfd *, bfd_boolean, const void *, asymbol *)) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc - support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */ - -extern long _bfd_norelocs_get_reloc_upper_bound (bfd *, asection *); -extern long _bfd_norelocs_canonicalize_reloc (bfd *, asection *, - arelent **, asymbol **); -#define _bfd_norelocs_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr) -#define _bfd_norelocs_bfd_reloc_name_lookup \ - ((reloc_howto_type *(*) (bfd *, const char *)) bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not - be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */ - -#define _bfd_nowrite_set_arch_mach \ - ((bfd_boolean (*) (bfd *, enum bfd_architecture, unsigned long)) \ - bfd_false) -#define _bfd_nowrite_set_section_contents \ - ((bfd_boolean (*) (bfd *, asection *, const void *, file_ptr, bfd_size_type)) \ - bfd_false) - -/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use - BFD_JUMP_TABLE_WRITE (_bfd_generic). */ - -#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach -extern bfd_boolean _bfd_generic_set_section_contents - (bfd *, asection *, const void *, file_ptr, bfd_size_type); - -/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not - support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */ - -#define _bfd_nolink_sizeof_headers \ - ((int (*) (bfd *, struct bfd_link_info *)) bfd_0) -#define _bfd_nolink_bfd_get_relocated_section_contents \ - ((bfd_byte *(*) (bfd *, struct bfd_link_info *, struct bfd_link_order *, \ - bfd_byte *, bfd_boolean, asymbol **)) \ - bfd_nullvoidptr) -#define _bfd_nolink_bfd_relax_section \ - ((bfd_boolean (*) \ - (bfd *, asection *, struct bfd_link_info *, bfd_boolean *)) \ - bfd_false) -#define _bfd_nolink_bfd_gc_sections \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ - bfd_false) -#define _bfd_nolink_bfd_lookup_section_flags \ - ((void (*) (struct bfd_link_info *, struct flag_info *)) \ - bfd_0) -#define _bfd_nolink_bfd_merge_sections \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \ - bfd_false) -#define _bfd_nolink_bfd_is_group_section \ - ((bfd_boolean (*) (bfd *, const struct bfd_section *)) \ - bfd_false) -#define _bfd_nolink_bfd_discard_group \ - ((bfd_boolean (*) (bfd *, struct bfd_section *)) \ - bfd_false) -#define _bfd_nolink_bfd_link_hash_table_create \ - ((struct bfd_link_hash_table *(*) (bfd *)) bfd_nullvoidptr) -#define _bfd_nolink_bfd_link_hash_table_free \ - ((void (*) (struct bfd_link_hash_table *)) bfd_void) -#define _bfd_nolink_bfd_link_add_symbols \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false) -#define _bfd_nolink_bfd_link_just_syms \ - ((void (*) (asection *, struct bfd_link_info *)) bfd_void) -#define _bfd_nolink_bfd_copy_link_hash_symbol_type \ - ((void (*) (bfd *, struct bfd_link_hash_entry *, \ - struct bfd_link_hash_entry *)) bfd_void) -#define _bfd_nolink_bfd_final_link \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false) -#define _bfd_nolink_bfd_link_split_section \ - ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false) -#define _bfd_nolink_section_already_linked \ - ((bfd_boolean (*) (bfd *, asection *, \ - struct bfd_link_info *)) bfd_false) -#define _bfd_nolink_bfd_define_common_symbol \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *, \ - struct bfd_link_hash_entry *)) bfd_false) - -/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not - have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC - (_bfd_nodynamic). */ - -#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_symtab \ - ((long (*) (bfd *, asymbol **)) _bfd_n1) -#define _bfd_nodynamic_get_synthetic_symtab \ - ((long (*) (bfd *, long, asymbol **, long, asymbol **, asymbol **)) _bfd_n1) -#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_reloc \ - ((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1) - -/* Generic routine to determine of the given symbol is a local - label. */ -extern bfd_boolean bfd_generic_is_local_label_name - (bfd *, const char *); - -/* Generic minisymbol routines. */ -extern long _bfd_generic_read_minisymbols - (bfd *, bfd_boolean, void **, unsigned int *); -extern asymbol *_bfd_generic_minisymbol_to_symbol - (bfd *, bfd_boolean, const void *, asymbol *); - -/* Find the nearest line using .stab/.stabstr sections. */ -extern bfd_boolean _bfd_stab_section_find_nearest_line - (bfd *, asymbol **, asection *, bfd_vma, bfd_boolean *, - const char **, const char **, unsigned int *, void **); - -/* Find the nearest line using DWARF 1 debugging information. */ -extern bfd_boolean _bfd_dwarf1_find_nearest_line - (bfd *, asection *, asymbol **, bfd_vma, const char **, - const char **, unsigned int *); - -/* Find the nearest line using DWARF 2 debugging information. */ -extern bfd_boolean _bfd_dwarf2_find_nearest_line - (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, - unsigned int *, unsigned int, void **); - -/* Find the line using DWARF 2 debugging information. */ -extern bfd_boolean _bfd_dwarf2_find_line - (bfd *, asymbol **, asymbol *, const char **, - unsigned int *, unsigned int, void **); - -bfd_boolean _bfd_generic_find_line - (bfd *, asymbol **, asymbol *, const char **, unsigned int *); - -/* Find inliner info after calling bfd_find_nearest_line. */ -extern bfd_boolean _bfd_dwarf2_find_inliner_info - (bfd *, const char **, const char **, unsigned int *, void **); - -/* Create a new section entry. */ -extern struct bfd_hash_entry *bfd_section_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); - -/* A routine to create entries for a bfd_link_hash_table. */ -extern struct bfd_hash_entry *_bfd_link_hash_newfunc - (struct bfd_hash_entry *entry, struct bfd_hash_table *table, - const char *string); - -/* Initialize a bfd_link_hash_table. */ -extern bfd_boolean _bfd_link_hash_table_init - (struct bfd_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int); - -/* Generic link hash table creation routine. */ -extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create - (bfd *); - -/* Generic link hash table destruction routine. */ -extern void _bfd_generic_link_hash_table_free - (struct bfd_link_hash_table *); - -/* Generic add symbol routine. */ -extern bfd_boolean _bfd_generic_link_add_symbols - (bfd *, struct bfd_link_info *); - -/* Generic add symbol routine. This version is used by targets for - which the linker must collect constructors and destructors by name, - as the collect2 program does. */ -extern bfd_boolean _bfd_generic_link_add_symbols_collect - (bfd *, struct bfd_link_info *); - -/* Generic archive add symbol routine. */ -extern bfd_boolean _bfd_generic_link_add_archive_symbols - (bfd *, struct bfd_link_info *, - bfd_boolean (*) (bfd *, struct bfd_link_info *, bfd_boolean *)); - -/* Forward declaration to avoid prototype errors. */ -typedef struct bfd_link_hash_entry _bfd_link_hash_entry; - -/* Generic routine to add a single symbol. */ -extern bfd_boolean _bfd_generic_link_add_one_symbol - (struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, bfd_boolean copy, - bfd_boolean constructor, struct bfd_link_hash_entry **); - -/* Generic routine to mark section as supplying symbols only. */ -extern void _bfd_generic_link_just_syms - (asection *, struct bfd_link_info *); - -/* Generic routine that does nothing. */ -extern void _bfd_generic_copy_link_hash_symbol_type - (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); - -/* Generic link routine. */ -extern bfd_boolean _bfd_generic_final_link - (bfd *, struct bfd_link_info *); - -extern bfd_boolean _bfd_generic_link_split_section - (bfd *, struct bfd_section *); - -extern bfd_boolean _bfd_generic_section_already_linked - (bfd *, asection *, struct bfd_link_info *); - -/* Generic reloc_link_order processing routine. */ -extern bfd_boolean _bfd_generic_reloc_link_order - (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); - -/* Default link order processing routine. */ -extern bfd_boolean _bfd_default_link_order - (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); - -/* Count the number of reloc entries in a link order list. */ -extern unsigned int _bfd_count_link_order_relocs - (struct bfd_link_order *); - -/* Final link relocation routine. */ -extern bfd_reloc_status_type _bfd_final_link_relocate - (reloc_howto_type *, bfd *, asection *, bfd_byte *, - bfd_vma, bfd_vma, bfd_vma); - -/* Relocate a particular location by a howto and a value. */ -extern bfd_reloc_status_type _bfd_relocate_contents - (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *); - -/* Clear a given location using a given howto. */ -extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd, - asection *input_section, bfd_byte *location); - -/* Link stabs in sections in the first pass. */ - -extern bfd_boolean _bfd_link_section_stabs - (bfd *, struct stab_info *, asection *, asection *, void **, - bfd_size_type *); - -/* Eliminate stabs for discarded functions and symbols. */ -extern bfd_boolean _bfd_discard_section_stabs - (bfd *, asection *, void *, bfd_boolean (*) (bfd_vma, void *), void *); - -/* Write out the .stab section when linking stabs in sections. */ - -extern bfd_boolean _bfd_write_section_stabs - (bfd *, struct stab_info *, asection *, void **, bfd_byte *); - -/* Write out the .stabstr string table when linking stabs in sections. */ - -extern bfd_boolean _bfd_write_stab_strings - (bfd *, struct stab_info *); - -/* Find an offset within a .stab section when linking stabs in - sections. */ - -extern bfd_vma _bfd_stab_section_offset - (asection *, void *, bfd_vma); - -/* Register a SEC_MERGE section as a candidate for merging. */ - -extern bfd_boolean _bfd_add_merge_section - (bfd *, void **, asection *, void **); - -/* Attempt to merge SEC_MERGE sections. */ - -extern bfd_boolean _bfd_merge_sections - (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *)); - -/* Write out a merged section. */ - -extern bfd_boolean _bfd_write_merged_section - (bfd *, asection *, void *); - -/* Find an offset within a modified SEC_MERGE section. */ - -extern bfd_vma _bfd_merged_section_offset - (bfd *, asection **, void *, bfd_vma); - -/* Create a string table. */ -extern struct bfd_strtab_hash *_bfd_stringtab_init - (void); - -/* Create an XCOFF .debug section style string table. */ -extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init - (void); - -/* Free a string table. */ -extern void _bfd_stringtab_free - (struct bfd_strtab_hash *); - -/* Get the size of a string table. */ -extern bfd_size_type _bfd_stringtab_size - (struct bfd_strtab_hash *); - -/* Add a string to a string table. */ -extern bfd_size_type _bfd_stringtab_add - (struct bfd_strtab_hash *, const char *, bfd_boolean hash, bfd_boolean copy); - -/* Write out a string table. */ -extern bfd_boolean _bfd_stringtab_emit - (bfd *, struct bfd_strtab_hash *); - -/* Check that endianness of input and output file match. */ -extern bfd_boolean _bfd_generic_verify_endian_match - (bfd *, bfd *); - -/* Macros to tell if bfds are read or write enabled. - - Note that bfds open for read may be scribbled into if the fd passed - to bfd_fdopenr is actually open both for read and write - simultaneously. However an output bfd will never be open for - read. Therefore sometimes you want to check bfd_read_p or - !bfd_read_p, and only sometimes bfd_write_p. -*/ - -#define bfd_read_p(abfd) \ - ((abfd)->direction == read_direction || (abfd)->direction == both_direction) -#define bfd_write_p(abfd) \ - ((abfd)->direction == write_direction || (abfd)->direction == both_direction) - -void bfd_assert - (const char*,int); - -#define BFD_ASSERT(x) \ - do { if (!(x)) bfd_assert(__FILE__,__LINE__); } while (0) - -#define BFD_FAIL() \ - do { bfd_assert(__FILE__,__LINE__); } while (0) - -extern void _bfd_abort - (const char *, int, const char *) ATTRIBUTE_NORETURN; - -/* if gcc >= 2.6, we can give a function name, too */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) -#define __PRETTY_FUNCTION__ ((char *) NULL) -#endif - -#undef abort -#define abort() _bfd_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) - -/* Manipulate a system FILE but using BFD's "file_ptr", rather than - the system "off_t" or "off64_t", as the offset. */ -extern file_ptr real_ftell (FILE *file); -extern int real_fseek (FILE *file, file_ptr offset, int whence); -extern FILE *real_fopen (const char *filename, const char *modes); - -/* List of supported target vectors, and the default vector (if - bfd_default_vector[0] is NULL, there is no default). */ -extern const bfd_target * const *bfd_target_vector; -extern const bfd_target *bfd_default_vector[]; - -/* List of associated target vectors. */ -extern const bfd_target * const *bfd_associated_vector; - -/* Functions shared by the ECOFF and MIPS ELF backends, which have no - other common header files. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_find_line; -#endif - -extern bfd_boolean _bfd_ecoff_locate_line - (bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, - const struct ecoff_debug_swap * const, struct ecoff_find_line *, - const char **, const char **, unsigned int *); -extern bfd_boolean _bfd_ecoff_get_accumulated_pdr - (void *, bfd_byte *); -extern bfd_boolean _bfd_ecoff_get_accumulated_sym - (void *, bfd_byte *); -extern bfd_boolean _bfd_ecoff_get_accumulated_ss - (void *, bfd_byte *); - -extern bfd_vma _bfd_get_gp_value - (bfd *); -extern void _bfd_set_gp_value - (bfd *, bfd_vma); - -/* Function shared by the COFF and ELF SH backends, which have no - other common header files. */ - -#ifndef _bfd_sh_align_load_span -extern bfd_boolean _bfd_sh_align_load_span - (bfd *, asection *, bfd_byte *, - bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma), - void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *); -#endif - -/* This is the shape of the elements inside the already_linked hash - table. It maps a name onto a list of already_linked elements with - the same name. */ - -struct bfd_section_already_linked_hash_entry -{ - struct bfd_hash_entry root; - struct bfd_section_already_linked *entry; -}; - -struct bfd_section_already_linked -{ - struct bfd_section_already_linked *next; - asection *sec; -}; - -extern struct bfd_section_already_linked_hash_entry * - bfd_section_already_linked_table_lookup (const char *); -extern bfd_boolean bfd_section_already_linked_table_insert - (struct bfd_section_already_linked_hash_entry *, asection *); -extern void bfd_section_already_linked_table_traverse - (bfd_boolean (*) (struct bfd_section_already_linked_hash_entry *, - void *), void *); - -extern bfd_vma read_unsigned_leb128 (bfd *, bfd_byte *, unsigned int *); -extern bfd_signed_vma read_signed_leb128 (bfd *, bfd_byte *, unsigned int *); - -struct dwarf_debug_section -{ - const char *uncompressed_name; - const char *compressed_name; -}; - -/* Map of uncompressed DWARF debug section name to compressed one. It - is terminated by NULL uncompressed_name. */ - -extern const struct dwarf_debug_section dwarf_debug_sections[]; -/* Extracted from init.c. */ -/* Extracted from libbfd.c. */ -bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); - -unsigned int bfd_log2 (bfd_vma x); - -/* Extracted from bfdio.c. */ -struct bfd_iovec -{ - /* To avoid problems with macros, a "b" rather than "f" - prefix is prepended to each method name. */ - /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching - bytes starting at PTR. Return the number of bytes actually - transfered (a read past end-of-file returns less than NBYTES), - or -1 (setting <>) if an error occurs. */ - file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes); - file_ptr (*bwrite) (struct bfd *abfd, const void *ptr, - file_ptr nbytes); - /* Return the current IOSTREAM file offset, or -1 (setting <> - if an error occurs. */ - file_ptr (*btell) (struct bfd *abfd); - /* For the following, on successful completion a value of 0 is returned. - Otherwise, a value of -1 is returned (and <> is set). */ - int (*bseek) (struct bfd *abfd, file_ptr offset, int whence); - int (*bclose) (struct bfd *abfd); - int (*bflush) (struct bfd *abfd); - int (*bstat) (struct bfd *abfd, struct stat *sb); - /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual - mmap parameter, except that LEN and OFFSET do not need to be page - aligned. Returns (void *)-1 on failure, mmapped address on success. - Also write in MAP_ADDR the address of the page aligned buffer and in - MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and - MAP_LEN to unmap. */ - void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, - int prot, int flags, file_ptr offset, - void **map_addr, bfd_size_type *map_len); -}; -extern const struct bfd_iovec _bfd_memory_iovec; -/* Extracted from bfdwin.c. */ -struct _bfd_window_internal { - struct _bfd_window_internal *next; - void *data; - bfd_size_type size; - int refcount : 31; /* should be enough... */ - unsigned mapped : 1; /* 1 = mmap, 0 = malloc */ -}; -/* Extracted from cache.c. */ -bfd_boolean bfd_cache_init (bfd *abfd); - -bfd_boolean bfd_cache_close (bfd *abfd); - -FILE* bfd_open_file (bfd *abfd); - -/* Extracted from reloc.c. */ -#ifdef _BFD_MAKE_TABLE_bfd_reloc_code_real - -static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", - - "BFD_RELOC_64", - "BFD_RELOC_32", - "BFD_RELOC_26", - "BFD_RELOC_24", - "BFD_RELOC_16", - "BFD_RELOC_14", - "BFD_RELOC_8", - "BFD_RELOC_64_PCREL", - "BFD_RELOC_32_PCREL", - "BFD_RELOC_24_PCREL", - "BFD_RELOC_16_PCREL", - "BFD_RELOC_12_PCREL", - "BFD_RELOC_8_PCREL", - "BFD_RELOC_32_SECREL", - "BFD_RELOC_32_GOT_PCREL", - "BFD_RELOC_16_GOT_PCREL", - "BFD_RELOC_8_GOT_PCREL", - "BFD_RELOC_32_GOTOFF", - "BFD_RELOC_16_GOTOFF", - "BFD_RELOC_LO16_GOTOFF", - "BFD_RELOC_HI16_GOTOFF", - "BFD_RELOC_HI16_S_GOTOFF", - "BFD_RELOC_8_GOTOFF", - "BFD_RELOC_64_PLT_PCREL", - "BFD_RELOC_32_PLT_PCREL", - "BFD_RELOC_24_PLT_PCREL", - "BFD_RELOC_16_PLT_PCREL", - "BFD_RELOC_8_PLT_PCREL", - "BFD_RELOC_64_PLTOFF", - "BFD_RELOC_32_PLTOFF", - "BFD_RELOC_16_PLTOFF", - "BFD_RELOC_LO16_PLTOFF", - "BFD_RELOC_HI16_PLTOFF", - "BFD_RELOC_HI16_S_PLTOFF", - "BFD_RELOC_8_PLTOFF", - "BFD_RELOC_68K_GLOB_DAT", - "BFD_RELOC_68K_JMP_SLOT", - "BFD_RELOC_68K_RELATIVE", - "BFD_RELOC_68K_TLS_GD32", - "BFD_RELOC_68K_TLS_GD16", - "BFD_RELOC_68K_TLS_GD8", - "BFD_RELOC_68K_TLS_LDM32", - "BFD_RELOC_68K_TLS_LDM16", - "BFD_RELOC_68K_TLS_LDM8", - "BFD_RELOC_68K_TLS_LDO32", - "BFD_RELOC_68K_TLS_LDO16", - "BFD_RELOC_68K_TLS_LDO8", - "BFD_RELOC_68K_TLS_IE32", - "BFD_RELOC_68K_TLS_IE16", - "BFD_RELOC_68K_TLS_IE8", - "BFD_RELOC_68K_TLS_LE32", - "BFD_RELOC_68K_TLS_LE16", - "BFD_RELOC_68K_TLS_LE8", - "BFD_RELOC_32_BASEREL", - "BFD_RELOC_16_BASEREL", - "BFD_RELOC_LO16_BASEREL", - "BFD_RELOC_HI16_BASEREL", - "BFD_RELOC_HI16_S_BASEREL", - "BFD_RELOC_8_BASEREL", - "BFD_RELOC_RVA", - "BFD_RELOC_8_FFnn", - "BFD_RELOC_32_PCREL_S2", - "BFD_RELOC_16_PCREL_S2", - "BFD_RELOC_23_PCREL_S2", - "BFD_RELOC_HI22", - "BFD_RELOC_LO10", - "BFD_RELOC_GPREL16", - "BFD_RELOC_GPREL32", - "BFD_RELOC_I960_CALLJ", - "BFD_RELOC_NONE", - "BFD_RELOC_SPARC_WDISP22", - "BFD_RELOC_SPARC22", - "BFD_RELOC_SPARC13", - "BFD_RELOC_SPARC_GOT10", - "BFD_RELOC_SPARC_GOT13", - "BFD_RELOC_SPARC_GOT22", - "BFD_RELOC_SPARC_PC10", - "BFD_RELOC_SPARC_PC22", - "BFD_RELOC_SPARC_WPLT30", - "BFD_RELOC_SPARC_COPY", - "BFD_RELOC_SPARC_GLOB_DAT", - "BFD_RELOC_SPARC_JMP_SLOT", - "BFD_RELOC_SPARC_RELATIVE", - "BFD_RELOC_SPARC_UA16", - "BFD_RELOC_SPARC_UA32", - "BFD_RELOC_SPARC_UA64", - "BFD_RELOC_SPARC_GOTDATA_HIX22", - "BFD_RELOC_SPARC_GOTDATA_LOX10", - "BFD_RELOC_SPARC_GOTDATA_OP_HIX22", - "BFD_RELOC_SPARC_GOTDATA_OP_LOX10", - "BFD_RELOC_SPARC_GOTDATA_OP", - "BFD_RELOC_SPARC_JMP_IREL", - "BFD_RELOC_SPARC_IRELATIVE", - "BFD_RELOC_SPARC_BASE13", - "BFD_RELOC_SPARC_BASE22", - "BFD_RELOC_SPARC_10", - "BFD_RELOC_SPARC_11", - "BFD_RELOC_SPARC_OLO10", - "BFD_RELOC_SPARC_HH22", - "BFD_RELOC_SPARC_HM10", - "BFD_RELOC_SPARC_LM22", - "BFD_RELOC_SPARC_PC_HH22", - "BFD_RELOC_SPARC_PC_HM10", - "BFD_RELOC_SPARC_PC_LM22", - "BFD_RELOC_SPARC_WDISP16", - "BFD_RELOC_SPARC_WDISP19", - "BFD_RELOC_SPARC_7", - "BFD_RELOC_SPARC_6", - "BFD_RELOC_SPARC_5", - "BFD_RELOC_SPARC_PLT32", - "BFD_RELOC_SPARC_PLT64", - "BFD_RELOC_SPARC_HIX22", - "BFD_RELOC_SPARC_LOX10", - "BFD_RELOC_SPARC_H44", - "BFD_RELOC_SPARC_M44", - "BFD_RELOC_SPARC_L44", - "BFD_RELOC_SPARC_REGISTER", - "BFD_RELOC_SPARC_REV32", - "BFD_RELOC_SPARC_TLS_GD_HI22", - "BFD_RELOC_SPARC_TLS_GD_LO10", - "BFD_RELOC_SPARC_TLS_GD_ADD", - "BFD_RELOC_SPARC_TLS_GD_CALL", - "BFD_RELOC_SPARC_TLS_LDM_HI22", - "BFD_RELOC_SPARC_TLS_LDM_LO10", - "BFD_RELOC_SPARC_TLS_LDM_ADD", - "BFD_RELOC_SPARC_TLS_LDM_CALL", - "BFD_RELOC_SPARC_TLS_LDO_HIX22", - "BFD_RELOC_SPARC_TLS_LDO_LOX10", - "BFD_RELOC_SPARC_TLS_LDO_ADD", - "BFD_RELOC_SPARC_TLS_IE_HI22", - "BFD_RELOC_SPARC_TLS_IE_LO10", - "BFD_RELOC_SPARC_TLS_IE_LD", - "BFD_RELOC_SPARC_TLS_IE_LDX", - "BFD_RELOC_SPARC_TLS_IE_ADD", - "BFD_RELOC_SPARC_TLS_LE_HIX22", - "BFD_RELOC_SPARC_TLS_LE_LOX10", - "BFD_RELOC_SPARC_TLS_DTPMOD32", - "BFD_RELOC_SPARC_TLS_DTPMOD64", - "BFD_RELOC_SPARC_TLS_DTPOFF32", - "BFD_RELOC_SPARC_TLS_DTPOFF64", - "BFD_RELOC_SPARC_TLS_TPOFF32", - "BFD_RELOC_SPARC_TLS_TPOFF64", - "BFD_RELOC_SPU_IMM7", - "BFD_RELOC_SPU_IMM8", - "BFD_RELOC_SPU_IMM10", - "BFD_RELOC_SPU_IMM10W", - "BFD_RELOC_SPU_IMM16", - "BFD_RELOC_SPU_IMM16W", - "BFD_RELOC_SPU_IMM18", - "BFD_RELOC_SPU_PCREL9a", - "BFD_RELOC_SPU_PCREL9b", - "BFD_RELOC_SPU_PCREL16", - "BFD_RELOC_SPU_LO16", - "BFD_RELOC_SPU_HI16", - "BFD_RELOC_SPU_PPU32", - "BFD_RELOC_SPU_PPU64", - "BFD_RELOC_SPU_ADD_PIC", - "BFD_RELOC_ALPHA_GPDISP_HI16", - "BFD_RELOC_ALPHA_GPDISP_LO16", - "BFD_RELOC_ALPHA_GPDISP", - "BFD_RELOC_ALPHA_LITERAL", - "BFD_RELOC_ALPHA_ELF_LITERAL", - "BFD_RELOC_ALPHA_LITUSE", - "BFD_RELOC_ALPHA_HINT", - "BFD_RELOC_ALPHA_LINKAGE", - "BFD_RELOC_ALPHA_CODEADDR", - "BFD_RELOC_ALPHA_GPREL_HI16", - "BFD_RELOC_ALPHA_GPREL_LO16", - "BFD_RELOC_ALPHA_BRSGP", - "BFD_RELOC_ALPHA_NOP", - "BFD_RELOC_ALPHA_BSR", - "BFD_RELOC_ALPHA_LDA", - "BFD_RELOC_ALPHA_BOH", - "BFD_RELOC_ALPHA_TLSGD", - "BFD_RELOC_ALPHA_TLSLDM", - "BFD_RELOC_ALPHA_DTPMOD64", - "BFD_RELOC_ALPHA_GOTDTPREL16", - "BFD_RELOC_ALPHA_DTPREL64", - "BFD_RELOC_ALPHA_DTPREL_HI16", - "BFD_RELOC_ALPHA_DTPREL_LO16", - "BFD_RELOC_ALPHA_DTPREL16", - "BFD_RELOC_ALPHA_GOTTPREL16", - "BFD_RELOC_ALPHA_TPREL64", - "BFD_RELOC_ALPHA_TPREL_HI16", - "BFD_RELOC_ALPHA_TPREL_LO16", - "BFD_RELOC_ALPHA_TPREL16", - "BFD_RELOC_MIPS_JMP", - "BFD_RELOC_MICROMIPS_JMP", - "BFD_RELOC_MIPS16_JMP", - "BFD_RELOC_MIPS16_GPREL", - "BFD_RELOC_HI16", - "BFD_RELOC_HI16_S", - "BFD_RELOC_LO16", - "BFD_RELOC_HI16_PCREL", - "BFD_RELOC_HI16_S_PCREL", - "BFD_RELOC_LO16_PCREL", - "BFD_RELOC_MIPS16_GOT16", - "BFD_RELOC_MIPS16_CALL16", - "BFD_RELOC_MIPS16_HI16", - "BFD_RELOC_MIPS16_HI16_S", - "BFD_RELOC_MIPS16_LO16", - "BFD_RELOC_MIPS_LITERAL", - "BFD_RELOC_MICROMIPS_LITERAL", - "BFD_RELOC_MICROMIPS_7_PCREL_S1", - "BFD_RELOC_MICROMIPS_10_PCREL_S1", - "BFD_RELOC_MICROMIPS_16_PCREL_S1", - "BFD_RELOC_MICROMIPS_GPREL16", - "BFD_RELOC_MICROMIPS_HI16", - "BFD_RELOC_MICROMIPS_HI16_S", - "BFD_RELOC_MICROMIPS_LO16", - "BFD_RELOC_MIPS_GOT16", - "BFD_RELOC_MICROMIPS_GOT16", - "BFD_RELOC_MIPS_CALL16", - "BFD_RELOC_MICROMIPS_CALL16", - "BFD_RELOC_MIPS_GOT_HI16", - "BFD_RELOC_MICROMIPS_GOT_HI16", - "BFD_RELOC_MIPS_GOT_LO16", - "BFD_RELOC_MICROMIPS_GOT_LO16", - "BFD_RELOC_MIPS_CALL_HI16", - "BFD_RELOC_MICROMIPS_CALL_HI16", - "BFD_RELOC_MIPS_CALL_LO16", - "BFD_RELOC_MICROMIPS_CALL_LO16", - "BFD_RELOC_MIPS_SUB", - "BFD_RELOC_MICROMIPS_SUB", - "BFD_RELOC_MIPS_GOT_PAGE", - "BFD_RELOC_MICROMIPS_GOT_PAGE", - "BFD_RELOC_MIPS_GOT_OFST", - "BFD_RELOC_MICROMIPS_GOT_OFST", - "BFD_RELOC_MIPS_GOT_DISP", - "BFD_RELOC_MICROMIPS_GOT_DISP", - "BFD_RELOC_MIPS_SHIFT5", - "BFD_RELOC_MIPS_SHIFT6", - "BFD_RELOC_MIPS_INSERT_A", - "BFD_RELOC_MIPS_INSERT_B", - "BFD_RELOC_MIPS_DELETE", - "BFD_RELOC_MIPS_HIGHEST", - "BFD_RELOC_MICROMIPS_HIGHEST", - "BFD_RELOC_MIPS_HIGHER", - "BFD_RELOC_MICROMIPS_HIGHER", - "BFD_RELOC_MIPS_SCN_DISP", - "BFD_RELOC_MICROMIPS_SCN_DISP", - "BFD_RELOC_MIPS_REL16", - "BFD_RELOC_MIPS_RELGOT", - "BFD_RELOC_MIPS_JALR", - "BFD_RELOC_MICROMIPS_JALR", - "BFD_RELOC_MIPS_TLS_DTPMOD32", - "BFD_RELOC_MIPS_TLS_DTPREL32", - "BFD_RELOC_MIPS_TLS_DTPMOD64", - "BFD_RELOC_MIPS_TLS_DTPREL64", - "BFD_RELOC_MIPS_TLS_GD", - "BFD_RELOC_MICROMIPS_TLS_GD", - "BFD_RELOC_MIPS_TLS_LDM", - "BFD_RELOC_MICROMIPS_TLS_LDM", - "BFD_RELOC_MIPS_TLS_DTPREL_HI16", - "BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16", - "BFD_RELOC_MIPS_TLS_DTPREL_LO16", - "BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16", - "BFD_RELOC_MIPS_TLS_GOTTPREL", - "BFD_RELOC_MICROMIPS_TLS_GOTTPREL", - "BFD_RELOC_MIPS_TLS_TPREL32", - "BFD_RELOC_MIPS_TLS_TPREL64", - "BFD_RELOC_MIPS_TLS_TPREL_HI16", - "BFD_RELOC_MICROMIPS_TLS_TPREL_HI16", - "BFD_RELOC_MIPS_TLS_TPREL_LO16", - "BFD_RELOC_MICROMIPS_TLS_TPREL_LO16", - - "BFD_RELOC_MIPS_COPY", - "BFD_RELOC_MIPS_JUMP_SLOT", - - "BFD_RELOC_MOXIE_10_PCREL", - - "BFD_RELOC_FRV_LABEL16", - "BFD_RELOC_FRV_LABEL24", - "BFD_RELOC_FRV_LO16", - "BFD_RELOC_FRV_HI16", - "BFD_RELOC_FRV_GPREL12", - "BFD_RELOC_FRV_GPRELU12", - "BFD_RELOC_FRV_GPREL32", - "BFD_RELOC_FRV_GPRELHI", - "BFD_RELOC_FRV_GPRELLO", - "BFD_RELOC_FRV_GOT12", - "BFD_RELOC_FRV_GOTHI", - "BFD_RELOC_FRV_GOTLO", - "BFD_RELOC_FRV_FUNCDESC", - "BFD_RELOC_FRV_FUNCDESC_GOT12", - "BFD_RELOC_FRV_FUNCDESC_GOTHI", - "BFD_RELOC_FRV_FUNCDESC_GOTLO", - "BFD_RELOC_FRV_FUNCDESC_VALUE", - "BFD_RELOC_FRV_FUNCDESC_GOTOFF12", - "BFD_RELOC_FRV_FUNCDESC_GOTOFFHI", - "BFD_RELOC_FRV_FUNCDESC_GOTOFFLO", - "BFD_RELOC_FRV_GOTOFF12", - "BFD_RELOC_FRV_GOTOFFHI", - "BFD_RELOC_FRV_GOTOFFLO", - "BFD_RELOC_FRV_GETTLSOFF", - "BFD_RELOC_FRV_TLSDESC_VALUE", - "BFD_RELOC_FRV_GOTTLSDESC12", - "BFD_RELOC_FRV_GOTTLSDESCHI", - "BFD_RELOC_FRV_GOTTLSDESCLO", - "BFD_RELOC_FRV_TLSMOFF12", - "BFD_RELOC_FRV_TLSMOFFHI", - "BFD_RELOC_FRV_TLSMOFFLO", - "BFD_RELOC_FRV_GOTTLSOFF12", - "BFD_RELOC_FRV_GOTTLSOFFHI", - "BFD_RELOC_FRV_GOTTLSOFFLO", - "BFD_RELOC_FRV_TLSOFF", - "BFD_RELOC_FRV_TLSDESC_RELAX", - "BFD_RELOC_FRV_GETTLSOFF_RELAX", - "BFD_RELOC_FRV_TLSOFF_RELAX", - "BFD_RELOC_FRV_TLSMOFF", - - "BFD_RELOC_MN10300_GOTOFF24", - "BFD_RELOC_MN10300_GOT32", - "BFD_RELOC_MN10300_GOT24", - "BFD_RELOC_MN10300_GOT16", - "BFD_RELOC_MN10300_COPY", - "BFD_RELOC_MN10300_GLOB_DAT", - "BFD_RELOC_MN10300_JMP_SLOT", - "BFD_RELOC_MN10300_RELATIVE", - "BFD_RELOC_MN10300_SYM_DIFF", - "BFD_RELOC_MN10300_ALIGN", - - "BFD_RELOC_386_GOT32", - "BFD_RELOC_386_PLT32", - "BFD_RELOC_386_COPY", - "BFD_RELOC_386_GLOB_DAT", - "BFD_RELOC_386_JUMP_SLOT", - "BFD_RELOC_386_RELATIVE", - "BFD_RELOC_386_GOTOFF", - "BFD_RELOC_386_GOTPC", - "BFD_RELOC_386_TLS_TPOFF", - "BFD_RELOC_386_TLS_IE", - "BFD_RELOC_386_TLS_GOTIE", - "BFD_RELOC_386_TLS_LE", - "BFD_RELOC_386_TLS_GD", - "BFD_RELOC_386_TLS_LDM", - "BFD_RELOC_386_TLS_LDO_32", - "BFD_RELOC_386_TLS_IE_32", - "BFD_RELOC_386_TLS_LE_32", - "BFD_RELOC_386_TLS_DTPMOD32", - "BFD_RELOC_386_TLS_DTPOFF32", - "BFD_RELOC_386_TLS_TPOFF32", - "BFD_RELOC_386_TLS_GOTDESC", - "BFD_RELOC_386_TLS_DESC_CALL", - "BFD_RELOC_386_TLS_DESC", - "BFD_RELOC_386_IRELATIVE", - "BFD_RELOC_X86_64_GOT32", - "BFD_RELOC_X86_64_PLT32", - "BFD_RELOC_X86_64_COPY", - "BFD_RELOC_X86_64_GLOB_DAT", - "BFD_RELOC_X86_64_JUMP_SLOT", - "BFD_RELOC_X86_64_RELATIVE", - "BFD_RELOC_X86_64_GOTPCREL", - "BFD_RELOC_X86_64_32S", - "BFD_RELOC_X86_64_DTPMOD64", - "BFD_RELOC_X86_64_DTPOFF64", - "BFD_RELOC_X86_64_TPOFF64", - "BFD_RELOC_X86_64_TLSGD", - "BFD_RELOC_X86_64_TLSLD", - "BFD_RELOC_X86_64_DTPOFF32", - "BFD_RELOC_X86_64_GOTTPOFF", - "BFD_RELOC_X86_64_TPOFF32", - "BFD_RELOC_X86_64_GOTOFF64", - "BFD_RELOC_X86_64_GOTPC32", - "BFD_RELOC_X86_64_GOT64", - "BFD_RELOC_X86_64_GOTPCREL64", - "BFD_RELOC_X86_64_GOTPC64", - "BFD_RELOC_X86_64_GOTPLT64", - "BFD_RELOC_X86_64_PLTOFF64", - "BFD_RELOC_X86_64_GOTPC32_TLSDESC", - "BFD_RELOC_X86_64_TLSDESC_CALL", - "BFD_RELOC_X86_64_TLSDESC", - "BFD_RELOC_X86_64_IRELATIVE", - "BFD_RELOC_NS32K_IMM_8", - "BFD_RELOC_NS32K_IMM_16", - "BFD_RELOC_NS32K_IMM_32", - "BFD_RELOC_NS32K_IMM_8_PCREL", - "BFD_RELOC_NS32K_IMM_16_PCREL", - "BFD_RELOC_NS32K_IMM_32_PCREL", - "BFD_RELOC_NS32K_DISP_8", - "BFD_RELOC_NS32K_DISP_16", - "BFD_RELOC_NS32K_DISP_32", - "BFD_RELOC_NS32K_DISP_8_PCREL", - "BFD_RELOC_NS32K_DISP_16_PCREL", - "BFD_RELOC_NS32K_DISP_32_PCREL", - "BFD_RELOC_PDP11_DISP_8_PCREL", - "BFD_RELOC_PDP11_DISP_6_PCREL", - "BFD_RELOC_PJ_CODE_HI16", - "BFD_RELOC_PJ_CODE_LO16", - "BFD_RELOC_PJ_CODE_DIR16", - "BFD_RELOC_PJ_CODE_DIR32", - "BFD_RELOC_PJ_CODE_REL16", - "BFD_RELOC_PJ_CODE_REL32", - "BFD_RELOC_PPC_B26", - "BFD_RELOC_PPC_BA26", - "BFD_RELOC_PPC_TOC16", - "BFD_RELOC_PPC_B16", - "BFD_RELOC_PPC_B16_BRTAKEN", - "BFD_RELOC_PPC_B16_BRNTAKEN", - "BFD_RELOC_PPC_BA16", - "BFD_RELOC_PPC_BA16_BRTAKEN", - "BFD_RELOC_PPC_BA16_BRNTAKEN", - "BFD_RELOC_PPC_COPY", - "BFD_RELOC_PPC_GLOB_DAT", - "BFD_RELOC_PPC_JMP_SLOT", - "BFD_RELOC_PPC_RELATIVE", - "BFD_RELOC_PPC_LOCAL24PC", - "BFD_RELOC_PPC_EMB_NADDR32", - "BFD_RELOC_PPC_EMB_NADDR16", - "BFD_RELOC_PPC_EMB_NADDR16_LO", - "BFD_RELOC_PPC_EMB_NADDR16_HI", - "BFD_RELOC_PPC_EMB_NADDR16_HA", - "BFD_RELOC_PPC_EMB_SDAI16", - "BFD_RELOC_PPC_EMB_SDA2I16", - "BFD_RELOC_PPC_EMB_SDA2REL", - "BFD_RELOC_PPC_EMB_SDA21", - "BFD_RELOC_PPC_EMB_MRKREF", - "BFD_RELOC_PPC_EMB_RELSEC16", - "BFD_RELOC_PPC_EMB_RELST_LO", - "BFD_RELOC_PPC_EMB_RELST_HI", - "BFD_RELOC_PPC_EMB_RELST_HA", - "BFD_RELOC_PPC_EMB_BIT_FLD", - "BFD_RELOC_PPC_EMB_RELSDA", - "BFD_RELOC_PPC64_HIGHER", - "BFD_RELOC_PPC64_HIGHER_S", - "BFD_RELOC_PPC64_HIGHEST", - "BFD_RELOC_PPC64_HIGHEST_S", - "BFD_RELOC_PPC64_TOC16_LO", - "BFD_RELOC_PPC64_TOC16_HI", - "BFD_RELOC_PPC64_TOC16_HA", - "BFD_RELOC_PPC64_TOC", - "BFD_RELOC_PPC64_PLTGOT16", - "BFD_RELOC_PPC64_PLTGOT16_LO", - "BFD_RELOC_PPC64_PLTGOT16_HI", - "BFD_RELOC_PPC64_PLTGOT16_HA", - "BFD_RELOC_PPC64_ADDR16_DS", - "BFD_RELOC_PPC64_ADDR16_LO_DS", - "BFD_RELOC_PPC64_GOT16_DS", - "BFD_RELOC_PPC64_GOT16_LO_DS", - "BFD_RELOC_PPC64_PLT16_LO_DS", - "BFD_RELOC_PPC64_SECTOFF_DS", - "BFD_RELOC_PPC64_SECTOFF_LO_DS", - "BFD_RELOC_PPC64_TOC16_DS", - "BFD_RELOC_PPC64_TOC16_LO_DS", - "BFD_RELOC_PPC64_PLTGOT16_DS", - "BFD_RELOC_PPC64_PLTGOT16_LO_DS", - "BFD_RELOC_PPC_TLS", - "BFD_RELOC_PPC_TLSGD", - "BFD_RELOC_PPC_TLSLD", - "BFD_RELOC_PPC_DTPMOD", - "BFD_RELOC_PPC_TPREL16", - "BFD_RELOC_PPC_TPREL16_LO", - "BFD_RELOC_PPC_TPREL16_HI", - "BFD_RELOC_PPC_TPREL16_HA", - "BFD_RELOC_PPC_TPREL", - "BFD_RELOC_PPC_DTPREL16", - "BFD_RELOC_PPC_DTPREL16_LO", - "BFD_RELOC_PPC_DTPREL16_HI", - "BFD_RELOC_PPC_DTPREL16_HA", - "BFD_RELOC_PPC_DTPREL", - "BFD_RELOC_PPC_GOT_TLSGD16", - "BFD_RELOC_PPC_GOT_TLSGD16_LO", - "BFD_RELOC_PPC_GOT_TLSGD16_HI", - "BFD_RELOC_PPC_GOT_TLSGD16_HA", - "BFD_RELOC_PPC_GOT_TLSLD16", - "BFD_RELOC_PPC_GOT_TLSLD16_LO", - "BFD_RELOC_PPC_GOT_TLSLD16_HI", - "BFD_RELOC_PPC_GOT_TLSLD16_HA", - "BFD_RELOC_PPC_GOT_TPREL16", - "BFD_RELOC_PPC_GOT_TPREL16_LO", - "BFD_RELOC_PPC_GOT_TPREL16_HI", - "BFD_RELOC_PPC_GOT_TPREL16_HA", - "BFD_RELOC_PPC_GOT_DTPREL16", - "BFD_RELOC_PPC_GOT_DTPREL16_LO", - "BFD_RELOC_PPC_GOT_DTPREL16_HI", - "BFD_RELOC_PPC_GOT_DTPREL16_HA", - "BFD_RELOC_PPC64_TPREL16_DS", - "BFD_RELOC_PPC64_TPREL16_LO_DS", - "BFD_RELOC_PPC64_TPREL16_HIGHER", - "BFD_RELOC_PPC64_TPREL16_HIGHERA", - "BFD_RELOC_PPC64_TPREL16_HIGHEST", - "BFD_RELOC_PPC64_TPREL16_HIGHESTA", - "BFD_RELOC_PPC64_DTPREL16_DS", - "BFD_RELOC_PPC64_DTPREL16_LO_DS", - "BFD_RELOC_PPC64_DTPREL16_HIGHER", - "BFD_RELOC_PPC64_DTPREL16_HIGHERA", - "BFD_RELOC_PPC64_DTPREL16_HIGHEST", - "BFD_RELOC_PPC64_DTPREL16_HIGHESTA", - "BFD_RELOC_I370_D12", - "BFD_RELOC_CTOR", - "BFD_RELOC_ARM_PCREL_BRANCH", - "BFD_RELOC_ARM_PCREL_BLX", - "BFD_RELOC_THUMB_PCREL_BLX", - "BFD_RELOC_ARM_PCREL_CALL", - "BFD_RELOC_ARM_PCREL_JUMP", - "BFD_RELOC_THUMB_PCREL_BRANCH7", - "BFD_RELOC_THUMB_PCREL_BRANCH9", - "BFD_RELOC_THUMB_PCREL_BRANCH12", - "BFD_RELOC_THUMB_PCREL_BRANCH20", - "BFD_RELOC_THUMB_PCREL_BRANCH23", - "BFD_RELOC_THUMB_PCREL_BRANCH25", - "BFD_RELOC_ARM_OFFSET_IMM", - "BFD_RELOC_ARM_THUMB_OFFSET", - "BFD_RELOC_ARM_TARGET1", - "BFD_RELOC_ARM_ROSEGREL32", - "BFD_RELOC_ARM_SBREL32", - "BFD_RELOC_ARM_TARGET2", - "BFD_RELOC_ARM_PREL31", - "BFD_RELOC_ARM_MOVW", - "BFD_RELOC_ARM_MOVT", - "BFD_RELOC_ARM_MOVW_PCREL", - "BFD_RELOC_ARM_MOVT_PCREL", - "BFD_RELOC_ARM_THUMB_MOVW", - "BFD_RELOC_ARM_THUMB_MOVT", - "BFD_RELOC_ARM_THUMB_MOVW_PCREL", - "BFD_RELOC_ARM_THUMB_MOVT_PCREL", - "BFD_RELOC_ARM_JUMP_SLOT", - "BFD_RELOC_ARM_GLOB_DAT", - "BFD_RELOC_ARM_GOT32", - "BFD_RELOC_ARM_PLT32", - "BFD_RELOC_ARM_RELATIVE", - "BFD_RELOC_ARM_GOTOFF", - "BFD_RELOC_ARM_GOTPC", - "BFD_RELOC_ARM_GOT_PREL", - "BFD_RELOC_ARM_TLS_GD32", - "BFD_RELOC_ARM_TLS_LDO32", - "BFD_RELOC_ARM_TLS_LDM32", - "BFD_RELOC_ARM_TLS_DTPOFF32", - "BFD_RELOC_ARM_TLS_DTPMOD32", - "BFD_RELOC_ARM_TLS_TPOFF32", - "BFD_RELOC_ARM_TLS_IE32", - "BFD_RELOC_ARM_TLS_LE32", - "BFD_RELOC_ARM_TLS_GOTDESC", - "BFD_RELOC_ARM_TLS_CALL", - "BFD_RELOC_ARM_THM_TLS_CALL", - "BFD_RELOC_ARM_TLS_DESCSEQ", - "BFD_RELOC_ARM_THM_TLS_DESCSEQ", - "BFD_RELOC_ARM_TLS_DESC", - "BFD_RELOC_ARM_ALU_PC_G0_NC", - "BFD_RELOC_ARM_ALU_PC_G0", - "BFD_RELOC_ARM_ALU_PC_G1_NC", - "BFD_RELOC_ARM_ALU_PC_G1", - "BFD_RELOC_ARM_ALU_PC_G2", - "BFD_RELOC_ARM_LDR_PC_G0", - "BFD_RELOC_ARM_LDR_PC_G1", - "BFD_RELOC_ARM_LDR_PC_G2", - "BFD_RELOC_ARM_LDRS_PC_G0", - "BFD_RELOC_ARM_LDRS_PC_G1", - "BFD_RELOC_ARM_LDRS_PC_G2", - "BFD_RELOC_ARM_LDC_PC_G0", - "BFD_RELOC_ARM_LDC_PC_G1", - "BFD_RELOC_ARM_LDC_PC_G2", - "BFD_RELOC_ARM_ALU_SB_G0_NC", - "BFD_RELOC_ARM_ALU_SB_G0", - "BFD_RELOC_ARM_ALU_SB_G1_NC", - "BFD_RELOC_ARM_ALU_SB_G1", - "BFD_RELOC_ARM_ALU_SB_G2", - "BFD_RELOC_ARM_LDR_SB_G0", - "BFD_RELOC_ARM_LDR_SB_G1", - "BFD_RELOC_ARM_LDR_SB_G2", - "BFD_RELOC_ARM_LDRS_SB_G0", - "BFD_RELOC_ARM_LDRS_SB_G1", - "BFD_RELOC_ARM_LDRS_SB_G2", - "BFD_RELOC_ARM_LDC_SB_G0", - "BFD_RELOC_ARM_LDC_SB_G1", - "BFD_RELOC_ARM_LDC_SB_G2", - "BFD_RELOC_ARM_V4BX", - "BFD_RELOC_ARM_IRELATIVE", - "BFD_RELOC_ARM_IMMEDIATE", - "BFD_RELOC_ARM_ADRL_IMMEDIATE", - "BFD_RELOC_ARM_T32_IMMEDIATE", - "BFD_RELOC_ARM_T32_ADD_IMM", - "BFD_RELOC_ARM_T32_IMM12", - "BFD_RELOC_ARM_T32_ADD_PC12", - "BFD_RELOC_ARM_SHIFT_IMM", - "BFD_RELOC_ARM_SMC", - "BFD_RELOC_ARM_HVC", - "BFD_RELOC_ARM_SWI", - "BFD_RELOC_ARM_MULTI", - "BFD_RELOC_ARM_CP_OFF_IMM", - "BFD_RELOC_ARM_CP_OFF_IMM_S2", - "BFD_RELOC_ARM_T32_CP_OFF_IMM", - "BFD_RELOC_ARM_T32_CP_OFF_IMM_S2", - "BFD_RELOC_ARM_ADR_IMM", - "BFD_RELOC_ARM_LDR_IMM", - "BFD_RELOC_ARM_LITERAL", - "BFD_RELOC_ARM_IN_POOL", - "BFD_RELOC_ARM_OFFSET_IMM8", - "BFD_RELOC_ARM_T32_OFFSET_U8", - "BFD_RELOC_ARM_T32_OFFSET_IMM", - "BFD_RELOC_ARM_HWLITERAL", - "BFD_RELOC_ARM_THUMB_ADD", - "BFD_RELOC_ARM_THUMB_IMM", - "BFD_RELOC_ARM_THUMB_SHIFT", - "BFD_RELOC_SH_PCDISP8BY2", - "BFD_RELOC_SH_PCDISP12BY2", - "BFD_RELOC_SH_IMM3", - "BFD_RELOC_SH_IMM3U", - "BFD_RELOC_SH_DISP12", - "BFD_RELOC_SH_DISP12BY2", - "BFD_RELOC_SH_DISP12BY4", - "BFD_RELOC_SH_DISP12BY8", - "BFD_RELOC_SH_DISP20", - "BFD_RELOC_SH_DISP20BY8", - "BFD_RELOC_SH_IMM4", - "BFD_RELOC_SH_IMM4BY2", - "BFD_RELOC_SH_IMM4BY4", - "BFD_RELOC_SH_IMM8", - "BFD_RELOC_SH_IMM8BY2", - "BFD_RELOC_SH_IMM8BY4", - "BFD_RELOC_SH_PCRELIMM8BY2", - "BFD_RELOC_SH_PCRELIMM8BY4", - "BFD_RELOC_SH_SWITCH16", - "BFD_RELOC_SH_SWITCH32", - "BFD_RELOC_SH_USES", - "BFD_RELOC_SH_COUNT", - "BFD_RELOC_SH_ALIGN", - "BFD_RELOC_SH_CODE", - "BFD_RELOC_SH_DATA", - "BFD_RELOC_SH_LABEL", - "BFD_RELOC_SH_LOOP_START", - "BFD_RELOC_SH_LOOP_END", - "BFD_RELOC_SH_COPY", - "BFD_RELOC_SH_GLOB_DAT", - "BFD_RELOC_SH_JMP_SLOT", - "BFD_RELOC_SH_RELATIVE", - "BFD_RELOC_SH_GOTPC", - "BFD_RELOC_SH_GOT_LOW16", - "BFD_RELOC_SH_GOT_MEDLOW16", - "BFD_RELOC_SH_GOT_MEDHI16", - "BFD_RELOC_SH_GOT_HI16", - "BFD_RELOC_SH_GOTPLT_LOW16", - "BFD_RELOC_SH_GOTPLT_MEDLOW16", - "BFD_RELOC_SH_GOTPLT_MEDHI16", - "BFD_RELOC_SH_GOTPLT_HI16", - "BFD_RELOC_SH_PLT_LOW16", - "BFD_RELOC_SH_PLT_MEDLOW16", - "BFD_RELOC_SH_PLT_MEDHI16", - "BFD_RELOC_SH_PLT_HI16", - "BFD_RELOC_SH_GOTOFF_LOW16", - "BFD_RELOC_SH_GOTOFF_MEDLOW16", - "BFD_RELOC_SH_GOTOFF_MEDHI16", - "BFD_RELOC_SH_GOTOFF_HI16", - "BFD_RELOC_SH_GOTPC_LOW16", - "BFD_RELOC_SH_GOTPC_MEDLOW16", - "BFD_RELOC_SH_GOTPC_MEDHI16", - "BFD_RELOC_SH_GOTPC_HI16", - "BFD_RELOC_SH_COPY64", - "BFD_RELOC_SH_GLOB_DAT64", - "BFD_RELOC_SH_JMP_SLOT64", - "BFD_RELOC_SH_RELATIVE64", - "BFD_RELOC_SH_GOT10BY4", - "BFD_RELOC_SH_GOT10BY8", - "BFD_RELOC_SH_GOTPLT10BY4", - "BFD_RELOC_SH_GOTPLT10BY8", - "BFD_RELOC_SH_GOTPLT32", - "BFD_RELOC_SH_SHMEDIA_CODE", - "BFD_RELOC_SH_IMMU5", - "BFD_RELOC_SH_IMMS6", - "BFD_RELOC_SH_IMMS6BY32", - "BFD_RELOC_SH_IMMU6", - "BFD_RELOC_SH_IMMS10", - "BFD_RELOC_SH_IMMS10BY2", - "BFD_RELOC_SH_IMMS10BY4", - "BFD_RELOC_SH_IMMS10BY8", - "BFD_RELOC_SH_IMMS16", - "BFD_RELOC_SH_IMMU16", - "BFD_RELOC_SH_IMM_LOW16", - "BFD_RELOC_SH_IMM_LOW16_PCREL", - "BFD_RELOC_SH_IMM_MEDLOW16", - "BFD_RELOC_SH_IMM_MEDLOW16_PCREL", - "BFD_RELOC_SH_IMM_MEDHI16", - "BFD_RELOC_SH_IMM_MEDHI16_PCREL", - "BFD_RELOC_SH_IMM_HI16", - "BFD_RELOC_SH_IMM_HI16_PCREL", - "BFD_RELOC_SH_PT_16", - "BFD_RELOC_SH_TLS_GD_32", - "BFD_RELOC_SH_TLS_LD_32", - "BFD_RELOC_SH_TLS_LDO_32", - "BFD_RELOC_SH_TLS_IE_32", - "BFD_RELOC_SH_TLS_LE_32", - "BFD_RELOC_SH_TLS_DTPMOD32", - "BFD_RELOC_SH_TLS_DTPOFF32", - "BFD_RELOC_SH_TLS_TPOFF32", - "BFD_RELOC_SH_GOT20", - "BFD_RELOC_SH_GOTOFF20", - "BFD_RELOC_SH_GOTFUNCDESC", - "BFD_RELOC_SH_GOTFUNCDESC20", - "BFD_RELOC_SH_GOTOFFFUNCDESC", - "BFD_RELOC_SH_GOTOFFFUNCDESC20", - "BFD_RELOC_SH_FUNCDESC", - "BFD_RELOC_ARC_B22_PCREL", - "BFD_RELOC_ARC_B26", - "BFD_RELOC_BFIN_16_IMM", - "BFD_RELOC_BFIN_16_HIGH", - "BFD_RELOC_BFIN_4_PCREL", - "BFD_RELOC_BFIN_5_PCREL", - "BFD_RELOC_BFIN_16_LOW", - "BFD_RELOC_BFIN_10_PCREL", - "BFD_RELOC_BFIN_11_PCREL", - "BFD_RELOC_BFIN_12_PCREL_JUMP", - "BFD_RELOC_BFIN_12_PCREL_JUMP_S", - "BFD_RELOC_BFIN_24_PCREL_CALL_X", - "BFD_RELOC_BFIN_24_PCREL_JUMP_L", - "BFD_RELOC_BFIN_GOT17M4", - "BFD_RELOC_BFIN_GOTHI", - "BFD_RELOC_BFIN_GOTLO", - "BFD_RELOC_BFIN_FUNCDESC", - "BFD_RELOC_BFIN_FUNCDESC_GOT17M4", - "BFD_RELOC_BFIN_FUNCDESC_GOTHI", - "BFD_RELOC_BFIN_FUNCDESC_GOTLO", - "BFD_RELOC_BFIN_FUNCDESC_VALUE", - "BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4", - "BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI", - "BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO", - "BFD_RELOC_BFIN_GOTOFF17M4", - "BFD_RELOC_BFIN_GOTOFFHI", - "BFD_RELOC_BFIN_GOTOFFLO", - "BFD_RELOC_BFIN_GOT", - "BFD_RELOC_BFIN_PLTPC", - "BFD_ARELOC_BFIN_PUSH", - "BFD_ARELOC_BFIN_CONST", - "BFD_ARELOC_BFIN_ADD", - "BFD_ARELOC_BFIN_SUB", - "BFD_ARELOC_BFIN_MULT", - "BFD_ARELOC_BFIN_DIV", - "BFD_ARELOC_BFIN_MOD", - "BFD_ARELOC_BFIN_LSHIFT", - "BFD_ARELOC_BFIN_RSHIFT", - "BFD_ARELOC_BFIN_AND", - "BFD_ARELOC_BFIN_OR", - "BFD_ARELOC_BFIN_XOR", - "BFD_ARELOC_BFIN_LAND", - "BFD_ARELOC_BFIN_LOR", - "BFD_ARELOC_BFIN_LEN", - "BFD_ARELOC_BFIN_NEG", - "BFD_ARELOC_BFIN_COMP", - "BFD_ARELOC_BFIN_PAGE", - "BFD_ARELOC_BFIN_HWPAGE", - "BFD_ARELOC_BFIN_ADDR", - "BFD_RELOC_D10V_10_PCREL_R", - "BFD_RELOC_D10V_10_PCREL_L", - "BFD_RELOC_D10V_18", - "BFD_RELOC_D10V_18_PCREL", - "BFD_RELOC_D30V_6", - "BFD_RELOC_D30V_9_PCREL", - "BFD_RELOC_D30V_9_PCREL_R", - "BFD_RELOC_D30V_15", - "BFD_RELOC_D30V_15_PCREL", - "BFD_RELOC_D30V_15_PCREL_R", - "BFD_RELOC_D30V_21", - "BFD_RELOC_D30V_21_PCREL", - "BFD_RELOC_D30V_21_PCREL_R", - "BFD_RELOC_D30V_32", - "BFD_RELOC_D30V_32_PCREL", - "BFD_RELOC_DLX_HI16_S", - "BFD_RELOC_DLX_LO16", - "BFD_RELOC_DLX_JMP26", - "BFD_RELOC_M32C_HI8", - "BFD_RELOC_M32C_RL_JUMP", - "BFD_RELOC_M32C_RL_1ADDR", - "BFD_RELOC_M32C_RL_2ADDR", - "BFD_RELOC_M32R_24", - "BFD_RELOC_M32R_10_PCREL", - "BFD_RELOC_M32R_18_PCREL", - "BFD_RELOC_M32R_26_PCREL", - "BFD_RELOC_M32R_HI16_ULO", - "BFD_RELOC_M32R_HI16_SLO", - "BFD_RELOC_M32R_LO16", - "BFD_RELOC_M32R_SDA16", - "BFD_RELOC_M32R_GOT24", - "BFD_RELOC_M32R_26_PLTREL", - "BFD_RELOC_M32R_COPY", - "BFD_RELOC_M32R_GLOB_DAT", - "BFD_RELOC_M32R_JMP_SLOT", - "BFD_RELOC_M32R_RELATIVE", - "BFD_RELOC_M32R_GOTOFF", - "BFD_RELOC_M32R_GOTOFF_HI_ULO", - "BFD_RELOC_M32R_GOTOFF_HI_SLO", - "BFD_RELOC_M32R_GOTOFF_LO", - "BFD_RELOC_M32R_GOTPC24", - "BFD_RELOC_M32R_GOT16_HI_ULO", - "BFD_RELOC_M32R_GOT16_HI_SLO", - "BFD_RELOC_M32R_GOT16_LO", - "BFD_RELOC_M32R_GOTPC_HI_ULO", - "BFD_RELOC_M32R_GOTPC_HI_SLO", - "BFD_RELOC_M32R_GOTPC_LO", - "BFD_RELOC_V850_9_PCREL", - "BFD_RELOC_V850_22_PCREL", - "BFD_RELOC_V850_SDA_16_16_OFFSET", - "BFD_RELOC_V850_SDA_15_16_OFFSET", - "BFD_RELOC_V850_ZDA_16_16_OFFSET", - "BFD_RELOC_V850_ZDA_15_16_OFFSET", - "BFD_RELOC_V850_TDA_6_8_OFFSET", - "BFD_RELOC_V850_TDA_7_8_OFFSET", - "BFD_RELOC_V850_TDA_7_7_OFFSET", - "BFD_RELOC_V850_TDA_16_16_OFFSET", - "BFD_RELOC_V850_TDA_4_5_OFFSET", - "BFD_RELOC_V850_TDA_4_4_OFFSET", - "BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET", - "BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET", - "BFD_RELOC_V850_CALLT_6_7_OFFSET", - "BFD_RELOC_V850_CALLT_16_16_OFFSET", - "BFD_RELOC_V850_LONGCALL", - "BFD_RELOC_V850_LONGJUMP", - "BFD_RELOC_V850_ALIGN", - "BFD_RELOC_V850_LO16_SPLIT_OFFSET", - "BFD_RELOC_V850_16_PCREL", - "BFD_RELOC_V850_17_PCREL", - "BFD_RELOC_V850_23", - "BFD_RELOC_V850_32_PCREL", - "BFD_RELOC_V850_32_ABS", - "BFD_RELOC_V850_16_SPLIT_OFFSET", - "BFD_RELOC_V850_16_S1", - "BFD_RELOC_V850_LO16_S1", - "BFD_RELOC_V850_CALLT_15_16_OFFSET", - "BFD_RELOC_V850_32_GOTPCREL", - "BFD_RELOC_V850_16_GOT", - "BFD_RELOC_V850_32_GOT", - "BFD_RELOC_V850_22_PLT_PCREL", - "BFD_RELOC_V850_32_PLT_PCREL", - "BFD_RELOC_V850_COPY", - "BFD_RELOC_V850_GLOB_DAT", - "BFD_RELOC_V850_JMP_SLOT", - "BFD_RELOC_V850_RELATIVE", - "BFD_RELOC_V850_16_GOTOFF", - "BFD_RELOC_V850_32_GOTOFF", - "BFD_RELOC_V850_CODE", - "BFD_RELOC_V850_DATA", - "BFD_RELOC_MN10300_32_PCREL", - "BFD_RELOC_MN10300_16_PCREL", - "BFD_RELOC_TIC30_LDP", - "BFD_RELOC_TIC54X_PARTLS7", - "BFD_RELOC_TIC54X_PARTMS9", - "BFD_RELOC_TIC54X_23", - "BFD_RELOC_TIC54X_16_OF_23", - "BFD_RELOC_TIC54X_MS7_OF_23", - "BFD_RELOC_C6000_PCR_S21", - "BFD_RELOC_C6000_PCR_S12", - "BFD_RELOC_C6000_PCR_S10", - "BFD_RELOC_C6000_PCR_S7", - "BFD_RELOC_C6000_ABS_S16", - "BFD_RELOC_C6000_ABS_L16", - "BFD_RELOC_C6000_ABS_H16", - "BFD_RELOC_C6000_SBR_U15_B", - "BFD_RELOC_C6000_SBR_U15_H", - "BFD_RELOC_C6000_SBR_U15_W", - "BFD_RELOC_C6000_SBR_S16", - "BFD_RELOC_C6000_SBR_L16_B", - "BFD_RELOC_C6000_SBR_L16_H", - "BFD_RELOC_C6000_SBR_L16_W", - "BFD_RELOC_C6000_SBR_H16_B", - "BFD_RELOC_C6000_SBR_H16_H", - "BFD_RELOC_C6000_SBR_H16_W", - "BFD_RELOC_C6000_SBR_GOT_U15_W", - "BFD_RELOC_C6000_SBR_GOT_L16_W", - "BFD_RELOC_C6000_SBR_GOT_H16_W", - "BFD_RELOC_C6000_DSBT_INDEX", - "BFD_RELOC_C6000_PREL31", - "BFD_RELOC_C6000_COPY", - "BFD_RELOC_C6000_JUMP_SLOT", - "BFD_RELOC_C6000_EHTYPE", - "BFD_RELOC_C6000_PCR_H16", - "BFD_RELOC_C6000_PCR_L16", - "BFD_RELOC_C6000_ALIGN", - "BFD_RELOC_C6000_FPHEAD", - "BFD_RELOC_C6000_NOCMP", - "BFD_RELOC_FR30_48", - "BFD_RELOC_FR30_20", - "BFD_RELOC_FR30_6_IN_4", - "BFD_RELOC_FR30_8_IN_8", - "BFD_RELOC_FR30_9_IN_8", - "BFD_RELOC_FR30_10_IN_8", - "BFD_RELOC_FR30_9_PCREL", - "BFD_RELOC_FR30_12_PCREL", - "BFD_RELOC_MCORE_PCREL_IMM8BY4", - "BFD_RELOC_MCORE_PCREL_IMM11BY2", - "BFD_RELOC_MCORE_PCREL_IMM4BY2", - "BFD_RELOC_MCORE_PCREL_32", - "BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2", - "BFD_RELOC_MCORE_RVA", - "BFD_RELOC_MEP_8", - "BFD_RELOC_MEP_16", - "BFD_RELOC_MEP_32", - "BFD_RELOC_MEP_PCREL8A2", - "BFD_RELOC_MEP_PCREL12A2", - "BFD_RELOC_MEP_PCREL17A2", - "BFD_RELOC_MEP_PCREL24A2", - "BFD_RELOC_MEP_PCABS24A2", - "BFD_RELOC_MEP_LOW16", - "BFD_RELOC_MEP_HI16U", - "BFD_RELOC_MEP_HI16S", - "BFD_RELOC_MEP_GPREL", - "BFD_RELOC_MEP_TPREL", - "BFD_RELOC_MEP_TPREL7", - "BFD_RELOC_MEP_TPREL7A2", - "BFD_RELOC_MEP_TPREL7A4", - "BFD_RELOC_MEP_UIMM24", - "BFD_RELOC_MEP_ADDR24A4", - "BFD_RELOC_MEP_GNU_VTINHERIT", - "BFD_RELOC_MEP_GNU_VTENTRY", - - "BFD_RELOC_MMIX_GETA", - "BFD_RELOC_MMIX_GETA_1", - "BFD_RELOC_MMIX_GETA_2", - "BFD_RELOC_MMIX_GETA_3", - "BFD_RELOC_MMIX_CBRANCH", - "BFD_RELOC_MMIX_CBRANCH_J", - "BFD_RELOC_MMIX_CBRANCH_1", - "BFD_RELOC_MMIX_CBRANCH_2", - "BFD_RELOC_MMIX_CBRANCH_3", - "BFD_RELOC_MMIX_PUSHJ", - "BFD_RELOC_MMIX_PUSHJ_1", - "BFD_RELOC_MMIX_PUSHJ_2", - "BFD_RELOC_MMIX_PUSHJ_3", - "BFD_RELOC_MMIX_PUSHJ_STUBBABLE", - "BFD_RELOC_MMIX_JMP", - "BFD_RELOC_MMIX_JMP_1", - "BFD_RELOC_MMIX_JMP_2", - "BFD_RELOC_MMIX_JMP_3", - "BFD_RELOC_MMIX_ADDR19", - "BFD_RELOC_MMIX_ADDR27", - "BFD_RELOC_MMIX_REG_OR_BYTE", - "BFD_RELOC_MMIX_REG", - "BFD_RELOC_MMIX_BASE_PLUS_OFFSET", - "BFD_RELOC_MMIX_LOCAL", - "BFD_RELOC_AVR_7_PCREL", - "BFD_RELOC_AVR_13_PCREL", - "BFD_RELOC_AVR_16_PM", - "BFD_RELOC_AVR_LO8_LDI", - "BFD_RELOC_AVR_HI8_LDI", - "BFD_RELOC_AVR_HH8_LDI", - "BFD_RELOC_AVR_MS8_LDI", - "BFD_RELOC_AVR_LO8_LDI_NEG", - "BFD_RELOC_AVR_HI8_LDI_NEG", - "BFD_RELOC_AVR_HH8_LDI_NEG", - "BFD_RELOC_AVR_MS8_LDI_NEG", - "BFD_RELOC_AVR_LO8_LDI_PM", - "BFD_RELOC_AVR_LO8_LDI_GS", - "BFD_RELOC_AVR_HI8_LDI_PM", - "BFD_RELOC_AVR_HI8_LDI_GS", - "BFD_RELOC_AVR_HH8_LDI_PM", - "BFD_RELOC_AVR_LO8_LDI_PM_NEG", - "BFD_RELOC_AVR_HI8_LDI_PM_NEG", - "BFD_RELOC_AVR_HH8_LDI_PM_NEG", - "BFD_RELOC_AVR_CALL", - "BFD_RELOC_AVR_LDI", - "BFD_RELOC_AVR_6", - "BFD_RELOC_AVR_6_ADIW", - "BFD_RELOC_RX_NEG8", - "BFD_RELOC_RX_NEG16", - "BFD_RELOC_RX_NEG24", - "BFD_RELOC_RX_NEG32", - "BFD_RELOC_RX_16_OP", - "BFD_RELOC_RX_24_OP", - "BFD_RELOC_RX_32_OP", - "BFD_RELOC_RX_8U", - "BFD_RELOC_RX_16U", - "BFD_RELOC_RX_24U", - "BFD_RELOC_RX_DIR3U_PCREL", - "BFD_RELOC_RX_DIFF", - "BFD_RELOC_RX_GPRELB", - "BFD_RELOC_RX_GPRELW", - "BFD_RELOC_RX_GPRELL", - "BFD_RELOC_RX_SYM", - "BFD_RELOC_RX_OP_SUBTRACT", - "BFD_RELOC_RX_OP_NEG", - "BFD_RELOC_RX_ABS8", - "BFD_RELOC_RX_ABS16", - "BFD_RELOC_RX_ABS16_REV", - "BFD_RELOC_RX_ABS32", - "BFD_RELOC_RX_ABS32_REV", - "BFD_RELOC_RX_ABS16U", - "BFD_RELOC_RX_ABS16UW", - "BFD_RELOC_RX_ABS16UL", - "BFD_RELOC_RX_RELAX", - "BFD_RELOC_390_12", - "BFD_RELOC_390_GOT12", - "BFD_RELOC_390_PLT32", - "BFD_RELOC_390_COPY", - "BFD_RELOC_390_GLOB_DAT", - "BFD_RELOC_390_JMP_SLOT", - "BFD_RELOC_390_RELATIVE", - "BFD_RELOC_390_GOTPC", - "BFD_RELOC_390_GOT16", - "BFD_RELOC_390_PC16DBL", - "BFD_RELOC_390_PLT16DBL", - "BFD_RELOC_390_PC32DBL", - "BFD_RELOC_390_PLT32DBL", - "BFD_RELOC_390_GOTPCDBL", - "BFD_RELOC_390_GOT64", - "BFD_RELOC_390_PLT64", - "BFD_RELOC_390_GOTENT", - "BFD_RELOC_390_GOTOFF64", - "BFD_RELOC_390_GOTPLT12", - "BFD_RELOC_390_GOTPLT16", - "BFD_RELOC_390_GOTPLT32", - "BFD_RELOC_390_GOTPLT64", - "BFD_RELOC_390_GOTPLTENT", - "BFD_RELOC_390_PLTOFF16", - "BFD_RELOC_390_PLTOFF32", - "BFD_RELOC_390_PLTOFF64", - "BFD_RELOC_390_TLS_LOAD", - "BFD_RELOC_390_TLS_GDCALL", - "BFD_RELOC_390_TLS_LDCALL", - "BFD_RELOC_390_TLS_GD32", - "BFD_RELOC_390_TLS_GD64", - "BFD_RELOC_390_TLS_GOTIE12", - "BFD_RELOC_390_TLS_GOTIE32", - "BFD_RELOC_390_TLS_GOTIE64", - "BFD_RELOC_390_TLS_LDM32", - "BFD_RELOC_390_TLS_LDM64", - "BFD_RELOC_390_TLS_IE32", - "BFD_RELOC_390_TLS_IE64", - "BFD_RELOC_390_TLS_IEENT", - "BFD_RELOC_390_TLS_LE32", - "BFD_RELOC_390_TLS_LE64", - "BFD_RELOC_390_TLS_LDO32", - "BFD_RELOC_390_TLS_LDO64", - "BFD_RELOC_390_TLS_DTPMOD", - "BFD_RELOC_390_TLS_DTPOFF", - "BFD_RELOC_390_TLS_TPOFF", - "BFD_RELOC_390_20", - "BFD_RELOC_390_GOT20", - "BFD_RELOC_390_GOTPLT20", - "BFD_RELOC_390_TLS_GOTIE20", - "BFD_RELOC_SCORE_GPREL15", - "BFD_RELOC_SCORE_DUMMY2", - "BFD_RELOC_SCORE_JMP", - "BFD_RELOC_SCORE_BRANCH", - "BFD_RELOC_SCORE_IMM30", - "BFD_RELOC_SCORE_IMM32", - "BFD_RELOC_SCORE16_JMP", - "BFD_RELOC_SCORE16_BRANCH", - "BFD_RELOC_SCORE_BCMP", - "BFD_RELOC_SCORE_GOT15", - "BFD_RELOC_SCORE_GOT_LO16", - "BFD_RELOC_SCORE_CALL15", - "BFD_RELOC_SCORE_DUMMY_HI16", - "BFD_RELOC_IP2K_FR9", - "BFD_RELOC_IP2K_BANK", - "BFD_RELOC_IP2K_ADDR16CJP", - "BFD_RELOC_IP2K_PAGE3", - "BFD_RELOC_IP2K_LO8DATA", - "BFD_RELOC_IP2K_HI8DATA", - "BFD_RELOC_IP2K_EX8DATA", - "BFD_RELOC_IP2K_LO8INSN", - "BFD_RELOC_IP2K_HI8INSN", - "BFD_RELOC_IP2K_PC_SKIP", - "BFD_RELOC_IP2K_TEXT", - "BFD_RELOC_IP2K_FR_OFFSET", - "BFD_RELOC_VPE4KMATH_DATA", - "BFD_RELOC_VPE4KMATH_INSN", - "BFD_RELOC_VTABLE_INHERIT", - "BFD_RELOC_VTABLE_ENTRY", - "BFD_RELOC_IA64_IMM14", - "BFD_RELOC_IA64_IMM22", - "BFD_RELOC_IA64_IMM64", - "BFD_RELOC_IA64_DIR32MSB", - "BFD_RELOC_IA64_DIR32LSB", - "BFD_RELOC_IA64_DIR64MSB", - "BFD_RELOC_IA64_DIR64LSB", - "BFD_RELOC_IA64_GPREL22", - "BFD_RELOC_IA64_GPREL64I", - "BFD_RELOC_IA64_GPREL32MSB", - "BFD_RELOC_IA64_GPREL32LSB", - "BFD_RELOC_IA64_GPREL64MSB", - "BFD_RELOC_IA64_GPREL64LSB", - "BFD_RELOC_IA64_LTOFF22", - "BFD_RELOC_IA64_LTOFF64I", - "BFD_RELOC_IA64_PLTOFF22", - "BFD_RELOC_IA64_PLTOFF64I", - "BFD_RELOC_IA64_PLTOFF64MSB", - "BFD_RELOC_IA64_PLTOFF64LSB", - "BFD_RELOC_IA64_FPTR64I", - "BFD_RELOC_IA64_FPTR32MSB", - "BFD_RELOC_IA64_FPTR32LSB", - "BFD_RELOC_IA64_FPTR64MSB", - "BFD_RELOC_IA64_FPTR64LSB", - "BFD_RELOC_IA64_PCREL21B", - "BFD_RELOC_IA64_PCREL21BI", - "BFD_RELOC_IA64_PCREL21M", - "BFD_RELOC_IA64_PCREL21F", - "BFD_RELOC_IA64_PCREL22", - "BFD_RELOC_IA64_PCREL60B", - "BFD_RELOC_IA64_PCREL64I", - "BFD_RELOC_IA64_PCREL32MSB", - "BFD_RELOC_IA64_PCREL32LSB", - "BFD_RELOC_IA64_PCREL64MSB", - "BFD_RELOC_IA64_PCREL64LSB", - "BFD_RELOC_IA64_LTOFF_FPTR22", - "BFD_RELOC_IA64_LTOFF_FPTR64I", - "BFD_RELOC_IA64_LTOFF_FPTR32MSB", - "BFD_RELOC_IA64_LTOFF_FPTR32LSB", - "BFD_RELOC_IA64_LTOFF_FPTR64MSB", - "BFD_RELOC_IA64_LTOFF_FPTR64LSB", - "BFD_RELOC_IA64_SEGREL32MSB", - "BFD_RELOC_IA64_SEGREL32LSB", - "BFD_RELOC_IA64_SEGREL64MSB", - "BFD_RELOC_IA64_SEGREL64LSB", - "BFD_RELOC_IA64_SECREL32MSB", - "BFD_RELOC_IA64_SECREL32LSB", - "BFD_RELOC_IA64_SECREL64MSB", - "BFD_RELOC_IA64_SECREL64LSB", - "BFD_RELOC_IA64_REL32MSB", - "BFD_RELOC_IA64_REL32LSB", - "BFD_RELOC_IA64_REL64MSB", - "BFD_RELOC_IA64_REL64LSB", - "BFD_RELOC_IA64_LTV32MSB", - "BFD_RELOC_IA64_LTV32LSB", - "BFD_RELOC_IA64_LTV64MSB", - "BFD_RELOC_IA64_LTV64LSB", - "BFD_RELOC_IA64_IPLTMSB", - "BFD_RELOC_IA64_IPLTLSB", - "BFD_RELOC_IA64_COPY", - "BFD_RELOC_IA64_LTOFF22X", - "BFD_RELOC_IA64_LDXMOV", - "BFD_RELOC_IA64_TPREL14", - "BFD_RELOC_IA64_TPREL22", - "BFD_RELOC_IA64_TPREL64I", - "BFD_RELOC_IA64_TPREL64MSB", - "BFD_RELOC_IA64_TPREL64LSB", - "BFD_RELOC_IA64_LTOFF_TPREL22", - "BFD_RELOC_IA64_DTPMOD64MSB", - "BFD_RELOC_IA64_DTPMOD64LSB", - "BFD_RELOC_IA64_LTOFF_DTPMOD22", - "BFD_RELOC_IA64_DTPREL14", - "BFD_RELOC_IA64_DTPREL22", - "BFD_RELOC_IA64_DTPREL64I", - "BFD_RELOC_IA64_DTPREL32MSB", - "BFD_RELOC_IA64_DTPREL32LSB", - "BFD_RELOC_IA64_DTPREL64MSB", - "BFD_RELOC_IA64_DTPREL64LSB", - "BFD_RELOC_IA64_LTOFF_DTPREL22", - "BFD_RELOC_M68HC11_HI8", - "BFD_RELOC_M68HC11_LO8", - "BFD_RELOC_M68HC11_3B", - "BFD_RELOC_M68HC11_RL_JUMP", - "BFD_RELOC_M68HC11_RL_GROUP", - "BFD_RELOC_M68HC11_LO16", - "BFD_RELOC_M68HC11_PAGE", - "BFD_RELOC_M68HC11_24", - "BFD_RELOC_M68HC12_5B", - "BFD_RELOC_16C_NUM08", - "BFD_RELOC_16C_NUM08_C", - "BFD_RELOC_16C_NUM16", - "BFD_RELOC_16C_NUM16_C", - "BFD_RELOC_16C_NUM32", - "BFD_RELOC_16C_NUM32_C", - "BFD_RELOC_16C_DISP04", - "BFD_RELOC_16C_DISP04_C", - "BFD_RELOC_16C_DISP08", - "BFD_RELOC_16C_DISP08_C", - "BFD_RELOC_16C_DISP16", - "BFD_RELOC_16C_DISP16_C", - "BFD_RELOC_16C_DISP24", - "BFD_RELOC_16C_DISP24_C", - "BFD_RELOC_16C_DISP24a", - "BFD_RELOC_16C_DISP24a_C", - "BFD_RELOC_16C_REG04", - "BFD_RELOC_16C_REG04_C", - "BFD_RELOC_16C_REG04a", - "BFD_RELOC_16C_REG04a_C", - "BFD_RELOC_16C_REG14", - "BFD_RELOC_16C_REG14_C", - "BFD_RELOC_16C_REG16", - "BFD_RELOC_16C_REG16_C", - "BFD_RELOC_16C_REG20", - "BFD_RELOC_16C_REG20_C", - "BFD_RELOC_16C_ABS20", - "BFD_RELOC_16C_ABS20_C", - "BFD_RELOC_16C_ABS24", - "BFD_RELOC_16C_ABS24_C", - "BFD_RELOC_16C_IMM04", - "BFD_RELOC_16C_IMM04_C", - "BFD_RELOC_16C_IMM16", - "BFD_RELOC_16C_IMM16_C", - "BFD_RELOC_16C_IMM20", - "BFD_RELOC_16C_IMM20_C", - "BFD_RELOC_16C_IMM24", - "BFD_RELOC_16C_IMM24_C", - "BFD_RELOC_16C_IMM32", - "BFD_RELOC_16C_IMM32_C", - "BFD_RELOC_CR16_NUM8", - "BFD_RELOC_CR16_NUM16", - "BFD_RELOC_CR16_NUM32", - "BFD_RELOC_CR16_NUM32a", - "BFD_RELOC_CR16_REGREL0", - "BFD_RELOC_CR16_REGREL4", - "BFD_RELOC_CR16_REGREL4a", - "BFD_RELOC_CR16_REGREL14", - "BFD_RELOC_CR16_REGREL14a", - "BFD_RELOC_CR16_REGREL16", - "BFD_RELOC_CR16_REGREL20", - "BFD_RELOC_CR16_REGREL20a", - "BFD_RELOC_CR16_ABS20", - "BFD_RELOC_CR16_ABS24", - "BFD_RELOC_CR16_IMM4", - "BFD_RELOC_CR16_IMM8", - "BFD_RELOC_CR16_IMM16", - "BFD_RELOC_CR16_IMM20", - "BFD_RELOC_CR16_IMM24", - "BFD_RELOC_CR16_IMM32", - "BFD_RELOC_CR16_IMM32a", - "BFD_RELOC_CR16_DISP4", - "BFD_RELOC_CR16_DISP8", - "BFD_RELOC_CR16_DISP16", - "BFD_RELOC_CR16_DISP20", - "BFD_RELOC_CR16_DISP24", - "BFD_RELOC_CR16_DISP24a", - "BFD_RELOC_CR16_SWITCH8", - "BFD_RELOC_CR16_SWITCH16", - "BFD_RELOC_CR16_SWITCH32", - "BFD_RELOC_CR16_GOT_REGREL20", - "BFD_RELOC_CR16_GOTC_REGREL20", - "BFD_RELOC_CR16_GLOB_DAT", - "BFD_RELOC_CRX_REL4", - "BFD_RELOC_CRX_REL8", - "BFD_RELOC_CRX_REL8_CMP", - "BFD_RELOC_CRX_REL16", - "BFD_RELOC_CRX_REL24", - "BFD_RELOC_CRX_REL32", - "BFD_RELOC_CRX_REGREL12", - "BFD_RELOC_CRX_REGREL22", - "BFD_RELOC_CRX_REGREL28", - "BFD_RELOC_CRX_REGREL32", - "BFD_RELOC_CRX_ABS16", - "BFD_RELOC_CRX_ABS32", - "BFD_RELOC_CRX_NUM8", - "BFD_RELOC_CRX_NUM16", - "BFD_RELOC_CRX_NUM32", - "BFD_RELOC_CRX_IMM16", - "BFD_RELOC_CRX_IMM32", - "BFD_RELOC_CRX_SWITCH8", - "BFD_RELOC_CRX_SWITCH16", - "BFD_RELOC_CRX_SWITCH32", - "BFD_RELOC_CRIS_BDISP8", - "BFD_RELOC_CRIS_UNSIGNED_5", - "BFD_RELOC_CRIS_SIGNED_6", - "BFD_RELOC_CRIS_UNSIGNED_6", - "BFD_RELOC_CRIS_SIGNED_8", - "BFD_RELOC_CRIS_UNSIGNED_8", - "BFD_RELOC_CRIS_SIGNED_16", - "BFD_RELOC_CRIS_UNSIGNED_16", - "BFD_RELOC_CRIS_LAPCQ_OFFSET", - "BFD_RELOC_CRIS_UNSIGNED_4", - "BFD_RELOC_CRIS_COPY", - "BFD_RELOC_CRIS_GLOB_DAT", - "BFD_RELOC_CRIS_JUMP_SLOT", - "BFD_RELOC_CRIS_RELATIVE", - "BFD_RELOC_CRIS_32_GOT", - "BFD_RELOC_CRIS_16_GOT", - "BFD_RELOC_CRIS_32_GOTPLT", - "BFD_RELOC_CRIS_16_GOTPLT", - "BFD_RELOC_CRIS_32_GOTREL", - "BFD_RELOC_CRIS_32_PLT_GOTREL", - "BFD_RELOC_CRIS_32_PLT_PCREL", - "BFD_RELOC_CRIS_32_GOT_GD", - "BFD_RELOC_CRIS_16_GOT_GD", - "BFD_RELOC_CRIS_32_GD", - "BFD_RELOC_CRIS_DTP", - "BFD_RELOC_CRIS_32_DTPREL", - "BFD_RELOC_CRIS_16_DTPREL", - "BFD_RELOC_CRIS_32_GOT_TPREL", - "BFD_RELOC_CRIS_16_GOT_TPREL", - "BFD_RELOC_CRIS_32_TPREL", - "BFD_RELOC_CRIS_16_TPREL", - "BFD_RELOC_CRIS_DTPMOD", - "BFD_RELOC_CRIS_32_IE", - "BFD_RELOC_860_COPY", - "BFD_RELOC_860_GLOB_DAT", - "BFD_RELOC_860_JUMP_SLOT", - "BFD_RELOC_860_RELATIVE", - "BFD_RELOC_860_PC26", - "BFD_RELOC_860_PLT26", - "BFD_RELOC_860_PC16", - "BFD_RELOC_860_LOW0", - "BFD_RELOC_860_SPLIT0", - "BFD_RELOC_860_LOW1", - "BFD_RELOC_860_SPLIT1", - "BFD_RELOC_860_LOW2", - "BFD_RELOC_860_SPLIT2", - "BFD_RELOC_860_LOW3", - "BFD_RELOC_860_LOGOT0", - "BFD_RELOC_860_SPGOT0", - "BFD_RELOC_860_LOGOT1", - "BFD_RELOC_860_SPGOT1", - "BFD_RELOC_860_LOGOTOFF0", - "BFD_RELOC_860_SPGOTOFF0", - "BFD_RELOC_860_LOGOTOFF1", - "BFD_RELOC_860_SPGOTOFF1", - "BFD_RELOC_860_LOGOTOFF2", - "BFD_RELOC_860_LOGOTOFF3", - "BFD_RELOC_860_LOPC", - "BFD_RELOC_860_HIGHADJ", - "BFD_RELOC_860_HAGOT", - "BFD_RELOC_860_HAGOTOFF", - "BFD_RELOC_860_HAPC", - "BFD_RELOC_860_HIGH", - "BFD_RELOC_860_HIGOT", - "BFD_RELOC_860_HIGOTOFF", - "BFD_RELOC_OPENRISC_ABS_26", - "BFD_RELOC_OPENRISC_REL_26", - "BFD_RELOC_H8_DIR16A8", - "BFD_RELOC_H8_DIR16R8", - "BFD_RELOC_H8_DIR24A8", - "BFD_RELOC_H8_DIR24R8", - "BFD_RELOC_H8_DIR32A16", - "BFD_RELOC_XSTORMY16_REL_12", - "BFD_RELOC_XSTORMY16_12", - "BFD_RELOC_XSTORMY16_24", - "BFD_RELOC_XSTORMY16_FPTR16", - "BFD_RELOC_RELC", - - "BFD_RELOC_XC16X_PAG", - "BFD_RELOC_XC16X_POF", - "BFD_RELOC_XC16X_SEG", - "BFD_RELOC_XC16X_SOF", - "BFD_RELOC_VAX_GLOB_DAT", - "BFD_RELOC_VAX_JMP_SLOT", - "BFD_RELOC_VAX_RELATIVE", - "BFD_RELOC_MT_PC16", - "BFD_RELOC_MT_HI16", - "BFD_RELOC_MT_LO16", - "BFD_RELOC_MT_GNU_VTINHERIT", - "BFD_RELOC_MT_GNU_VTENTRY", - "BFD_RELOC_MT_PCINSN8", - "BFD_RELOC_MSP430_10_PCREL", - "BFD_RELOC_MSP430_16_PCREL", - "BFD_RELOC_MSP430_16", - "BFD_RELOC_MSP430_16_PCREL_BYTE", - "BFD_RELOC_MSP430_16_BYTE", - "BFD_RELOC_MSP430_2X_PCREL", - "BFD_RELOC_MSP430_RL_PCREL", - "BFD_RELOC_IQ2000_OFFSET_16", - "BFD_RELOC_IQ2000_OFFSET_21", - "BFD_RELOC_IQ2000_UHI16", - "BFD_RELOC_XTENSA_RTLD", - "BFD_RELOC_XTENSA_GLOB_DAT", - "BFD_RELOC_XTENSA_JMP_SLOT", - "BFD_RELOC_XTENSA_RELATIVE", - "BFD_RELOC_XTENSA_PLT", - "BFD_RELOC_XTENSA_DIFF8", - "BFD_RELOC_XTENSA_DIFF16", - "BFD_RELOC_XTENSA_DIFF32", - "BFD_RELOC_XTENSA_SLOT0_OP", - "BFD_RELOC_XTENSA_SLOT1_OP", - "BFD_RELOC_XTENSA_SLOT2_OP", - "BFD_RELOC_XTENSA_SLOT3_OP", - "BFD_RELOC_XTENSA_SLOT4_OP", - "BFD_RELOC_XTENSA_SLOT5_OP", - "BFD_RELOC_XTENSA_SLOT6_OP", - "BFD_RELOC_XTENSA_SLOT7_OP", - "BFD_RELOC_XTENSA_SLOT8_OP", - "BFD_RELOC_XTENSA_SLOT9_OP", - "BFD_RELOC_XTENSA_SLOT10_OP", - "BFD_RELOC_XTENSA_SLOT11_OP", - "BFD_RELOC_XTENSA_SLOT12_OP", - "BFD_RELOC_XTENSA_SLOT13_OP", - "BFD_RELOC_XTENSA_SLOT14_OP", - "BFD_RELOC_XTENSA_SLOT0_ALT", - "BFD_RELOC_XTENSA_SLOT1_ALT", - "BFD_RELOC_XTENSA_SLOT2_ALT", - "BFD_RELOC_XTENSA_SLOT3_ALT", - "BFD_RELOC_XTENSA_SLOT4_ALT", - "BFD_RELOC_XTENSA_SLOT5_ALT", - "BFD_RELOC_XTENSA_SLOT6_ALT", - "BFD_RELOC_XTENSA_SLOT7_ALT", - "BFD_RELOC_XTENSA_SLOT8_ALT", - "BFD_RELOC_XTENSA_SLOT9_ALT", - "BFD_RELOC_XTENSA_SLOT10_ALT", - "BFD_RELOC_XTENSA_SLOT11_ALT", - "BFD_RELOC_XTENSA_SLOT12_ALT", - "BFD_RELOC_XTENSA_SLOT13_ALT", - "BFD_RELOC_XTENSA_SLOT14_ALT", - "BFD_RELOC_XTENSA_OP0", - "BFD_RELOC_XTENSA_OP1", - "BFD_RELOC_XTENSA_OP2", - "BFD_RELOC_XTENSA_ASM_EXPAND", - "BFD_RELOC_XTENSA_ASM_SIMPLIFY", - "BFD_RELOC_XTENSA_TLSDESC_FN", - "BFD_RELOC_XTENSA_TLSDESC_ARG", - "BFD_RELOC_XTENSA_TLS_DTPOFF", - "BFD_RELOC_XTENSA_TLS_TPOFF", - "BFD_RELOC_XTENSA_TLS_FUNC", - "BFD_RELOC_XTENSA_TLS_ARG", - "BFD_RELOC_XTENSA_TLS_CALL", - "BFD_RELOC_Z80_DISP8", - "BFD_RELOC_Z8K_DISP7", - "BFD_RELOC_Z8K_CALLR", - "BFD_RELOC_Z8K_IMM4L", - "BFD_RELOC_LM32_CALL", - "BFD_RELOC_LM32_BRANCH", - "BFD_RELOC_LM32_16_GOT", - "BFD_RELOC_LM32_GOTOFF_HI16", - "BFD_RELOC_LM32_GOTOFF_LO16", - "BFD_RELOC_LM32_COPY", - "BFD_RELOC_LM32_GLOB_DAT", - "BFD_RELOC_LM32_JMP_SLOT", - "BFD_RELOC_LM32_RELATIVE", - "BFD_RELOC_MACH_O_SECTDIFF", - "BFD_RELOC_MACH_O_PAIR", - "BFD_RELOC_MACH_O_X86_64_BRANCH32", - "BFD_RELOC_MACH_O_X86_64_BRANCH8", - "BFD_RELOC_MACH_O_X86_64_GOT", - "BFD_RELOC_MACH_O_X86_64_GOT_LOAD", - "BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32", - "BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64", - "BFD_RELOC_MACH_O_X86_64_PCREL32_1", - "BFD_RELOC_MACH_O_X86_64_PCREL32_2", - "BFD_RELOC_MACH_O_X86_64_PCREL32_4", - "BFD_RELOC_MICROBLAZE_32_LO", - "BFD_RELOC_MICROBLAZE_32_LO_PCREL", - "BFD_RELOC_MICROBLAZE_32_ROSDA", - "BFD_RELOC_MICROBLAZE_32_RWSDA", - "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM", - "BFD_RELOC_MICROBLAZE_64_NONE", - "BFD_RELOC_MICROBLAZE_64_GOTPC", - "BFD_RELOC_MICROBLAZE_64_GOT", - "BFD_RELOC_MICROBLAZE_64_PLT", - "BFD_RELOC_MICROBLAZE_64_GOTOFF", - "BFD_RELOC_MICROBLAZE_32_GOTOFF", - "BFD_RELOC_MICROBLAZE_COPY", - "BFD_RELOC_TILEPRO_COPY", - "BFD_RELOC_TILEPRO_GLOB_DAT", - "BFD_RELOC_TILEPRO_JMP_SLOT", - "BFD_RELOC_TILEPRO_RELATIVE", - "BFD_RELOC_TILEPRO_BROFF_X1", - "BFD_RELOC_TILEPRO_JOFFLONG_X1", - "BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT", - "BFD_RELOC_TILEPRO_IMM8_X0", - "BFD_RELOC_TILEPRO_IMM8_Y0", - "BFD_RELOC_TILEPRO_IMM8_X1", - "BFD_RELOC_TILEPRO_IMM8_Y1", - "BFD_RELOC_TILEPRO_DEST_IMM8_X1", - "BFD_RELOC_TILEPRO_MT_IMM15_X1", - "BFD_RELOC_TILEPRO_MF_IMM15_X1", - "BFD_RELOC_TILEPRO_IMM16_X0", - "BFD_RELOC_TILEPRO_IMM16_X1", - "BFD_RELOC_TILEPRO_IMM16_X0_LO", - "BFD_RELOC_TILEPRO_IMM16_X1_LO", - "BFD_RELOC_TILEPRO_IMM16_X0_HI", - "BFD_RELOC_TILEPRO_IMM16_X1_HI", - "BFD_RELOC_TILEPRO_IMM16_X0_HA", - "BFD_RELOC_TILEPRO_IMM16_X1_HA", - "BFD_RELOC_TILEPRO_IMM16_X0_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X1_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL", - "BFD_RELOC_TILEPRO_IMM16_X0_GOT", - "BFD_RELOC_TILEPRO_IMM16_X1_GOT", - "BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO", - "BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO", - "BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI", - "BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI", - "BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA", - "BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA", - "BFD_RELOC_TILEPRO_MMSTART_X0", - "BFD_RELOC_TILEPRO_MMEND_X0", - "BFD_RELOC_TILEPRO_MMSTART_X1", - "BFD_RELOC_TILEPRO_MMEND_X1", - "BFD_RELOC_TILEPRO_SHAMT_X0", - "BFD_RELOC_TILEPRO_SHAMT_X1", - "BFD_RELOC_TILEPRO_SHAMT_Y0", - "BFD_RELOC_TILEPRO_SHAMT_Y1", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI", - "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA", - "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA", - "BFD_RELOC_TILEPRO_TLS_DTPMOD32", - "BFD_RELOC_TILEPRO_TLS_DTPOFF32", - "BFD_RELOC_TILEPRO_TLS_TPOFF32", - "BFD_RELOC_TILEGX_HW0", - "BFD_RELOC_TILEGX_HW1", - "BFD_RELOC_TILEGX_HW2", - "BFD_RELOC_TILEGX_HW3", - "BFD_RELOC_TILEGX_HW0_LAST", - "BFD_RELOC_TILEGX_HW1_LAST", - "BFD_RELOC_TILEGX_HW2_LAST", - "BFD_RELOC_TILEGX_COPY", - "BFD_RELOC_TILEGX_GLOB_DAT", - "BFD_RELOC_TILEGX_JMP_SLOT", - "BFD_RELOC_TILEGX_RELATIVE", - "BFD_RELOC_TILEGX_BROFF_X1", - "BFD_RELOC_TILEGX_JUMPOFF_X1", - "BFD_RELOC_TILEGX_JUMPOFF_X1_PLT", - "BFD_RELOC_TILEGX_IMM8_X0", - "BFD_RELOC_TILEGX_IMM8_Y0", - "BFD_RELOC_TILEGX_IMM8_X1", - "BFD_RELOC_TILEGX_IMM8_Y1", - "BFD_RELOC_TILEGX_DEST_IMM8_X1", - "BFD_RELOC_TILEGX_MT_IMM14_X1", - "BFD_RELOC_TILEGX_MF_IMM14_X1", - "BFD_RELOC_TILEGX_MMSTART_X0", - "BFD_RELOC_TILEGX_MMEND_X0", - "BFD_RELOC_TILEGX_SHAMT_X0", - "BFD_RELOC_TILEGX_SHAMT_X1", - "BFD_RELOC_TILEGX_SHAMT_Y0", - "BFD_RELOC_TILEGX_SHAMT_Y1", - "BFD_RELOC_TILEGX_IMM16_X0_HW0", - "BFD_RELOC_TILEGX_IMM16_X1_HW0", - "BFD_RELOC_TILEGX_IMM16_X0_HW1", - "BFD_RELOC_TILEGX_IMM16_X1_HW1", - "BFD_RELOC_TILEGX_IMM16_X0_HW2", - "BFD_RELOC_TILEGX_IMM16_X1_HW2", - "BFD_RELOC_TILEGX_IMM16_X0_HW3", - "BFD_RELOC_TILEGX_IMM16_X1_HW3", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE", - "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE", - "BFD_RELOC_TILEGX_TLS_DTPMOD64", - "BFD_RELOC_TILEGX_TLS_DTPOFF64", - "BFD_RELOC_TILEGX_TLS_TPOFF64", - "BFD_RELOC_TILEGX_TLS_DTPMOD32", - "BFD_RELOC_TILEGX_TLS_DTPOFF32", - "BFD_RELOC_TILEGX_TLS_TPOFF32", - "@@overflow: BFD_RELOC_UNUSED@@", -}; -#endif - -reloc_howto_type *bfd_default_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); - -bfd_boolean bfd_generic_relax_section - (bfd *abfd, - asection *section, - struct bfd_link_info *, - bfd_boolean *); - -bfd_boolean bfd_generic_gc_sections - (bfd *, struct bfd_link_info *); - -void bfd_generic_lookup_section_flags - (struct bfd_link_info *, struct flag_info *); - -bfd_boolean bfd_generic_merge_sections - (bfd *, struct bfd_link_info *); - -bfd_byte *bfd_generic_get_relocated_section_contents - (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - bfd_boolean relocatable, - asymbol **symbols); - -/* Extracted from archures.c. */ -extern const bfd_arch_info_type bfd_default_arch_struct; -bfd_boolean bfd_default_set_arch_mach - (bfd *abfd, enum bfd_architecture arch, unsigned long mach); - -const bfd_arch_info_type *bfd_default_compatible - (const bfd_arch_info_type *a, const bfd_arch_info_type *b); - -bfd_boolean bfd_default_scan - (const struct bfd_arch_info *info, const char *string); - -/* Extracted from elf.c. */ diff --git a/contrib/binutils-2.22/bfd/libcoff.h b/contrib/binutils-2.22/bfd/libcoff.h deleted file mode 100644 index bd58c82e47..0000000000 --- a/contrib/binutils-2.22/bfd/libcoff.h +++ /dev/null @@ -1,958 +0,0 @@ -/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically - generated from "libcoff-in.h" and "coffcode.h". - Run "make headers" in your build bfd/ to regenerate. */ - -/* BFD COFF object file private structure. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "bfdlink.h" - -/* Object file tdata; access macros. */ - -#define coff_data(bfd) ((bfd)->tdata.coff_obj_data) -#define obj_pe(bfd) (coff_data (bfd)->pe) -#define obj_symbols(bfd) (coff_data (bfd)->symbols) -#define obj_sym_filepos(bfd) (coff_data (bfd)->sym_filepos) -#define obj_relocbase(bfd) (coff_data (bfd)->relocbase) -#define obj_raw_syments(bfd) (coff_data (bfd)->raw_syments) -#define obj_raw_syment_count(bfd) (coff_data (bfd)->raw_syment_count) -#define obj_convert(bfd) (coff_data (bfd)->conversion_table) -#define obj_conv_table_size(bfd) (coff_data (bfd)->conv_table_size) -#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) -#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms) -#define obj_coff_strings(bfd) (coff_data (bfd)->strings) -#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings) -#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes) -#define obj_coff_strings_written(bfd) (coff_data (bfd)->strings_written) -#define obj_coff_local_toc_table(bfd) (coff_data (bfd)->local_toc_sym_map) - -/* `Tdata' information kept for COFF files. */ - -typedef struct coff_tdata -{ - struct coff_symbol_struct *symbols; /* Symtab for input bfd. */ - unsigned int *conversion_table; - int conv_table_size; - file_ptr sym_filepos; - - struct coff_ptr_struct *raw_syments; - unsigned long raw_syment_count; - - /* These are only valid once writing has begun. */ - long int relocbase; - - /* These members communicate important constants about the symbol table - to GDB's symbol-reading code. These `constants' unfortunately vary - from coff implementation to implementation... */ - unsigned local_n_btmask; - unsigned local_n_btshft; - unsigned local_n_tmask; - unsigned local_n_tshift; - unsigned local_symesz; - unsigned local_auxesz; - unsigned local_linesz; - - /* The unswapped external symbols. May be NULL. Read by - _bfd_coff_get_external_symbols. */ - void * external_syms; - /* If this is TRUE, the external_syms may not be freed. */ - bfd_boolean keep_syms; - - /* The string table. May be NULL. Read by - _bfd_coff_read_string_table. */ - char *strings; - /* If this is TRUE, the strings may not be freed. */ - bfd_boolean keep_strings; - /* If this is TRUE, the strings have been written out already. */ - bfd_boolean strings_written; - - /* Is this a PE format coff file? */ - int pe; - /* Used by the COFF backend linker. */ - struct coff_link_hash_entry **sym_hashes; - - /* Used by the pe linker for PowerPC. */ - int *local_toc_sym_map; - - struct bfd_link_info *link_info; - - /* Used by coff_find_nearest_line. */ - void * line_info; - - /* A place to stash dwarf2 info for this bfd. */ - void * dwarf2_find_line_info; - - /* The timestamp from the COFF file header. */ - long timestamp; - - /* Copy of some of the f_flags bits in the COFF filehdr structure, - used by ARM code. */ - flagword flags; - - /* coff-stgo32 EXE stub header after BFD tdata has been allocated. Its data - is kept in internal_filehdr.go32stub beforehand. */ - char *go32stub; -} coff_data_type; - -/* Tdata for pe image files. */ -typedef struct pe_tdata -{ - coff_data_type coff; - struct internal_extra_pe_aouthdr pe_opthdr; - int dll; - int has_reloc_section; - int dont_strip_reloc; - bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *); - flagword real_flags; -} pe_data_type; - -#define pe_data(bfd) ((bfd)->tdata.pe_obj_data) - -/* Tdata for XCOFF files. */ - -struct xcoff_tdata -{ - /* Basic COFF information. */ - coff_data_type coff; - - /* TRUE if this is an XCOFF64 file. */ - bfd_boolean xcoff64; - - /* TRUE if a large a.out header should be generated. */ - bfd_boolean full_aouthdr; - - /* TOC value. */ - bfd_vma toc; - - /* Index of section holding TOC. */ - int sntoc; - - /* Index of section holding entry point. */ - int snentry; - - /* .text alignment from optional header. */ - int text_align_power; - - /* .data alignment from optional header. */ - int data_align_power; - - /* modtype from optional header. */ - short modtype; - - /* cputype from optional header. */ - short cputype; - - /* maxdata from optional header. */ - bfd_vma maxdata; - - /* maxstack from optional header. */ - bfd_vma maxstack; - - /* Used by the XCOFF backend linker. */ - asection **csects; - long *debug_indices; - unsigned int *lineno_counts; - unsigned int import_file_id; -}; - -#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data) - -/* We take the address of the first element of an asymbol to ensure that the - macro is only ever applied to an asymbol. */ -#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd))) - -/* The used_by_bfd field of a section may be set to a pointer to this - structure. */ - -struct coff_section_tdata -{ - /* The relocs, swapped into COFF internal form. This may be NULL. */ - struct internal_reloc *relocs; - /* If this is TRUE, the relocs entry may not be freed. */ - bfd_boolean keep_relocs; - /* The section contents. This may be NULL. */ - bfd_byte *contents; - /* If this is TRUE, the contents entry may not be freed. */ - bfd_boolean keep_contents; - /* Information cached by coff_find_nearest_line. */ - bfd_vma offset; - unsigned int i; - const char *function; - /* Optional information about a COMDAT entry; NULL if not COMDAT. */ - struct coff_comdat_info *comdat; - int line_base; - /* A pointer used for .stab linking optimizations. */ - void * stab_info; - /* Available for individual backends. */ - void * tdata; -}; - -/* An accessor macro for the coff_section_tdata structure. */ -#define coff_section_data(abfd, sec) \ - ((struct coff_section_tdata *) (sec)->used_by_bfd) - -/* Tdata for sections in XCOFF files. This is used by the linker. */ - -struct xcoff_section_tdata -{ - /* Used for XCOFF csects created by the linker; points to the real - XCOFF section which contains this csect. */ - asection *enclosing; - /* The lineno_count field for the enclosing section, because we are - going to clobber it there. */ - unsigned int lineno_count; - /* The first and last symbol indices for symbols used by this csect. */ - unsigned long first_symndx; - unsigned long last_symndx; -}; - -/* An accessor macro the xcoff_section_tdata structure. */ -#define xcoff_section_data(abfd, sec) \ - ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata) - -/* Tdata for sections in PE files. */ - -struct pei_section_tdata -{ - /* The virtual size of the section. */ - bfd_size_type virt_size; - /* The PE section flags. */ - long pe_flags; -}; - -/* An accessor macro for the pei_section_tdata structure. */ -#define pei_section_data(abfd, sec) \ - ((struct pei_section_tdata *) coff_section_data ((abfd), (sec))->tdata) - -/* COFF linker hash table entries. */ - -struct coff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* Symbol type. */ - unsigned short type; - - /* Symbol class. */ - unsigned char symbol_class; - - /* Number of auxiliary entries. */ - char numaux; - - /* BFD to take auxiliary entries from. */ - bfd *auxbfd; - - /* Pointer to array of auxiliary entries, if any. */ - union internal_auxent *aux; - - /* Flag word; legal values follow. */ - unsigned short coff_link_hash_flags; - /* Symbol is a PE section symbol. */ -#define COFF_LINK_HASH_PE_SECTION_SYMBOL (01) -}; - -/* COFF linker hash table. */ - -struct coff_link_hash_table -{ - struct bfd_link_hash_table root; - /* A pointer to information used to link stabs in sections. */ - struct stab_info stab_info; -}; - -/* Look up an entry in a COFF linker hash table. */ - -#define coff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct coff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a COFF linker hash table. */ - -#define coff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \ - (info))) - -/* Get the COFF linker hash table from a link_info structure. */ - -#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash)) - -/* Functions in coffgen.c. */ -extern const bfd_target *coff_object_p - (bfd *); -extern struct bfd_section *coff_section_from_bfd_index - (bfd *, int); -extern long coff_get_symtab_upper_bound - (bfd *); -extern long coff_canonicalize_symtab - (bfd *, asymbol **); -extern int coff_count_linenumbers - (bfd *); -extern struct coff_symbol_struct *coff_symbol_from - (bfd *, asymbol *); -extern bfd_boolean coff_renumber_symbols - (bfd *, int *); -extern void coff_mangle_symbols - (bfd *); -extern bfd_boolean coff_write_symbols - (bfd *); -extern bfd_boolean coff_write_linenumbers - (bfd *); -extern alent *coff_get_lineno - (bfd *, asymbol *); -extern asymbol *coff_section_symbol - (bfd *, char *); -extern bfd_boolean _bfd_coff_get_external_symbols - (bfd *); -extern const char *_bfd_coff_read_string_table - (bfd *); -extern bfd_boolean _bfd_coff_free_symbols - (bfd *); -extern struct coff_ptr_struct *coff_get_normalized_symtab - (bfd *); -extern long coff_get_reloc_upper_bound - (bfd *, sec_ptr); -extern asymbol *coff_make_empty_symbol - (bfd *); -extern void coff_print_symbol - (bfd *, void * filep, asymbol *, bfd_print_symbol_type); -extern void coff_get_symbol_info - (bfd *, asymbol *, symbol_info *ret); -extern bfd_boolean _bfd_coff_is_local_label_name - (bfd *, const char *); -extern asymbol *coff_bfd_make_debug_symbol - (bfd *, void *, unsigned long); -extern bfd_boolean coff_find_nearest_line - (bfd *, asection *, asymbol **, bfd_vma, const char **, - const char **, unsigned int *); -extern bfd_boolean coff_find_inliner_info - (bfd *, const char **, const char **, unsigned int *); -extern int coff_sizeof_headers - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_coff_reloc16_relax_section - (bfd *, asection *, struct bfd_link_info *, bfd_boolean *); -extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - (bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, bfd_boolean, asymbol **); -extern bfd_vma bfd_coff_reloc16_get_value - (arelent *, struct bfd_link_info *, asection *); -extern void bfd_perform_slip - (bfd *, unsigned int, asection *, bfd_vma); - -/* Functions and types in cofflink.c. */ - -#define STRING_SIZE_SIZE 4 - -/* We use a hash table to merge identical enum, struct, and union - definitions in the linker. */ - -/* Information we keep for a single element (an enum value, a - structure or union field) in the debug merge hash table. */ - -struct coff_debug_merge_element -{ - /* Next element. */ - struct coff_debug_merge_element *next; - - /* Name. */ - const char *name; - - /* Type. */ - unsigned int type; - - /* Symbol index for complex type. */ - long tagndx; -}; - -/* A linked list of debug merge entries for a given name. */ - -struct coff_debug_merge_type -{ - /* Next type with the same name. */ - struct coff_debug_merge_type *next; - - /* Class of type. */ - int type_class; - - /* Symbol index where this type is defined. */ - long indx; - - /* List of elements. */ - struct coff_debug_merge_element *elements; -}; - -/* Information we store in the debug merge hash table. */ - -struct coff_debug_merge_hash_entry -{ - struct bfd_hash_entry root; - - /* A list of types with this name. */ - struct coff_debug_merge_type *types; -}; - -/* The debug merge hash table. */ - -struct coff_debug_merge_hash_table -{ - struct bfd_hash_table root; -}; - -/* Initialize a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_init(table) \ - (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc, \ - sizeof (struct coff_debug_merge_hash_entry))) - -/* Free a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_free(table) \ - (bfd_hash_table_free (&(table)->root)) - -/* Look up an entry in a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_lookup(table, string, create, copy) \ - ((struct coff_debug_merge_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Information we keep for each section in the output file when doing - a relocatable link. */ - -struct coff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct coff_link_hash_entry **rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct coff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Used to indicate failure in traversal routine. */ - bfd_boolean failed; - /* If doing "task linking" set only during the time when we want the - global symbol writer to convert the storage class of defined global - symbols from global to static. */ - bfd_boolean global_to_static; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* When doing a relocatable link, an array of information kept for - each output section, indexed by the target_index field. */ - struct coff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Symbol index of first aux entry of last .bf symbol with an empty - endndx field (-1 if none). */ - long last_bf_index; - /* Contents of last_bf_index aux entry. */ - union internal_auxent last_bf; - /* Hash table used to merge debug information. */ - struct coff_debug_merge_hash_table debug_merge; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold sections of symbols of any input file. */ - asection **sec_ptrs; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; - /* Buffer large enough to hold swapped relocs of any input section. */ - struct internal_reloc *internal_relocs; -}; - -/* Most COFF variants have no way to record the alignment of a - section. This struct is used to set a specific alignment based on - the name of the section. */ - -struct coff_section_alignment_entry -{ - /* The section name. */ - const char *name; - - /* This is either (unsigned int) -1, indicating that the section - name must match exactly, or it is the number of letters which - must match at the start of the name. */ - unsigned int comparison_length; - - /* These macros may be used to fill in the first two fields in a - structure initialization. */ -#define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1) -#define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1) - - /* Only use this entry if the default section alignment for this - target is at least that much (as a power of two). If this field - is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ - unsigned int default_alignment_min; - - /* Only use this entry if the default section alignment for this - target is no greater than this (as a power of two). If this - field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */ - unsigned int default_alignment_max; - -#define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1) - - /* The desired alignment for this section (as a power of two). */ - unsigned int alignment_power; -}; - -extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -extern bfd_boolean _bfd_coff_link_hash_table_init - (struct coff_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int); -extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create - (bfd *); -extern const char *_bfd_coff_internal_syment_name - (bfd *, const struct internal_syment *, char *); -extern bfd_boolean _bfd_coff_section_already_linked - (bfd *, asection *, struct bfd_link_info *); -extern bfd_boolean _bfd_coff_link_add_symbols - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_coff_final_link - (bfd *, struct bfd_link_info *); -extern struct internal_reloc *_bfd_coff_read_internal_relocs - (bfd *, asection *, bfd_boolean, bfd_byte *, bfd_boolean, - struct internal_reloc *); -extern bfd_boolean _bfd_coff_generic_relocate_section - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **); -extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -extern bfd_boolean _bfd_coff_write_global_sym - (struct bfd_hash_entry *, void *); -extern bfd_boolean _bfd_coff_write_task_globals - (struct coff_link_hash_entry *, void *); -extern bfd_boolean _bfd_coff_link_input_bfd - (struct coff_final_link_info *, bfd *); -extern bfd_boolean _bfd_coff_reloc_link_order - (bfd *, struct coff_final_link_info *, asection *, - struct bfd_link_order *); - - -#define coff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Functions in xcofflink.c. */ - -extern long _bfd_xcoff_get_dynamic_symtab_upper_bound - (bfd *); -extern long _bfd_xcoff_canonicalize_dynamic_symtab - (bfd *, asymbol **); -extern long _bfd_xcoff_get_dynamic_reloc_upper_bound - (bfd *); -extern long _bfd_xcoff_canonicalize_dynamic_reloc - (bfd *, arelent **, asymbol **); -extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create - (bfd *); -extern void _bfd_xcoff_bfd_link_hash_table_free - (struct bfd_link_hash_table *); -extern bfd_boolean _bfd_xcoff_bfd_link_add_symbols - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_xcoff_bfd_final_link - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_xcoff_define_common_symbol - (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); -extern bfd_boolean _bfd_ppc_xcoff_relocate_section - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **); - -/* Functions in coff-ppc.c. FIXME: These are called by pe.em in the - linker, and so should start with bfd and be declared in bfd.h. */ - -extern bfd_boolean ppc_allocate_toc_section - (struct bfd_link_info *); -extern bfd_boolean ppc_process_before_allocation - (bfd *, struct bfd_link_info *); -/* Extracted from coffcode.h. */ -typedef struct coff_ptr_struct -{ - /* Remembers the offset from the first symbol in the file for - this symbol. Generated by coff_renumber_symbols. */ - unsigned int offset; - - /* Should the value of this symbol be renumbered. Used for - XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */ - unsigned int fix_value : 1; - - /* Should the tag field of this symbol be renumbered. - Created by coff_pointerize_aux. */ - unsigned int fix_tag : 1; - - /* Should the endidx field of this symbol be renumbered. - Created by coff_pointerize_aux. */ - unsigned int fix_end : 1; - - /* Should the x_csect.x_scnlen field be renumbered. - Created by coff_pointerize_aux. */ - unsigned int fix_scnlen : 1; - - /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the - index into the line number entries. Set by coff_slurp_symbol_table. */ - unsigned int fix_line : 1; - - /* The container for the symbol structure as read and translated - from the file. */ - union - { - union internal_auxent auxent; - struct internal_syment syment; - } u; -} combined_entry_type; - - -/* Each canonical asymbol really looks like this: */ - -typedef struct coff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ - asymbol symbol; - - /* A pointer to the hidden information for this symbol */ - combined_entry_type *native; - - /* A pointer to the linenumber information for this symbol */ - struct lineno_cache_entry *lineno; - - /* Have the line numbers been relocated yet ? */ - bfd_boolean done_lineno; -} coff_symbol_type; -/* COFF symbol classifications. */ - -enum coff_symbol_classification -{ - /* Global symbol. */ - COFF_SYMBOL_GLOBAL, - /* Common symbol. */ - COFF_SYMBOL_COMMON, - /* Undefined symbol. */ - COFF_SYMBOL_UNDEFINED, - /* Local symbol. */ - COFF_SYMBOL_LOCAL, - /* PE section symbol. */ - COFF_SYMBOL_PE_SECTION -}; - -typedef struct -{ - void (*_bfd_coff_swap_aux_in) - (bfd *, void *, int, int, int, int, void *); - - void (*_bfd_coff_swap_sym_in) - (bfd *, void *, void *); - - void (*_bfd_coff_swap_lineno_in) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_aux_out) - (bfd *, void *, int, int, int, int, void *); - - unsigned int (*_bfd_coff_swap_sym_out) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_lineno_out) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_reloc_out) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_filehdr_out) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_aouthdr_out) - (bfd *, void *, void *); - - unsigned int (*_bfd_coff_swap_scnhdr_out) - (bfd *, void *, void *); - - unsigned int _bfd_filhsz; - unsigned int _bfd_aoutsz; - unsigned int _bfd_scnhsz; - unsigned int _bfd_symesz; - unsigned int _bfd_auxesz; - unsigned int _bfd_relsz; - unsigned int _bfd_linesz; - unsigned int _bfd_filnmlen; - bfd_boolean _bfd_coff_long_filenames; - - bfd_boolean _bfd_coff_long_section_names; - bfd_boolean (*_bfd_coff_set_long_section_names) - (bfd *, int); - - unsigned int _bfd_coff_default_section_alignment_power; - bfd_boolean _bfd_coff_force_symnames_in_strings; - unsigned int _bfd_coff_debug_string_prefix_length; - - void (*_bfd_coff_swap_filehdr_in) - (bfd *, void *, void *); - - void (*_bfd_coff_swap_aouthdr_in) - (bfd *, void *, void *); - - void (*_bfd_coff_swap_scnhdr_in) - (bfd *, void *, void *); - - void (*_bfd_coff_swap_reloc_in) - (bfd *abfd, void *, void *); - - bfd_boolean (*_bfd_coff_bad_format_hook) - (bfd *, void *); - - bfd_boolean (*_bfd_coff_set_arch_mach_hook) - (bfd *, void *); - - void * (*_bfd_coff_mkobject_hook) - (bfd *, void *, void *); - - bfd_boolean (*_bfd_styp_to_sec_flags_hook) - (bfd *, void *, const char *, asection *, flagword *); - - void (*_bfd_set_alignment_hook) - (bfd *, asection *, void *); - - bfd_boolean (*_bfd_coff_slurp_symbol_table) - (bfd *); - - bfd_boolean (*_bfd_coff_symname_in_debug) - (bfd *, struct internal_syment *); - - bfd_boolean (*_bfd_coff_pointerize_aux_hook) - (bfd *, combined_entry_type *, combined_entry_type *, - unsigned int, combined_entry_type *); - - bfd_boolean (*_bfd_coff_print_aux) - (bfd *, FILE *, combined_entry_type *, combined_entry_type *, - combined_entry_type *, unsigned int); - - void (*_bfd_coff_reloc16_extra_cases) - (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, - bfd_byte *, unsigned int *, unsigned int *); - - int (*_bfd_coff_reloc16_estimate) - (bfd *, asection *, arelent *, unsigned int, - struct bfd_link_info *); - - enum coff_symbol_classification (*_bfd_coff_classify_symbol) - (bfd *, struct internal_syment *); - - bfd_boolean (*_bfd_coff_compute_section_file_positions) - (bfd *); - - bfd_boolean (*_bfd_coff_start_final_link) - (bfd *, struct bfd_link_info *); - - bfd_boolean (*_bfd_coff_relocate_section) - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **); - - reloc_howto_type *(*_bfd_coff_rtype_to_howto) - (bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *); - - bfd_boolean (*_bfd_coff_adjust_symndx) - (bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, bfd_boolean *); - - bfd_boolean (*_bfd_coff_link_add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, - struct bfd_link_hash_entry **); - - bfd_boolean (*_bfd_coff_link_output_has_begun) - (bfd *, struct coff_final_link_info *); - - bfd_boolean (*_bfd_coff_final_link_postscript) - (bfd *, struct coff_final_link_info *); - - bfd_boolean (*_bfd_coff_print_pdata) - (bfd *, void *); - -} bfd_coff_backend_data; - -#define coff_backend_info(abfd) \ - ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) - -#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ - ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) - -#define bfd_coff_swap_sym_in(a,e,i) \ - ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) - -#define bfd_coff_swap_lineno_in(a,e,i) \ - ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) - -#define bfd_coff_swap_reloc_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) - -#define bfd_coff_swap_lineno_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) - -#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ - ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) - -#define bfd_coff_swap_sym_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) - -#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) - -#define bfd_coff_swap_filehdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) - -#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) -#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) -#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) -#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) -#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) -#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) -#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) -#define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen) -#define bfd_coff_long_filenames(abfd) \ - (coff_backend_info (abfd)->_bfd_coff_long_filenames) -#define bfd_coff_long_section_names(abfd) \ - (coff_backend_info (abfd)->_bfd_coff_long_section_names) -#define bfd_coff_set_long_section_names(abfd, enable) \ - ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) -#define bfd_coff_default_section_alignment_power(abfd) \ - (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) -#define bfd_coff_swap_filehdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) - -#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) - -#define bfd_coff_swap_reloc_in(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) - -#define bfd_coff_bad_format_hook(abfd, filehdr) \ - ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) - -#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ - ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) -#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ - ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\ - (abfd, filehdr, aouthdr)) - -#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\ - ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\ - (abfd, scnhdr, name, section, flags_ptr)) - -#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ - ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) - -#define bfd_coff_slurp_symbol_table(abfd)\ - ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) - -#define bfd_coff_symname_in_debug(abfd, sym)\ - ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) - -#define bfd_coff_force_symnames_in_strings(abfd)\ - (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings) - -#define bfd_coff_debug_string_prefix_length(abfd)\ - (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length) - -#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ - ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ - (abfd, file, base, symbol, aux, indaux)) - -#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\ - reloc, data, src_ptr, dst_ptr)\ - ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ - (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) - -#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ - ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ - (abfd, section, reloc, shrink, link_info)) - -#define bfd_coff_classify_symbol(abfd, sym)\ - ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\ - (abfd, sym)) - -#define bfd_coff_compute_section_file_positions(abfd)\ - ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ - (abfd)) - -#define bfd_coff_start_final_link(obfd, info)\ - ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ - (obfd, info)) -#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ - ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ - (obfd, info, ibfd, o, con, rel, isyms, secs)) -#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ - ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ - (abfd, sec, rel, h, sym, addendp)) -#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ - ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ - (obfd, info, ibfd, sec, rel, adjustedp)) -#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ - value, string, cp, coll, hashp)\ - ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ - (info, abfd, name, flags, section, value, string, cp, coll, hashp)) - -#define bfd_coff_link_output_has_begun(a,p) \ - ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) -#define bfd_coff_final_link_postscript(a,p) \ - ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p)) - -#define bfd_coff_have_print_pdata(a) \ - (coff_backend_info (a)->_bfd_coff_print_pdata) -#define bfd_coff_print_pdata(a,p) \ - ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p)) - -/* Macro: Returns true if the bfd is a PE executable as opposed to a - PE object file. */ -#define bfd_pei_p(abfd) \ - (CONST_STRNEQ ((abfd)->xvec->name, "pei-")) diff --git a/contrib/binutils-2.22/bfd/libecoff.h b/contrib/binutils-2.22/bfd/libecoff.h deleted file mode 100644 index 8afdccb0ce..0000000000 --- a/contrib/binutils-2.22/bfd/libecoff.h +++ /dev/null @@ -1,348 +0,0 @@ -/* BFD ECOFF object file private structure. - Copyright 1993, 1994, 1995, 1996, 1999, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "bfdlink.h" - -#ifndef ECOFF_H -#include "coff/ecoff.h" -#endif - -/* This is the backend information kept for ECOFF files. This - structure is constant for a particular backend. The first element - is the COFF backend data structure, so that ECOFF targets can use - the generic COFF code. */ - -#define ecoff_backend(abfd) \ - ((struct ecoff_backend_data *) (abfd)->xvec->backend_data) - -struct ecoff_backend_data -{ - /* COFF backend information. This must be the first field. */ - bfd_coff_backend_data coff; - /* Supported architecture. */ - enum bfd_architecture arch; - /* Initial portion of armap string. */ - const char *armap_start; - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - bfd_vma round; - /* TRUE if the .rdata section is part of the text segment, as on the - Alpha. FALSE if .rdata is part of the data segment, as on the - MIPS. */ - bfd_boolean rdata_in_text; - /* Bitsize of constructor entries. */ - unsigned int constructor_bitsize; - /* Reloc to use for constructor entries. */ - reloc_howto_type *constructor_reloc; - /* How to swap debugging information. */ - struct ecoff_debug_swap debug_swap; - /* External reloc size. */ - bfd_size_type external_reloc_size; - /* Reloc swapping functions. */ - void (*swap_reloc_in) (bfd *, void *, struct internal_reloc *); - void (*swap_reloc_out) (bfd *, const struct internal_reloc *, void *); - /* Backend reloc tweaking. */ - void (*adjust_reloc_in) - (bfd *, const struct internal_reloc *, arelent *); - void (*adjust_reloc_out) - (bfd *, const arelent *, struct internal_reloc *); - /* Relocate section contents while linking. */ - bfd_boolean (*relocate_section) - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, void *); - /* Do final adjustments to filehdr and aouthdr. */ - bfd_boolean (*adjust_headers) - (bfd *, struct internal_filehdr *, struct internal_aouthdr *); - /* Read an element from an archive at a given file position. This - is needed because OSF/1 3.2 uses a weird archive format. */ - bfd *(*get_elt_at_filepos) (bfd *, file_ptr); -}; - -/* ECOFF targets don't support COFF long section names, so this - macro is provided to use as an initialiser for the related - members of the embedded bfd_coff_backend_data struct. */ -#define ECOFF_NO_LONG_SECTION_NAMES (FALSE), _bfd_ecoff_no_long_sections - -/* This is the target specific information kept for ECOFF files. */ - -#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data) - -typedef struct ecoff_tdata -{ - /* The reloc file position, set by - ecoff_compute_section_file_positions. */ - file_ptr reloc_filepos; - - /* The symbol table file position, set by _bfd_ecoff_mkobject_hook. */ - file_ptr sym_filepos; - - /* The start and end of the text segment. Only valid for an - existing file, not for one we are creating. */ - unsigned long text_start; - unsigned long text_end; - - /* The cached gp value. This is used when relocating. */ - bfd_vma gp; - - /* The maximum size of objects to optimize using gp. This is - typically set by the -G option to the compiler, assembler or - linker. */ - unsigned int gp_size; - - /* The register masks. When linking, all the masks found in the - input files are combined into the masks of the output file. - These are not all used for all targets, but that's OK, because - the relevant ones are the only ones swapped in and out. */ - unsigned long gprmask; - unsigned long fprmask; - unsigned long cprmask[4]; - - /* The ECOFF symbolic debugging information. */ - struct ecoff_debug_info debug_info; - - /* The unswapped ECOFF symbolic information. */ - void * raw_syments; - - /* The canonical BFD symbols. */ - struct ecoff_symbol_struct *canonical_symbols; - - /* A mapping from external symbol numbers to entries in the linker - hash table, used when linking. */ - struct ecoff_link_hash_entry **sym_hashes; - - /* A mapping from reloc symbol indices to sections, used when - linking. */ - asection **symndx_to_section; - - /* TRUE if this BFD was written by the backend linker. */ - bfd_boolean linker; - - /* TRUE if a warning that multiple global pointer values are - needed in the output binary was issued already. */ - bfd_boolean issued_multiple_gp_warning; - - /* Used by find_nearest_line entry point. The structure could be - included directly in this one, but there's no point to wasting - the memory just for the infrequently called find_nearest_line. */ - struct ecoff_find_line *find_line_info; - - /* Whether the .rdata section is in the text segment for this - particular ECOFF file. This is not valid until - ecoff_compute_section_file_positions is called. */ - bfd_boolean rdata_in_text; - -} ecoff_data_type; - -/* Each canonical asymbol really looks like this. */ - -typedef struct ecoff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ - asymbol symbol; - - /* The fdr for this symbol. */ - FDR *fdr; - - /* TRUE if this is a local symbol rather than an external one. */ - bfd_boolean local; - - /* A pointer to the unswapped hidden information for this symbol. - This is either a struct sym_ext or a struct ext_ext, depending on - the value of the local field above. */ - void * native; -} ecoff_symbol_type; - -/* We take the address of the first element of an asymbol to ensure that the - macro is only ever applied to an asymbol. */ -#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd))) - -/* We need to save the index of an external symbol when we write it - out so that can set the symbol index correctly when we write out - the relocs. */ -#define ecoff_get_sym_index(symbol) ((symbol)->udata.i) -#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata.i = (idx)) - -/* A pointer to this structure is put in the used_by_bfd pointer of - a section to keep track of any per-section data. - The user_by_bfd pointer will be NULL if the information was not - needed. */ - -struct ecoff_section_tdata -{ - /* When producing an executable (i.e., final, non-relocatable link) - on the Alpha, we may need to use multiple global pointer values - to span the entire .lita section. In essence, we allow each - input .lita section to have its own gp value. To support this, - we need to keep track of the gp values that we picked for each - input .lita section . */ - bfd_vma gp; -}; - -/* An accessor macro for the ecoff_section_tdata structure. */ -#define ecoff_section_data(abfd, sec) \ - ((struct ecoff_section_tdata *) (sec)->used_by_bfd) - -/* ECOFF linker hash table entries. */ - -struct ecoff_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Symbol index in output file. */ - long indx; - /* BFD that ext field value came from. */ - bfd *abfd; - /* ECOFF external symbol information. */ - EXTR esym; - /* Nonzero if this symbol has been written out. */ - char written; - /* Nonzero if this symbol was referred to as small undefined. */ - char small; -}; - -/* ECOFF linker hash table. */ - -struct ecoff_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Make an ECOFF object. */ -extern bfd_boolean _bfd_ecoff_mkobject (bfd *); - -/* Read in the ECOFF symbolic debugging information. */ -extern bfd_boolean _bfd_ecoff_slurp_symbolic_info - (bfd *, asection *, struct ecoff_debug_info *); - -/* Generic ECOFF BFD backend vectors. */ - -extern bfd_boolean _bfd_ecoff_write_object_contents (bfd *); - -#define _bfd_ecoff_close_and_cleanup _bfd_generic_close_and_cleanup -#define _bfd_ecoff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -extern bfd_boolean _bfd_ecoff_new_section_hook - (bfd *, asection *); -extern bfd_boolean _bfd_ecoff_get_section_contents - (bfd *, asection *, void * location, file_ptr, bfd_size_type); - -#define _bfd_ecoff_bfd_link_split_section _bfd_generic_link_split_section - -extern bfd_boolean _bfd_ecoff_bfd_copy_private_bfd_data - (bfd *, bfd *); -#define _bfd_ecoff_bfd_copy_private_section_data \ - _bfd_generic_bfd_copy_private_section_data - -#define _bfd_ecoff_bfd_copy_private_symbol_data \ - _bfd_generic_bfd_copy_private_symbol_data - -#define _bfd_ecoff_bfd_copy_private_header_data \ - _bfd_generic_bfd_copy_private_header_data - -#define _bfd_ecoff_bfd_print_private_bfd_data \ - _bfd_generic_bfd_print_private_bfd_data - -#define _bfd_ecoff_bfd_merge_private_bfd_data \ - _bfd_generic_bfd_merge_private_bfd_data - -#define _bfd_ecoff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -extern bfd_boolean _bfd_ecoff_slurp_armap (bfd *); -#define _bfd_ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table -#define _bfd_ecoff_construct_extended_name_table \ - _bfd_archive_bsd_construct_extended_name_table -#define _bfd_ecoff_truncate_arname bfd_dont_truncate_arname -extern bfd_boolean _bfd_ecoff_write_armap - (bfd *, unsigned int, struct orl *, unsigned int, int); -#define _bfd_ecoff_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_ecoff_write_ar_hdr _bfd_generic_write_ar_hdr -#define _bfd_ecoff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_ecoff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_ecoff_update_armap_timestamp bfd_true -#define _bfd_ecoff_bfd_is_target_special_symbol \ - ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) - -extern long _bfd_ecoff_get_symtab_upper_bound (bfd *); -extern long _bfd_ecoff_canonicalize_symtab (bfd *, asymbol **); -extern asymbol *_bfd_ecoff_make_empty_symbol (bfd *); -extern void _bfd_ecoff_print_symbol - (bfd *, void *, asymbol *, bfd_print_symbol_type); -extern void _bfd_ecoff_get_symbol_info - (bfd *, asymbol *, symbol_info *); -extern bfd_boolean _bfd_ecoff_bfd_is_local_label_name - (bfd *, const char *); -#define _bfd_ecoff_get_lineno _bfd_nosymbols_get_lineno -extern bfd_boolean _bfd_ecoff_find_nearest_line - (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, - unsigned int *); -#define _bfd_ecoff_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define _bfd_ecoff_read_minisymbols _bfd_generic_read_minisymbols -#define _bfd_ecoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define _bfd_ecoff_find_inliner_info _bfd_nosymbols_find_inliner_info - -#define _bfd_ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound -extern long _bfd_ecoff_canonicalize_reloc - (bfd *, asection *, arelent **, asymbol **symbols); -/* ecoff_bfd_reloc_type_lookup defined by backend. */ - -extern bfd_boolean _bfd_ecoff_set_arch_mach - (bfd *, enum bfd_architecture, unsigned long); -extern bfd_boolean _bfd_ecoff_set_section_contents - (bfd *, asection *, const void * location, file_ptr, bfd_size_type); - -extern int _bfd_ecoff_sizeof_headers (bfd *, struct bfd_link_info *); -/* ecoff_bfd_get_relocated_section_contents defined by backend. */ -/* ecoff_bfd_relax_section defined by backend. */ -extern struct bfd_link_hash_table *_bfd_ecoff_bfd_link_hash_table_create - (bfd *); -#define _bfd_ecoff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -extern bfd_boolean _bfd_ecoff_bfd_link_add_symbols - (bfd *, struct bfd_link_info *); -#define _bfd_ecoff_bfd_link_just_syms _bfd_generic_link_just_syms -#define _bfd_ecoff_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -extern bfd_boolean _bfd_ecoff_bfd_final_link - (bfd *, struct bfd_link_info *); - -/* Hook functions for the generic COFF section reading code. */ - -extern void * _bfd_ecoff_mkobject_hook (bfd *, void *, void *); -#define _bfd_ecoff_set_alignment_hook \ - ((void (*) (bfd *, asection *, void *)) bfd_void) -extern bfd_boolean _bfd_ecoff_set_arch_mach_hook - (bfd *, void *); -extern bfd_boolean _bfd_ecoff_no_long_sections - (bfd *abfd, int enable); -extern bfd_boolean _bfd_ecoff_styp_to_sec_flags - (bfd *, void *, const char *, asection *, flagword *); -extern bfd_boolean _bfd_ecoff_slurp_symbol_table (bfd *); - -/* ECOFF auxiliary information swapping routines. These are the same - for all ECOFF targets, so they are defined in ecofflink.c. */ - -extern void _bfd_ecoff_swap_tir_in - (int, const struct tir_ext *, TIR *); -extern void _bfd_ecoff_swap_tir_out - (int, const TIR *, struct tir_ext *); -extern void _bfd_ecoff_swap_rndx_in - (int, const struct rndx_ext *, RNDXR *); -extern void _bfd_ecoff_swap_rndx_out - (int, const RNDXR *, struct rndx_ext *); diff --git a/contrib/binutils-2.22/bfd/linker.c b/contrib/binutils-2.22/bfd/linker.c deleted file mode 100644 index 7a01e114a2..0000000000 --- a/contrib/binutils-2.22/bfd/linker.c +++ /dev/null @@ -1,3405 +0,0 @@ -/* linker.c -- BFD linker routines - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" - -/* -SECTION - Linker Functions - -@cindex Linker - The linker uses three special entry points in the BFD target - vector. It is not necessary to write special routines for - these entry points when creating a new BFD back end, since - generic versions are provided. However, writing them can - speed up linking and make it use significantly less runtime - memory. - - The first routine creates a hash table used by the other - routines. The second routine adds the symbols from an object - file to the hash table. The third routine takes all the - object files and links them together to create the output - file. These routines are designed so that the linker proper - does not need to know anything about the symbols in the object - files that it is linking. The linker merely arranges the - sections as directed by the linker script and lets BFD handle - the details of symbols and relocs. - - The second routine and third routines are passed a pointer to - a <> structure (defined in - <>) which holds information relevant to the link, - including the linker hash table (which was created by the - first routine) and a set of callback functions to the linker - proper. - - The generic linker routines are in <>, and use the - header file <>. As of this writing, the only back - ends which have implemented versions of these routines are - a.out (in <>) and ECOFF (in <>). The a.out - routines are used as examples throughout this section. - -@menu -@* Creating a Linker Hash Table:: -@* Adding Symbols to the Hash Table:: -@* Performing the Final Link:: -@end menu - -INODE -Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions -SUBSECTION - Creating a linker hash table - -@cindex _bfd_link_hash_table_create in target vector -@cindex target vector (_bfd_link_hash_table_create) - The linker routines must create a hash table, which must be - derived from <> described in - <>. @xref{Hash Tables}, for information on how to - create a derived hash table. This entry point is called using - the target vector of the linker output file. - - The <<_bfd_link_hash_table_create>> entry point must allocate - and initialize an instance of the desired hash table. If the - back end does not require any additional information to be - stored with the entries in the hash table, the entry point may - simply create a <>. Most likely, - however, some additional information will be needed. - - For example, with each entry in the hash table the a.out - linker keeps the index the symbol has in the final output file - (this index number is used so that when doing a relocatable - link the symbol index used in the output file can be quickly - filled in when copying over a reloc). The a.out linker code - defines the required structures and functions for a hash table - derived from <>. The a.out linker - hash table is created by the function - <>; it simply allocates - space for the hash table, initializes it, and returns a - pointer to it. - - When writing the linker routines for a new back end, you will - generally not know exactly which fields will be required until - you have finished. You should simply create a new hash table - which defines no additional fields, and then simply add fields - as they become necessary. - -INODE -Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions -SUBSECTION - Adding symbols to the hash table - -@cindex _bfd_link_add_symbols in target vector -@cindex target vector (_bfd_link_add_symbols) - The linker proper will call the <<_bfd_link_add_symbols>> - entry point for each object file or archive which is to be - linked (typically these are the files named on the command - line, but some may also come from the linker script). The - entry point is responsible for examining the file. For an - object file, BFD must add any relevant symbol information to - the hash table. For an archive, BFD must determine which - elements of the archive should be used and adding them to the - link. - - The a.out version of this entry point is - <>. - -@menu -@* Differing file formats:: -@* Adding symbols from an object file:: -@* Adding symbols from an archive:: -@end menu - -INODE -Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table -SUBSUBSECTION - Differing file formats - - Normally all the files involved in a link will be of the same - format, but it is also possible to link together different - format object files, and the back end must support that. The - <<_bfd_link_add_symbols>> entry point is called via the target - vector of the file to be added. This has an important - consequence: the function may not assume that the hash table - is the type created by the corresponding - <<_bfd_link_hash_table_create>> vector. All the - <<_bfd_link_add_symbols>> function can assume about the hash - table is that it is derived from <>. - - Sometimes the <<_bfd_link_add_symbols>> function must store - some information in the hash table entry to be used by the - <<_bfd_final_link>> function. In such a case the output bfd - xvec must be checked to make sure that the hash table was - created by an object file of the same format. - - The <<_bfd_final_link>> routine must be prepared to handle a - hash entry without any extra information added by the - <<_bfd_link_add_symbols>> function. A hash entry without - extra information will also occur when the linker script - directs the linker to create a symbol. Note that, regardless - of how a hash table entry is added, all the fields will be - initialized to some sort of null value by the hash table entry - initialization function. - - See <> for an example of how to - check the output bfd before saving information (in this - case, the ECOFF external symbol debugging information) in a - hash table entry. - -INODE -Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an object file - - When the <<_bfd_link_add_symbols>> routine is passed an object - file, it must add all externally visible symbols in that - object file to the hash table. The actual work of adding the - symbol to the hash table is normally handled by the function - <<_bfd_generic_link_add_one_symbol>>. The - <<_bfd_link_add_symbols>> routine is responsible for reading - all the symbols from the object file and passing the correct - information to <<_bfd_generic_link_add_one_symbol>>. - - The <<_bfd_link_add_symbols>> routine should not use - <> to read the symbols. The point of - providing this routine is to avoid the overhead of converting - the symbols into generic <> structures. - -@findex _bfd_generic_link_add_one_symbol - <<_bfd_generic_link_add_one_symbol>> handles the details of - combining common symbols, warning about multiple definitions, - and so forth. It takes arguments which describe the symbol to - add, notably symbol flags, a section, and an offset. The - symbol flags include such things as <> or - <>. The section is a section in the object - file, or something like <> for an undefined - symbol or <> for a common symbol. - - If the <<_bfd_final_link>> routine is also going to need to - read the symbol information, the <<_bfd_link_add_symbols>> - routine should save it somewhere attached to the object file - BFD. However, the information should only be saved if the - <> field of the <> argument is TRUE, so - that the <<-no-keep-memory>> linker switch is effective. - - The a.out function which adds symbols from an object file is - <>, and most of the interesting - work is in <>. The latter saves - pointers to the hash tables entries created by - <<_bfd_generic_link_add_one_symbol>> indexed by symbol number, - so that the <<_bfd_final_link>> routine does not have to call - the hash table lookup routine to locate the entry. - -INODE -Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an archive - - When the <<_bfd_link_add_symbols>> routine is passed an - archive, it must look through the symbols defined by the - archive and decide which elements of the archive should be - included in the link. For each such element it must call the - <> linker callback, and it must add the - symbols from the object file to the linker hash table. (The - callback may in fact indicate that a replacement BFD should be - used, in which case the symbols from that BFD should be added - to the linker hash table instead.) - -@findex _bfd_generic_link_add_archive_symbols - In most cases the work of looking through the symbols in the - archive should be done by the - <<_bfd_generic_link_add_archive_symbols>> function. This - function builds a hash table from the archive symbol table and - looks through the list of undefined symbols to see which - elements should be included. - <<_bfd_generic_link_add_archive_symbols>> is passed a function - to call to make the final decision about adding an archive - element to the link and to do the actual work of adding the - symbols to the linker hash table. - - The function passed to - <<_bfd_generic_link_add_archive_symbols>> must read the - symbols of the archive element and decide whether the archive - element should be included in the link. If the element is to - be included, the <> linker callback - routine must be called with the element as an argument, and - the element's symbols must be added to the linker hash table - just as though the element had itself been passed to the - <<_bfd_link_add_symbols>> function. The <> - callback has the option to indicate that it would like to - replace the element archive with a substitute BFD, in which - case it is the symbols of that substitute BFD that must be - added to the linker hash table instead. - - When the a.out <<_bfd_link_add_symbols>> function receives an - archive, it calls <<_bfd_generic_link_add_archive_symbols>> - passing <> as the function - argument. <> calls - <>. If the latter decides to add - the element (an element is only added if it provides a real, - non-common, definition for a previously undefined or common - symbol) it calls the <> callback and then - <> calls - <> to actually add the symbols to the - linker hash table - possibly those of a substitute BFD, if the - <> callback avails itself of that option. - - The ECOFF back end is unusual in that it does not normally - call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF - archives already contain a hash table of symbols. The ECOFF - back end searches the archive itself to avoid the overhead of - creating a new hash table. - -INODE -Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions -SUBSECTION - Performing the final link - -@cindex _bfd_link_final_link in target vector -@cindex target vector (_bfd_final_link) - When all the input files have been processed, the linker calls - the <<_bfd_final_link>> entry point of the output BFD. This - routine is responsible for producing the final output file, - which has several aspects. It must relocate the contents of - the input sections and copy the data into the output sections. - It must build an output symbol table including any local - symbols from the input files and the global symbols from the - hash table. When producing relocatable output, it must - modify the input relocs and write them into the output file. - There may also be object format dependent work to be done. - - The linker will also call the <> entry - point when the BFD is closed. The two entry points must work - together in order to produce the correct output file. - - The details of how this works are inevitably dependent upon - the specific object file format. The a.out - <<_bfd_final_link>> routine is <>. - -@menu -@* Information provided by the linker:: -@* Relocating the section contents:: -@* Writing the symbol table:: -@end menu - -INODE -Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link -SUBSUBSECTION - Information provided by the linker - - Before the linker calls the <<_bfd_final_link>> entry point, - it sets up some data structures for the function to use. - - The <> field of the <> structure - will point to a list of all the input files included in the - link. These files are linked through the <> field - of the <> structure. - - Each section in the output file will have a list of - <> structures attached to the <> - field (the <> structure is defined in - <>). These structures describe how to create the - contents of the output section in terms of the contents of - various input sections, fill constants, and, eventually, other - types of information. They also describe relocs that must be - created by the BFD backend, but do not correspond to any input - file; this is used to support -Ur, which builds constructors - while generating a relocatable object file. - -INODE -Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link -SUBSUBSECTION - Relocating the section contents - - The <<_bfd_final_link>> function should look through the - <> structures attached to each section of the - output file. Each <> structure should either be - handled specially, or it should be passed to the function - <<_bfd_default_link_order>> which will do the right thing - (<<_bfd_default_link_order>> is defined in <>). - - For efficiency, a <> of type - <> whose associated section belongs - to a BFD of the same format as the output BFD must be handled - specially. This type of <> describes part of an - output section in terms of a section belonging to one of the - input files. The <<_bfd_final_link>> function should read the - contents of the section and any associated relocs, apply the - relocs to the section contents, and write out the modified - section contents. If performing a relocatable link, the - relocs themselves must also be modified and written out. - -@findex _bfd_relocate_contents -@findex _bfd_final_link_relocate - The functions <<_bfd_relocate_contents>> and - <<_bfd_final_link_relocate>> provide some general support for - performing the actual relocations, notably overflow checking. - Their arguments include information about the symbol the - relocation is against and a <> argument - which describes the relocation to perform. These functions - are defined in <>. - - The a.out function which handles reading, relocating, and - writing section contents is <>. The - actual relocation is done in <> - and <>. - -INODE -Writing the symbol table, , Relocating the section contents, Performing the Final Link -SUBSUBSECTION - Writing the symbol table - - The <<_bfd_final_link>> function must gather all the symbols - in the input files and write them out. It must also write out - all the symbols in the global hash table. This must be - controlled by the <> and <> fields of the - <> structure. - - The local symbols of the input files will not have been - entered into the linker hash table. The <<_bfd_final_link>> - routine must consider each input file and include the symbols - in the output file. It may be convenient to do this when - looking through the <> structures, or it may be - done by stepping through the <> list. - - The <<_bfd_final_link>> routine must also traverse the global - hash table to gather all the externally visible symbols. It - is possible that most of the externally visible symbols may be - written out when considering the symbols of each input file, - but it is still necessary to traverse the hash table since the - linker script may have defined some symbols that are not in - any of the input files. - - The <> field of the <> structure - controls which symbols are written out. The possible values - are listed in <>. If the value is <>, - then the <> field of the <> - structure is a hash table of symbols to keep; each symbol - should be looked up in this hash table, and only symbols which - are present should be included in the output file. - - If the <> field of the <> structure - permits local symbols to be written out, the <> field - is used to further controls which local symbols are included - in the output file. If the value is <>, then all - local symbols which begin with a certain prefix are discarded; - this is controlled by the <> entry point. - - The a.out backend handles symbols by calling - <> on each input BFD and then - traversing the global hash table with the function - <>. It builds a string table - while writing out the symbols, which is written to the output - file at the end of <>. -*/ - -static bfd_boolean generic_link_add_object_symbols - (bfd *, struct bfd_link_info *, bfd_boolean collect); -static bfd_boolean generic_link_add_symbols - (bfd *, struct bfd_link_info *, bfd_boolean); -static bfd_boolean generic_link_check_archive_element_no_collect - (bfd *, struct bfd_link_info *, bfd_boolean *); -static bfd_boolean generic_link_check_archive_element_collect - (bfd *, struct bfd_link_info *, bfd_boolean *); -static bfd_boolean generic_link_check_archive_element - (bfd *, struct bfd_link_info *, bfd_boolean *, bfd_boolean); -static bfd_boolean generic_link_add_symbol_list - (bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **, - bfd_boolean); -static bfd_boolean generic_add_output_symbol - (bfd *, size_t *psymalloc, asymbol *); -static bfd_boolean default_data_link_order - (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); -static bfd_boolean default_indirect_link_order - (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *, - bfd_boolean); - -/* The link hash table structure is defined in bfdlink.h. It provides - a base hash table which the backend specific hash tables are built - upon. */ - -/* Routine to create an entry in the link hash table. */ - -struct bfd_hash_entry * -_bfd_link_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = bfd_hash_newfunc (entry, table, string); - if (entry) - { - struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry; - - /* Initialize the local fields. */ - memset ((char *) &h->root + sizeof (h->root), 0, - sizeof (*h) - sizeof (h->root)); - } - - return entry; -} - -/* Initialize a link hash table. The BFD argument is the one - responsible for creating this table. */ - -bfd_boolean -_bfd_link_hash_table_init - (struct bfd_link_hash_table *table, - bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int entsize) -{ - table->undefs = NULL; - table->undefs_tail = NULL; - table->type = bfd_link_generic_hash_table; - - return bfd_hash_table_init (&table->table, newfunc, entsize); -} - -/* Look up a symbol in a link hash table. If follow is TRUE, we - follow bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ - -struct bfd_link_hash_entry * -bfd_link_hash_lookup (struct bfd_link_hash_table *table, - const char *string, - bfd_boolean create, - bfd_boolean copy, - bfd_boolean follow) -{ - struct bfd_link_hash_entry *ret; - - ret = ((struct bfd_link_hash_entry *) - bfd_hash_lookup (&table->table, string, create, copy)); - - if (follow && ret != NULL) - { - while (ret->type == bfd_link_hash_indirect - || ret->type == bfd_link_hash_warning) - ret = ret->u.i.link; - } - - return ret; -} - -/* Look up a symbol in the main linker hash table if the symbol might - be wrapped. This should only be used for references to an - undefined symbol, not for definitions of a symbol. */ - -struct bfd_link_hash_entry * -bfd_wrapped_link_hash_lookup (bfd *abfd, - struct bfd_link_info *info, - const char *string, - bfd_boolean create, - bfd_boolean copy, - bfd_boolean follow) -{ - bfd_size_type amt; - - if (info->wrap_hash != NULL) - { - const char *l; - char prefix = '\0'; - - l = string; - if (*l == bfd_get_symbol_leading_char (abfd) || *l == info->wrap_char) - { - prefix = *l; - ++l; - } - -#undef WRAP -#define WRAP "__wrap_" - - if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL) - { - char *n; - struct bfd_link_hash_entry *h; - - /* This symbol is being wrapped. We want to replace all - references to SYM with references to __wrap_SYM. */ - - amt = strlen (l) + sizeof WRAP + 1; - n = (char *) bfd_malloc (amt); - if (n == NULL) - return NULL; - - n[0] = prefix; - n[1] = '\0'; - strcat (n, WRAP); - strcat (n, l); - h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow); - free (n); - return h; - } - -#undef WRAP - -#undef REAL -#define REAL "__real_" - - if (*l == '_' - && CONST_STRNEQ (l, REAL) - && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, - FALSE, FALSE) != NULL) - { - char *n; - struct bfd_link_hash_entry *h; - - /* This is a reference to __real_SYM, where SYM is being - wrapped. We want to replace all references to __real_SYM - with references to SYM. */ - - amt = strlen (l + sizeof REAL - 1) + 2; - n = (char *) bfd_malloc (amt); - if (n == NULL) - return NULL; - - n[0] = prefix; - n[1] = '\0'; - strcat (n, l + sizeof REAL - 1); - h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow); - free (n); - return h; - } - -#undef REAL - } - - return bfd_link_hash_lookup (info->hash, string, create, copy, follow); -} - -/* Traverse a generic link hash table. Differs from bfd_hash_traverse - in the treatment of warning symbols. When warning symbols are - created they replace the real symbol, so you don't get to see the - real symbol in a bfd_hash_travere. This traversal calls func with - the real symbol. */ - -void -bfd_link_hash_traverse - (struct bfd_link_hash_table *htab, - bfd_boolean (*func) (struct bfd_link_hash_entry *, void *), - void *info) -{ - unsigned int i; - - htab->table.frozen = 1; - for (i = 0; i < htab->table.size; i++) - { - struct bfd_link_hash_entry *p; - - p = (struct bfd_link_hash_entry *) htab->table.table[i]; - for (; p != NULL; p = (struct bfd_link_hash_entry *) p->root.next) - if (!(*func) (p->type == bfd_link_hash_warning ? p->u.i.link : p, info)) - goto out; - } - out: - htab->table.frozen = 0; -} - -/* Add a symbol to the linker hash table undefs list. */ - -void -bfd_link_add_undef (struct bfd_link_hash_table *table, - struct bfd_link_hash_entry *h) -{ - BFD_ASSERT (h->u.undef.next == NULL); - if (table->undefs_tail != NULL) - table->undefs_tail->u.undef.next = h; - if (table->undefs == NULL) - table->undefs = h; - table->undefs_tail = h; -} - -/* The undefs list was designed so that in normal use we don't need to - remove entries. However, if symbols on the list are changed from - bfd_link_hash_undefined to either bfd_link_hash_undefweak or - bfd_link_hash_new for some reason, then they must be removed from the - list. Failure to do so might result in the linker attempting to add - the symbol to the list again at a later stage. */ - -void -bfd_link_repair_undef_list (struct bfd_link_hash_table *table) -{ - struct bfd_link_hash_entry **pun; - - pun = &table->undefs; - while (*pun != NULL) - { - struct bfd_link_hash_entry *h = *pun; - - if (h->type == bfd_link_hash_new - || h->type == bfd_link_hash_undefweak) - { - *pun = h->u.undef.next; - h->u.undef.next = NULL; - if (h == table->undefs_tail) - { - if (pun == &table->undefs) - table->undefs_tail = NULL; - else - /* pun points at an u.undef.next field. Go back to - the start of the link_hash_entry. */ - table->undefs_tail = (struct bfd_link_hash_entry *) - ((char *) pun - ((char *) &h->u.undef.next - (char *) h)); - break; - } - } - else - pun = &h->u.undef.next; - } -} - -/* Routine to create an entry in a generic link hash table. */ - -struct bfd_hash_entry * -_bfd_generic_link_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = _bfd_link_hash_newfunc (entry, table, string); - if (entry) - { - struct generic_link_hash_entry *ret; - - /* Set local fields. */ - ret = (struct generic_link_hash_entry *) entry; - ret->written = FALSE; - ret->sym = NULL; - } - - return entry; -} - -/* Create a generic link hash table. */ - -struct bfd_link_hash_table * -_bfd_generic_link_hash_table_create (bfd *abfd) -{ - struct generic_link_hash_table *ret; - bfd_size_type amt = sizeof (struct generic_link_hash_table); - - ret = (struct generic_link_hash_table *) bfd_malloc (amt); - if (ret == NULL) - return NULL; - if (! _bfd_link_hash_table_init (&ret->root, abfd, - _bfd_generic_link_hash_newfunc, - sizeof (struct generic_link_hash_entry))) - { - free (ret); - return NULL; - } - return &ret->root; -} - -void -_bfd_generic_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct generic_link_hash_table *ret - = (struct generic_link_hash_table *) hash; - - bfd_hash_table_free (&ret->root.table); - free (ret); -} - -/* Grab the symbols for an object file when doing a generic link. We - store the symbols in the outsymbols field. We need to keep them - around for the entire link to ensure that we only read them once. - If we read them multiple times, we might wind up with relocs and - the hash table pointing to different instances of the symbol - structure. */ - -bfd_boolean -bfd_generic_link_read_symbols (bfd *abfd) -{ - if (bfd_get_outsymbols (abfd) == NULL) - { - long symsize; - long symcount; - - symsize = bfd_get_symtab_upper_bound (abfd); - if (symsize < 0) - return FALSE; - bfd_get_outsymbols (abfd) = (struct bfd_symbol **) bfd_alloc (abfd, - symsize); - if (bfd_get_outsymbols (abfd) == NULL && symsize != 0) - return FALSE; - symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd)); - if (symcount < 0) - return FALSE; - bfd_get_symcount (abfd) = symcount; - } - - return TRUE; -} - -/* Generic function to add symbols to from an object file to the - global hash table. This version does not automatically collect - constructors by name. */ - -bfd_boolean -_bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info) -{ - return generic_link_add_symbols (abfd, info, FALSE); -} - -/* Generic function to add symbols from an object file to the global - hash table. This version automatically collects constructors by - name, as the collect2 program does. It should be used for any - target which does not provide some other mechanism for setting up - constructors and destructors; these are approximately those targets - for which gcc uses collect2 and do not support stabs. */ - -bfd_boolean -_bfd_generic_link_add_symbols_collect (bfd *abfd, struct bfd_link_info *info) -{ - return generic_link_add_symbols (abfd, info, TRUE); -} - -/* Indicate that we are only retrieving symbol values from this - section. We want the symbols to act as though the values in the - file are absolute. */ - -void -_bfd_generic_link_just_syms (asection *sec, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - sec->output_section = bfd_abs_section_ptr; - sec->output_offset = sec->vma; -} - -/* Copy the type of a symbol assiciated with a linker hast table entry. - Override this so that symbols created in linker scripts get their - type from the RHS of the assignment. - The default implementation does nothing. */ -void -_bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hdest ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry * hsrc ATTRIBUTE_UNUSED) -{ -} - -/* Add symbols from an object file to the global hash table. */ - -static bfd_boolean -generic_link_add_symbols (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean collect) -{ - bfd_boolean ret; - - switch (bfd_get_format (abfd)) - { - case bfd_object: - ret = generic_link_add_object_symbols (abfd, info, collect); - break; - case bfd_archive: - ret = (_bfd_generic_link_add_archive_symbols - (abfd, info, - (collect - ? generic_link_check_archive_element_collect - : generic_link_check_archive_element_no_collect))); - break; - default: - bfd_set_error (bfd_error_wrong_format); - ret = FALSE; - } - - return ret; -} - -/* Add symbols from an object file to the global hash table. */ - -static bfd_boolean -generic_link_add_object_symbols (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean collect) -{ - bfd_size_type symcount; - struct bfd_symbol **outsyms; - - if (!bfd_generic_link_read_symbols (abfd)) - return FALSE; - symcount = _bfd_generic_link_get_symcount (abfd); - outsyms = _bfd_generic_link_get_symbols (abfd); - return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect); -} - -/* We build a hash table of all symbols defined in an archive. */ - -/* An archive symbol may be defined by multiple archive elements. - This linked list is used to hold the elements. */ - -struct archive_list -{ - struct archive_list *next; - unsigned int indx; -}; - -/* An entry in an archive hash table. */ - -struct archive_hash_entry -{ - struct bfd_hash_entry root; - /* Where the symbol is defined. */ - struct archive_list *defs; -}; - -/* An archive hash table itself. */ - -struct archive_hash_table -{ - struct bfd_hash_table table; -}; - -/* Create a new entry for an archive hash table. */ - -static struct bfd_hash_entry * -archive_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - struct archive_hash_entry *ret = (struct archive_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = (struct archive_hash_entry *) - bfd_hash_allocate (table, sizeof (struct archive_hash_entry)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct archive_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->defs = NULL; - } - - return &ret->root; -} - -/* Initialize an archive hash table. */ - -static bfd_boolean -archive_hash_table_init - (struct archive_hash_table *table, - struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int entsize) -{ - return bfd_hash_table_init (&table->table, newfunc, entsize); -} - -/* Look up an entry in an archive hash table. */ - -#define archive_hash_lookup(t, string, create, copy) \ - ((struct archive_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Allocate space in an archive hash table. */ - -#define archive_hash_allocate(t, size) bfd_hash_allocate (&(t)->table, (size)) - -/* Free an archive hash table. */ - -#define archive_hash_table_free(t) bfd_hash_table_free (&(t)->table) - -/* Generic function to add symbols from an archive file to the global - hash file. This function presumes that the archive symbol table - has already been read in (this is normally done by the - bfd_check_format entry point). It looks through the undefined and - common symbols and searches the archive symbol table for them. If - it finds an entry, it includes the associated object file in the - link. - - The old linker looked through the archive symbol table for - undefined symbols. We do it the other way around, looking through - undefined symbols for symbols defined in the archive. The - advantage of the newer scheme is that we only have to look through - the list of undefined symbols once, whereas the old method had to - re-search the symbol table each time a new object file was added. - - The CHECKFN argument is used to see if an object file should be - included. CHECKFN should set *PNEEDED to TRUE if the object file - should be included, and must also call the bfd_link_info - add_archive_element callback function and handle adding the symbols - to the global hash table. CHECKFN must notice if the callback - indicates a substitute BFD, and arrange to add those symbols instead - if it does so. CHECKFN should only return FALSE if some sort of - error occurs. - - For some formats, such as a.out, it is possible to look through an - object file but not actually include it in the link. The - archive_pass field in a BFD is used to avoid checking the symbols - of an object files too many times. When an object is included in - the link, archive_pass is set to -1. If an object is scanned but - not included, archive_pass is set to the pass number. The pass - number is incremented each time a new object file is included. The - pass number is used because when a new object file is included it - may create new undefined symbols which cause a previously examined - object file to be included. */ - -bfd_boolean -_bfd_generic_link_add_archive_symbols - (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *, bfd_boolean *)) -{ - carsym *arsyms; - carsym *arsym_end; - register carsym *arsym; - int pass; - struct archive_hash_table arsym_hash; - unsigned int indx; - struct bfd_link_hash_entry **pundef; - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, NULL) == NULL) - return TRUE; - bfd_set_error (bfd_error_no_armap); - return FALSE; - } - - arsyms = bfd_ardata (abfd)->symdefs; - arsym_end = arsyms + bfd_ardata (abfd)->symdef_count; - - /* In order to quickly determine whether an symbol is defined in - this archive, we build a hash table of the symbols. */ - if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc, - sizeof (struct archive_hash_entry))) - return FALSE; - for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) - { - struct archive_hash_entry *arh; - struct archive_list *l, **pp; - - arh = archive_hash_lookup (&arsym_hash, arsym->name, TRUE, FALSE); - if (arh == NULL) - goto error_return; - l = ((struct archive_list *) - archive_hash_allocate (&arsym_hash, sizeof (struct archive_list))); - if (l == NULL) - goto error_return; - l->indx = indx; - for (pp = &arh->defs; *pp != NULL; pp = &(*pp)->next) - ; - *pp = l; - l->next = NULL; - } - - /* The archive_pass field in the archive itself is used to - initialize PASS, sine we may search the same archive multiple - times. */ - pass = abfd->archive_pass + 1; - - /* New undefined symbols are added to the end of the list, so we - only need to look through it once. */ - pundef = &info->hash->undefs; - while (*pundef != NULL) - { - struct bfd_link_hash_entry *h; - struct archive_hash_entry *arh; - struct archive_list *l; - - h = *pundef; - - /* When a symbol is defined, it is not necessarily removed from - the list. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - { - /* Remove this entry from the list, for general cleanliness - and because we are going to look through the list again - if we search any more libraries. We can't remove the - entry if it is the tail, because that would lose any - entries we add to the list later on (it would also cause - us to lose track of whether the symbol has been - referenced). */ - if (*pundef != info->hash->undefs_tail) - *pundef = (*pundef)->u.undef.next; - else - pundef = &(*pundef)->u.undef.next; - continue; - } - - /* Look for this symbol in the archive symbol map. */ - arh = archive_hash_lookup (&arsym_hash, h->root.string, FALSE, FALSE); - if (arh == NULL) - { - /* If we haven't found the exact symbol we're looking for, - let's look for its import thunk */ - if (info->pei386_auto_import) - { - bfd_size_type amt = strlen (h->root.string) + 10; - char *buf = (char *) bfd_malloc (amt); - if (buf == NULL) - return FALSE; - - sprintf (buf, "__imp_%s", h->root.string); - arh = archive_hash_lookup (&arsym_hash, buf, FALSE, FALSE); - free(buf); - } - if (arh == NULL) - { - pundef = &(*pundef)->u.undef.next; - continue; - } - } - /* Look at all the objects which define this symbol. */ - for (l = arh->defs; l != NULL; l = l->next) - { - bfd *element; - bfd_boolean needed; - - /* If the symbol has gotten defined along the way, quit. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - break; - - element = bfd_get_elt_at_index (abfd, l->indx); - if (element == NULL) - goto error_return; - - /* If we've already included this element, or if we've - already checked it on this pass, continue. */ - if (element->archive_pass == -1 - || element->archive_pass == pass) - continue; - - /* If we can't figure this element out, just ignore it. */ - if (! bfd_check_format (element, bfd_object)) - { - element->archive_pass = -1; - continue; - } - - /* CHECKFN will see if this element should be included, and - go ahead and include it if appropriate. */ - if (! (*checkfn) (element, info, &needed)) - goto error_return; - - if (! needed) - element->archive_pass = pass; - else - { - element->archive_pass = -1; - - /* Increment the pass count to show that we may need to - recheck object files which were already checked. */ - ++pass; - } - } - - pundef = &(*pundef)->u.undef.next; - } - - archive_hash_table_free (&arsym_hash); - - /* Save PASS in case we are called again. */ - abfd->archive_pass = pass; - - return TRUE; - - error_return: - archive_hash_table_free (&arsym_hash); - return FALSE; -} - -/* See if we should include an archive element. This version is used - when we do not want to automatically collect constructors based on - the symbol name, presumably because we have some other mechanism - for finding them. */ - -static bfd_boolean -generic_link_check_archive_element_no_collect ( - bfd *abfd, - struct bfd_link_info *info, - bfd_boolean *pneeded) -{ - return generic_link_check_archive_element (abfd, info, pneeded, FALSE); -} - -/* See if we should include an archive element. This version is used - when we want to automatically collect constructors based on the - symbol name, as collect2 does. */ - -static bfd_boolean -generic_link_check_archive_element_collect (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean *pneeded) -{ - return generic_link_check_archive_element (abfd, info, pneeded, TRUE); -} - -/* See if we should include an archive element. Optionally collect - constructors. */ - -static bfd_boolean -generic_link_check_archive_element (bfd *abfd, - struct bfd_link_info *info, - bfd_boolean *pneeded, - bfd_boolean collect) -{ - asymbol **pp, **ppend; - - *pneeded = FALSE; - - if (!bfd_generic_link_read_symbols (abfd)) - return FALSE; - - pp = _bfd_generic_link_get_symbols (abfd); - ppend = pp + _bfd_generic_link_get_symcount (abfd); - for (; pp < ppend; pp++) - { - asymbol *p; - struct bfd_link_hash_entry *h; - - p = *pp; - - /* We are only interested in globally visible symbols. */ - if (! bfd_is_com_section (p->section) - && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0) - continue; - - /* We are only interested if we know something about this - symbol, and it is undefined or common. An undefined weak - symbol (type bfd_link_hash_undefweak) is not considered to be - a reference when pulling files out of an archive. See the - SVR4 ABI, p. 4-27. */ - h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), FALSE, - FALSE, TRUE); - if (h == NULL - || (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common)) - continue; - - /* P is a symbol we are looking for. */ - - if (! bfd_is_com_section (p->section)) - { - bfd_size_type symcount; - asymbol **symbols; - bfd *oldbfd = abfd; - - /* This object file defines this symbol, so pull it in. */ - if (!(*info->callbacks - ->add_archive_element) (info, abfd, bfd_asymbol_name (p), - &abfd)) - return FALSE; - /* Potentially, the add_archive_element hook may have set a - substitute BFD for us. */ - if (abfd != oldbfd - && !bfd_generic_link_read_symbols (abfd)) - return FALSE; - symcount = _bfd_generic_link_get_symcount (abfd); - symbols = _bfd_generic_link_get_symbols (abfd); - if (! generic_link_add_symbol_list (abfd, info, symcount, - symbols, collect)) - return FALSE; - *pneeded = TRUE; - return TRUE; - } - - /* P is a common symbol. */ - - if (h->type == bfd_link_hash_undefined) - { - bfd *symbfd; - bfd_vma size; - unsigned int power; - - symbfd = h->u.undef.abfd; - if (symbfd == NULL) - { - /* This symbol was created as undefined from outside - BFD. We assume that we should link in the object - file. This is for the -u option in the linker. */ - if (!(*info->callbacks - ->add_archive_element) (info, abfd, bfd_asymbol_name (p), - &abfd)) - return FALSE; - /* Potentially, the add_archive_element hook may have set a - substitute BFD for us. But no symbols are going to get - registered by anything we're returning to from here. */ - *pneeded = TRUE; - return TRUE; - } - - /* Turn the symbol into a common symbol but do not link in - the object file. This is how a.out works. Object - formats that require different semantics must implement - this function differently. This symbol is already on the - undefs list. We add the section to a common section - attached to symbfd to ensure that it is in a BFD which - will be linked in. */ - h->type = bfd_link_hash_common; - h->u.c.p = (struct bfd_link_hash_common_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_common_entry)); - if (h->u.c.p == NULL) - return FALSE; - - size = bfd_asymbol_value (p); - h->u.c.size = size; - - power = bfd_log2 (size); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - - if (p->section == bfd_com_section_ptr) - h->u.c.p->section = bfd_make_section_old_way (symbfd, "COMMON"); - else - h->u.c.p->section = bfd_make_section_old_way (symbfd, - p->section->name); - h->u.c.p->section->flags |= SEC_ALLOC; - } - else - { - /* Adjust the size of the common symbol if necessary. This - is how a.out works. Object formats that require - different semantics must implement this function - differently. */ - if (bfd_asymbol_value (p) > h->u.c.size) - h->u.c.size = bfd_asymbol_value (p); - } - } - - /* This archive element is not needed. */ - return TRUE; -} - -/* Add the symbols from an object file to the global hash table. ABFD - is the object file. INFO is the linker information. SYMBOL_COUNT - is the number of symbols. SYMBOLS is the list of symbols. COLLECT - is TRUE if constructors should be automatically collected by name - as is done by collect2. */ - -static bfd_boolean -generic_link_add_symbol_list (bfd *abfd, - struct bfd_link_info *info, - bfd_size_type symbol_count, - asymbol **symbols, - bfd_boolean collect) -{ - asymbol **pp, **ppend; - - pp = symbols; - ppend = symbols + symbol_count; - for (; pp < ppend; pp++) - { - asymbol *p; - - p = *pp; - - if ((p->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (p)) - || bfd_is_com_section (bfd_get_section (p)) - || bfd_is_ind_section (bfd_get_section (p))) - { - const char *name; - const char *string; - struct generic_link_hash_entry *h; - struct bfd_link_hash_entry *bh; - - string = name = bfd_asymbol_name (p); - if (((p->flags & BSF_INDIRECT) != 0 - || bfd_is_ind_section (p->section)) - && pp + 1 < ppend) - { - pp++; - string = bfd_asymbol_name (*pp); - } - else if ((p->flags & BSF_WARNING) != 0 - && pp + 1 < ppend) - { - /* The name of P is actually the warning string, and the - next symbol is the one to warn about. */ - pp++; - name = bfd_asymbol_name (*pp); - } - - bh = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, p->flags, bfd_get_section (p), - p->value, string, FALSE, collect, &bh))) - return FALSE; - h = (struct generic_link_hash_entry *) bh; - - /* If this is a constructor symbol, and the linker didn't do - anything with it, then we want to just pass the symbol - through to the output file. This will happen when - linking with -r. */ - if ((p->flags & BSF_CONSTRUCTOR) != 0 - && (h == NULL || h->root.type == bfd_link_hash_new)) - { - p->udata.p = NULL; - continue; - } - - /* Save the BFD symbol so that we don't lose any backend - specific information that may be attached to it. We only - want this one if it gives more information than the - existing one; we don't want to replace a defined symbol - with an undefined one. This routine may be called with a - hash table other than the generic hash table, so we only - do this if we are certain that the hash table is a - generic one. */ - if (info->output_bfd->xvec == abfd->xvec) - { - if (h->sym == NULL - || (! bfd_is_und_section (bfd_get_section (p)) - && (! bfd_is_com_section (bfd_get_section (p)) - || bfd_is_und_section (bfd_get_section (h->sym))))) - { - h->sym = p; - /* BSF_OLD_COMMON is a hack to support COFF reloc - reading, and it should go away when the COFF - linker is switched to the new version. */ - if (bfd_is_com_section (bfd_get_section (p))) - p->flags |= BSF_OLD_COMMON; - } - } - - /* Store a back pointer from the symbol to the hash - table entry for the benefit of relaxation code until - it gets rewritten to not use asymbol structures. - Setting this is also used to check whether these - symbols were set up by the generic linker. */ - p->udata.p = h; - } - } - - return TRUE; -} - -/* We use a state table to deal with adding symbols from an object - file. The first index into the state table describes the symbol - from the object file. The second index into the state table is the - type of the symbol in the hash table. */ - -/* The symbol from the object file is turned into one of these row - values. */ - -enum link_row -{ - UNDEF_ROW, /* Undefined. */ - UNDEFW_ROW, /* Weak undefined. */ - DEF_ROW, /* Defined. */ - DEFW_ROW, /* Weak defined. */ - COMMON_ROW, /* Common. */ - INDR_ROW, /* Indirect. */ - WARN_ROW, /* Warning. */ - SET_ROW /* Member of set. */ -}; - -/* apparently needed for Hitachi 3050R(HI-UX/WE2)? */ -#undef FAIL - -/* The actions to take in the state table. */ - -enum link_action -{ - FAIL, /* Abort. */ - UND, /* Mark symbol undefined. */ - WEAK, /* Mark symbol weak undefined. */ - DEF, /* Mark symbol defined. */ - DEFW, /* Mark symbol weak defined. */ - COM, /* Mark symbol common. */ - REF, /* Mark defined symbol referenced. */ - CREF, /* Possibly warn about common reference to defined symbol. */ - CDEF, /* Define existing common symbol. */ - NOACT, /* No action. */ - BIG, /* Mark symbol common using largest size. */ - MDEF, /* Multiple definition error. */ - MIND, /* Multiple indirect symbols. */ - IND, /* Make indirect symbol. */ - CIND, /* Make indirect symbol from existing common symbol. */ - SET, /* Add value to set. */ - MWARN, /* Make warning symbol. */ - WARN, /* Issue warning. */ - CWARN, /* Warn if referenced, else MWARN. */ - CYCLE, /* Repeat with symbol pointed to. */ - REFC, /* Mark indirect symbol referenced and then CYCLE. */ - WARNC /* Issue warning and then CYCLE. */ -}; - -/* The state table itself. The first index is a link_row and the - second index is a bfd_link_hash_type. */ - -static const enum link_action link_action[8][8] = -{ - /* current\prev new undef undefw def defw com indr warn */ - /* UNDEF_ROW */ {UND, NOACT, UND, REF, REF, NOACT, REFC, WARNC }, - /* UNDEFW_ROW */ {WEAK, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC }, - /* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE }, - /* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE }, - /* COMMON_ROW */ {COM, COM, COM, CREF, COM, BIG, REFC, WARNC }, - /* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE }, - /* WARN_ROW */ {MWARN, WARN, WARN, CWARN, CWARN, WARN, CWARN, NOACT }, - /* SET_ROW */ {SET, SET, SET, SET, SET, SET, CYCLE, CYCLE } -}; - -/* Most of the entries in the LINK_ACTION table are straightforward, - but a few are somewhat subtle. - - A reference to an indirect symbol (UNDEF_ROW/indr or - UNDEFW_ROW/indr) is counted as a reference both to the indirect - symbol and to the symbol the indirect symbol points to. - - A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn) - causes the warning to be issued. - - A common definition of an indirect symbol (COMMON_ROW/indr) is - treated as a multiple definition error. Likewise for an indirect - definition of a common symbol (INDR_ROW/com). - - An indirect definition of a warning (INDR_ROW/warn) does not cause - the warning to be issued. - - If a warning is created for an indirect symbol (WARN_ROW/indr) no - warning is created for the symbol the indirect symbol points to. - - Adding an entry to a set does not count as a reference to a set, - and no warning is issued (SET_ROW/warn). */ - -/* Return the BFD in which a hash entry has been defined, if known. */ - -static bfd * -hash_entry_bfd (struct bfd_link_hash_entry *h) -{ - while (h->type == bfd_link_hash_warning) - h = h->u.i.link; - switch (h->type) - { - default: - return NULL; - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - return h->u.undef.abfd; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->u.def.section->owner; - case bfd_link_hash_common: - return h->u.c.p->section->owner; - } - /*NOTREACHED*/ -} - -/* Add a symbol to the global hash table. - ABFD is the BFD the symbol comes from. - NAME is the name of the symbol. - FLAGS is the BSF_* bits associated with the symbol. - SECTION is the section in which the symbol is defined; this may be - bfd_und_section_ptr or bfd_com_section_ptr. - VALUE is the value of the symbol, relative to the section. - STRING is used for either an indirect symbol, in which case it is - the name of the symbol to indirect to, or a warning symbol, in - which case it is the warning string. - COPY is TRUE if NAME or STRING must be copied into locally - allocated memory if they need to be saved. - COLLECT is TRUE if we should automatically collect gcc constructor - or destructor names as collect2 does. - HASHP, if not NULL, is a place to store the created hash table - entry; if *HASHP is not NULL, the caller has already looked up - the hash table entry, and stored it in *HASHP. */ - -bfd_boolean -_bfd_generic_link_add_one_symbol (struct bfd_link_info *info, - bfd *abfd, - const char *name, - flagword flags, - asection *section, - bfd_vma value, - const char *string, - bfd_boolean copy, - bfd_boolean collect, - struct bfd_link_hash_entry **hashp) -{ - enum link_row row; - struct bfd_link_hash_entry *h; - bfd_boolean cycle; - - BFD_ASSERT (section != NULL); - - if (bfd_is_ind_section (section) - || (flags & BSF_INDIRECT) != 0) - row = INDR_ROW; - else if ((flags & BSF_WARNING) != 0) - row = WARN_ROW; - else if ((flags & BSF_CONSTRUCTOR) != 0) - row = SET_ROW; - else if (bfd_is_und_section (section)) - { - if ((flags & BSF_WEAK) != 0) - row = UNDEFW_ROW; - else - row = UNDEF_ROW; - } - else if ((flags & BSF_WEAK) != 0) - row = DEFW_ROW; - else if (bfd_is_com_section (section)) - row = COMMON_ROW; - else - row = DEF_ROW; - - if (hashp != NULL && *hashp != NULL) - h = *hashp; - else - { - if (row == UNDEF_ROW || row == UNDEFW_ROW) - h = bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE); - else - h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE); - if (h == NULL) - { - if (hashp != NULL) - *hashp = NULL; - return FALSE; - } - } - - if (info->notice_all - || (info->notice_hash != NULL - && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)) - { - if (! (*info->callbacks->notice) (info, h, - abfd, section, value, flags, string)) - return FALSE; - } - - if (hashp != NULL) - *hashp = h; - - do - { - enum link_action action; - - cycle = FALSE; - action = link_action[(int) row][(int) h->type]; - switch (action) - { - case FAIL: - abort (); - - case NOACT: - /* Do nothing. */ - break; - - case UND: - /* Make a new undefined symbol. */ - h->type = bfd_link_hash_undefined; - h->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, h); - break; - - case WEAK: - /* Make a new weak undefined symbol. */ - h->type = bfd_link_hash_undefweak; - h->u.undef.abfd = abfd; - break; - - case CDEF: - /* We have found a definition for a symbol which was - previously common. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, h, abfd, bfd_link_hash_defined, 0))) - return FALSE; - /* Fall through. */ - case DEF: - case DEFW: - { - enum bfd_link_hash_type oldtype; - - /* Define a symbol. */ - oldtype = h->type; - if (action == DEFW) - h->type = bfd_link_hash_defweak; - else - h->type = bfd_link_hash_defined; - h->u.def.section = section; - h->u.def.value = value; - - /* If we have been asked to, we act like collect2 and - identify all functions that might be global - constructors and destructors and pass them up in a - callback. We only do this for certain object file - types, since many object file types can handle this - automatically. */ - if (collect && name[0] == '_') - { - const char *s; - - /* A constructor or destructor name starts like this: - _+GLOBAL_[_.$][ID][_.$] where the first [_.$] and - the second are the same character (we accept any - character there, in case a new object file format - comes along with even worse naming restrictions). */ - -#define CONS_PREFIX "GLOBAL_" -#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1) - - s = name + 1; - while (*s == '_') - ++s; - if (s[0] == 'G' && CONST_STRNEQ (s, CONS_PREFIX)) - { - char c; - - c = s[CONS_PREFIX_LEN + 1]; - if ((c == 'I' || c == 'D') - && s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2]) - { - /* If this is a definition of a symbol which - was previously weakly defined, we are in - trouble. We have already added a - constructor entry for the weak defined - symbol, and now we are trying to add one - for the new symbol. Fortunately, this case - should never arise in practice. */ - if (oldtype == bfd_link_hash_defweak) - abort (); - - if (! ((*info->callbacks->constructor) - (info, c == 'I', - h->root.string, abfd, section, value))) - return FALSE; - } - } - } - } - - break; - - case COM: - /* We have found a common definition for a symbol. */ - if (h->type == bfd_link_hash_new) - bfd_link_add_undef (info->hash, h); - h->type = bfd_link_hash_common; - h->u.c.p = (struct bfd_link_hash_common_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_common_entry)); - if (h->u.c.p == NULL) - return FALSE; - - h->u.c.size = value; - - /* Select a default alignment based on the size. This may - be overridden by the caller. */ - { - unsigned int power; - - power = bfd_log2 (value); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - } - - /* The section of a common symbol is only used if the common - symbol is actually allocated. It basically provides a - hook for the linker script to decide which output section - the common symbols should be put in. In most cases, the - section of a common symbol will be bfd_com_section_ptr, - the code here will choose a common symbol section named - "COMMON", and the linker script will contain *(COMMON) in - the appropriate place. A few targets use separate common - sections for small symbols, and they require special - handling. */ - if (section == bfd_com_section_ptr) - { - h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.p->section->flags |= SEC_ALLOC; - } - else if (section->owner != abfd) - { - h->u.c.p->section = bfd_make_section_old_way (abfd, - section->name); - h->u.c.p->section->flags |= SEC_ALLOC; - } - else - h->u.c.p->section = section; - break; - - case REF: - /* A reference to a defined symbol. */ - if (h->u.undef.next == NULL && info->hash->undefs_tail != h) - h->u.undef.next = h; - break; - - case BIG: - /* We have found a common definition for a symbol which - already had a common definition. Use the maximum of the - two sizes, and use the section required by the larger symbol. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, h, abfd, bfd_link_hash_common, value))) - return FALSE; - if (value > h->u.c.size) - { - unsigned int power; - - h->u.c.size = value; - - /* Select a default alignment based on the size. This may - be overridden by the caller. */ - power = bfd_log2 (value); - if (power > 4) - power = 4; - h->u.c.p->alignment_power = power; - - /* Some systems have special treatment for small commons, - hence we want to select the section used by the larger - symbol. This makes sure the symbol does not go in a - small common section if it is now too large. */ - if (section == bfd_com_section_ptr) - { - h->u.c.p->section - = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.p->section->flags |= SEC_ALLOC; - } - else if (section->owner != abfd) - { - h->u.c.p->section - = bfd_make_section_old_way (abfd, section->name); - h->u.c.p->section->flags |= SEC_ALLOC; - } - else - h->u.c.p->section = section; - } - break; - - case CREF: - /* We have found a common definition for a symbol which - was already defined. */ - if (! ((*info->callbacks->multiple_common) - (info, h, abfd, bfd_link_hash_common, value))) - return FALSE; - break; - - case MIND: - /* Multiple indirect symbols. This is OK if they both point - to the same symbol. */ - if (strcmp (h->u.i.link->root.string, string) == 0) - break; - /* Fall through. */ - case MDEF: - /* Handle a multiple definition. */ - if (! ((*info->callbacks->multiple_definition) - (info, h, abfd, section, value))) - return FALSE; - break; - - case CIND: - /* Create an indirect symbol from an existing common symbol. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, h, abfd, bfd_link_hash_indirect, 0))) - return FALSE; - /* Fall through. */ - case IND: - /* Create an indirect symbol. */ - { - struct bfd_link_hash_entry *inh; - - /* STRING is the name of the symbol we want to indirect - to. */ - inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE, - copy, FALSE); - if (inh == NULL) - return FALSE; - if (inh->type == bfd_link_hash_indirect - && inh->u.i.link == h) - { - (*_bfd_error_handler) - (_("%B: indirect symbol `%s' to `%s' is a loop"), - abfd, name, string); - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - if (inh->type == bfd_link_hash_new) - { - inh->type = bfd_link_hash_undefined; - inh->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, inh); - } - - /* If the indirect symbol has been referenced, we need to - push the reference down to the symbol we are - referencing. */ - if (h->type != bfd_link_hash_new) - { - row = UNDEF_ROW; - cycle = TRUE; - } - - h->type = bfd_link_hash_indirect; - h->u.i.link = inh; - } - break; - - case SET: - /* Add an entry to a set. */ - if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, - abfd, section, value)) - return FALSE; - break; - - case WARNC: - /* Issue a warning and cycle. */ - if (h->u.i.warning != NULL) - { - if (! (*info->callbacks->warning) (info, h->u.i.warning, - h->root.string, abfd, - NULL, 0)) - return FALSE; - /* Only issue a warning once. */ - h->u.i.warning = NULL; - } - /* Fall through. */ - case CYCLE: - /* Try again with the referenced symbol. */ - h = h->u.i.link; - cycle = TRUE; - break; - - case REFC: - /* A reference to an indirect symbol. */ - if (h->u.undef.next == NULL && info->hash->undefs_tail != h) - h->u.undef.next = h; - h = h->u.i.link; - cycle = TRUE; - break; - - case WARN: - /* Issue a warning. */ - if (! (*info->callbacks->warning) (info, string, h->root.string, - hash_entry_bfd (h), NULL, 0)) - return FALSE; - break; - - case CWARN: - /* Warn if this symbol has been referenced already, - otherwise add a warning. A symbol has been referenced if - the u.undef.next field is not NULL, or it is the tail of the - undefined symbol list. The REF case above helps to - ensure this. */ - if (h->u.undef.next != NULL || info->hash->undefs_tail == h) - { - if (! (*info->callbacks->warning) (info, string, h->root.string, - hash_entry_bfd (h), NULL, 0)) - return FALSE; - break; - } - /* Fall through. */ - case MWARN: - /* Make a warning symbol. */ - { - struct bfd_link_hash_entry *sub; - - /* STRING is the warning to give. */ - sub = ((struct bfd_link_hash_entry *) - ((*info->hash->table.newfunc) - (NULL, &info->hash->table, h->root.string))); - if (sub == NULL) - return FALSE; - *sub = *h; - sub->type = bfd_link_hash_warning; - sub->u.i.link = h; - if (! copy) - sub->u.i.warning = string; - else - { - char *w; - size_t len = strlen (string) + 1; - - w = (char *) bfd_hash_allocate (&info->hash->table, len); - if (w == NULL) - return FALSE; - memcpy (w, string, len); - sub->u.i.warning = w; - } - - bfd_hash_replace (&info->hash->table, - (struct bfd_hash_entry *) h, - (struct bfd_hash_entry *) sub); - if (hashp != NULL) - *hashp = sub; - } - break; - } - } - while (cycle); - - return TRUE; -} - -/* Generic final link routine. */ - -bfd_boolean -_bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) -{ - bfd *sub; - asection *o; - struct bfd_link_order *p; - size_t outsymalloc; - struct generic_write_global_symbol_info wginfo; - - bfd_get_outsymbols (abfd) = NULL; - bfd_get_symcount (abfd) = 0; - outsymalloc = 0; - - /* Mark all sections which will be included in the output file. */ - for (o = abfd->sections; o != NULL; o = o->next) - for (p = o->map_head.link_order; p != NULL; p = p->next) - if (p->type == bfd_indirect_link_order) - p->u.indirect.section->linker_mark = TRUE; - - /* Build the output symbol table. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) - return FALSE; - - /* Accumulate the global symbols. */ - wginfo.info = info; - wginfo.output_bfd = abfd; - wginfo.psymalloc = &outsymalloc; - _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), - _bfd_generic_link_write_global_symbol, - &wginfo); - - /* Make sure we have a trailing NULL pointer on OUTSYMBOLS. We - shouldn't really need one, since we have SYMCOUNT, but some old - code still expects one. */ - if (! generic_add_output_symbol (abfd, &outsymalloc, NULL)) - return FALSE; - - if (info->relocatable) - { - /* Allocate space for the output relocs for each section. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *input_section; - bfd *input_bfd; - long relsize; - arelent **relocs; - asymbol **symbols; - long reloc_count; - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - relsize = bfd_get_reloc_upper_bound (input_bfd, - input_section); - if (relsize < 0) - return FALSE; - relocs = (arelent **) bfd_malloc (relsize); - if (!relocs && relsize != 0) - return FALSE; - symbols = _bfd_generic_link_get_symbols (input_bfd); - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - relocs, - symbols); - free (relocs); - if (reloc_count < 0) - return FALSE; - BFD_ASSERT ((unsigned long) reloc_count - == input_section->reloc_count); - o->reloc_count += reloc_count; - } - } - if (o->reloc_count > 0) - { - bfd_size_type amt; - - amt = o->reloc_count; - amt *= sizeof (arelent *); - o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt); - if (!o->orelocation) - return FALSE; - o->flags |= SEC_RELOC; - /* Reset the count so that it can be used as an index - when putting in the output relocs. */ - o->reloc_count = 0; - } - } - } - - /* Handle all the link order information for the sections. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->map_head.link_order; p != NULL; p = p->next) - { - switch (p->type) - { - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) - return FALSE; - break; - case bfd_indirect_link_order: - if (! default_indirect_link_order (abfd, info, o, p, TRUE)) - return FALSE; - break; - default: - if (! _bfd_default_link_order (abfd, info, o, p)) - return FALSE; - break; - } - } - } - - return TRUE; -} - -/* Add an output symbol to the output BFD. */ - -static bfd_boolean -generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym) -{ - if (bfd_get_symcount (output_bfd) >= *psymalloc) - { - asymbol **newsyms; - bfd_size_type amt; - - if (*psymalloc == 0) - *psymalloc = 124; - else - *psymalloc *= 2; - amt = *psymalloc; - amt *= sizeof (asymbol *); - newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt); - if (newsyms == NULL) - return FALSE; - bfd_get_outsymbols (output_bfd) = newsyms; - } - - bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym; - if (sym != NULL) - ++ bfd_get_symcount (output_bfd); - - return TRUE; -} - -/* Handle the symbols for an input BFD. */ - -bfd_boolean -_bfd_generic_link_output_symbols (bfd *output_bfd, - bfd *input_bfd, - struct bfd_link_info *info, - size_t *psymalloc) -{ - asymbol **sym_ptr; - asymbol **sym_end; - - if (!bfd_generic_link_read_symbols (input_bfd)) - return FALSE; - - /* Create a filename symbol if we are supposed to. */ - if (info->create_object_symbols_section != NULL) - { - asection *sec; - - for (sec = input_bfd->sections; sec != NULL; sec = sec->next) - { - if (sec->output_section == info->create_object_symbols_section) - { - asymbol *newsym; - - newsym = bfd_make_empty_symbol (input_bfd); - if (!newsym) - return FALSE; - newsym->name = input_bfd->filename; - newsym->value = 0; - newsym->flags = BSF_LOCAL | BSF_FILE; - newsym->section = sec; - - if (! generic_add_output_symbol (output_bfd, psymalloc, - newsym)) - return FALSE; - - break; - } - } - } - - /* Adjust the values of the globally visible symbols, and write out - local symbols. */ - sym_ptr = _bfd_generic_link_get_symbols (input_bfd); - sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd); - for (; sym_ptr < sym_end; sym_ptr++) - { - asymbol *sym; - struct generic_link_hash_entry *h; - bfd_boolean output; - - h = NULL; - sym = *sym_ptr; - if ((sym->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) - { - if (sym->udata.p != NULL) - h = (struct generic_link_hash_entry *) sym->udata.p; - else if ((sym->flags & BSF_CONSTRUCTOR) != 0) - { - /* This case normally means that the main linker code - deliberately ignored this constructor symbol. We - should just pass it through. This will screw up if - the constructor symbol is from a different, - non-generic, object file format, but the case will - only arise when linking with -r, which will probably - fail anyhow, since there will be no way to represent - the relocs in the output format being used. */ - h = NULL; - } - else if (bfd_is_und_section (bfd_get_section (sym))) - h = ((struct generic_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - bfd_asymbol_name (sym), - FALSE, FALSE, TRUE)); - else - h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), - bfd_asymbol_name (sym), - FALSE, FALSE, TRUE); - - if (h != NULL) - { - /* Force all references to this symbol to point to - the same area in memory. It is possible that - this routine will be called with a hash table - other than a generic hash table, so we double - check that. */ - if (info->output_bfd->xvec == input_bfd->xvec) - { - if (h->sym != NULL) - *sym_ptr = sym = h->sym; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - break; - case bfd_link_hash_undefweak: - sym->flags |= BSF_WEAK; - break; - case bfd_link_hash_indirect: - h = (struct generic_link_hash_entry *) h->root.u.i.link; - /* fall through */ - case bfd_link_hash_defined: - sym->flags |= BSF_GLOBAL; - sym->flags &=~ BSF_CONSTRUCTOR; - sym->value = h->root.u.def.value; - sym->section = h->root.u.def.section; - break; - case bfd_link_hash_defweak: - sym->flags |= BSF_WEAK; - sym->flags &=~ BSF_CONSTRUCTOR; - sym->value = h->root.u.def.value; - sym->section = h->root.u.def.section; - break; - case bfd_link_hash_common: - sym->value = h->root.u.c.size; - sym->flags |= BSF_GLOBAL; - if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* We do not set the section of the symbol to - h->root.u.c.p->section. That value was saved so - that we would know where to allocate the symbol - if it was defined. In this case the type is - still bfd_link_hash_common, so we did not define - it, so we do not want to use that section. */ - break; - } - } - } - - /* This switch is straight from the old code in - write_file_locals in ldsym.c. */ - if (info->strip == strip_all - || (info->strip == strip_some - && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), - FALSE, FALSE) == NULL)) - output = FALSE; - else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0) - { - /* If this symbol is marked as occurring now, rather - than at the end, output it now. This is used for - COFF C_EXT FCN symbols. FIXME: There must be a - better way. */ - if (bfd_asymbol_bfd (sym) == input_bfd - && (sym->flags & BSF_NOT_AT_END) != 0) - output = TRUE; - else - output = FALSE; - } - else if (bfd_is_ind_section (sym->section)) - output = FALSE; - else if ((sym->flags & BSF_DEBUGGING) != 0) - { - if (info->strip == strip_none) - output = TRUE; - else - output = FALSE; - } - else if (bfd_is_und_section (sym->section) - || bfd_is_com_section (sym->section)) - output = FALSE; - else if ((sym->flags & BSF_LOCAL) != 0) - { - if ((sym->flags & BSF_WARNING) != 0) - output = FALSE; - else - { - switch (info->discard) - { - default: - case discard_all: - output = FALSE; - break; - case discard_sec_merge: - output = TRUE; - if (info->relocatable - || ! (sym->section->flags & SEC_MERGE)) - break; - /* FALLTHROUGH */ - case discard_l: - if (bfd_is_local_label (input_bfd, sym)) - output = FALSE; - else - output = TRUE; - break; - case discard_none: - output = TRUE; - break; - } - } - } - else if ((sym->flags & BSF_CONSTRUCTOR)) - { - if (info->strip != strip_all) - output = TRUE; - else - output = FALSE; - } - else - abort (); - - /* If this symbol is in a section which is not being included - in the output file, then we don't want to output the - symbol. */ - if (!bfd_is_abs_section (sym->section) - && bfd_section_removed_from_list (output_bfd, - sym->section->output_section)) - output = FALSE; - - if (output) - { - if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) - return FALSE; - if (h != NULL) - h->written = TRUE; - } - } - - return TRUE; -} - -/* Set the section and value of a generic BFD symbol based on a linker - hash table entry. */ - -static void -set_symbol_from_hash (asymbol *sym, struct bfd_link_hash_entry *h) -{ - switch (h->type) - { - default: - abort (); - break; - case bfd_link_hash_new: - /* This can happen when a constructor symbol is seen but we are - not building constructors. */ - if (sym->section != NULL) - { - BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0); - } - else - { - sym->flags |= BSF_CONSTRUCTOR; - sym->section = bfd_abs_section_ptr; - sym->value = 0; - } - break; - case bfd_link_hash_undefined: - sym->section = bfd_und_section_ptr; - sym->value = 0; - break; - case bfd_link_hash_undefweak: - sym->section = bfd_und_section_ptr; - sym->value = 0; - sym->flags |= BSF_WEAK; - break; - case bfd_link_hash_defined: - sym->section = h->u.def.section; - sym->value = h->u.def.value; - break; - case bfd_link_hash_defweak: - sym->flags |= BSF_WEAK; - sym->section = h->u.def.section; - sym->value = h->u.def.value; - break; - case bfd_link_hash_common: - sym->value = h->u.c.size; - if (sym->section == NULL) - sym->section = bfd_com_section_ptr; - else if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* Do not set the section; see _bfd_generic_link_output_symbols. */ - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: What should we do here? */ - break; - } -} - -/* Write out a global symbol, if it hasn't already been written out. - This is called for each symbol in the hash table. */ - -bfd_boolean -_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h, - void *data) -{ - struct generic_write_global_symbol_info *wginfo = - (struct generic_write_global_symbol_info *) data; - asymbol *sym; - - if (h->written) - return TRUE; - - h->written = TRUE; - - if (wginfo->info->strip == strip_all - || (wginfo->info->strip == strip_some - && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, - FALSE, FALSE) == NULL)) - return TRUE; - - if (h->sym != NULL) - sym = h->sym; - else - { - sym = bfd_make_empty_symbol (wginfo->output_bfd); - if (!sym) - return FALSE; - sym->name = h->root.root.string; - sym->flags = 0; - } - - set_symbol_from_hash (sym, &h->root); - - sym->flags |= BSF_GLOBAL; - - if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc, - sym)) - { - /* FIXME: No way to return failure. */ - abort (); - } - - return TRUE; -} - -/* Create a relocation. */ - -bfd_boolean -_bfd_generic_reloc_link_order (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - struct bfd_link_order *link_order) -{ - arelent *r; - - if (! info->relocatable) - abort (); - if (sec->orelocation == NULL) - abort (); - - r = (arelent *) bfd_alloc (abfd, sizeof (arelent)); - if (r == NULL) - return FALSE; - - r->address = link_order->offset; - r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); - if (r->howto == 0) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - /* Get the symbol to use for the relocation. */ - if (link_order->type == bfd_section_reloc_link_order) - r->sym_ptr_ptr = link_order->u.reloc.p->u.section->symbol_ptr_ptr; - else - { - struct generic_link_hash_entry *h; - - h = ((struct generic_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, - link_order->u.reloc.p->u.name, - FALSE, FALSE, TRUE)); - if (h == NULL - || ! h->written) - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) - return FALSE; - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - r->sym_ptr_ptr = &h->sym; - } - - /* If this is an inplace reloc, write the addend to the object file. - Otherwise, store it in the reloc addend. */ - if (! r->howto->partial_inplace) - r->addend = link_order->u.reloc.p->addend; - else - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - bfd_boolean ok; - file_ptr loc; - - size = bfd_get_reloc_size (r->howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return FALSE; - rstat = _bfd_relocate_contents (r->howto, abfd, - (bfd_vma) link_order->u.reloc.p->addend, - buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, NULL, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (abfd, link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - r->howto->name, link_order->u.reloc.p->addend, - NULL, NULL, 0))) - { - free (buf); - return FALSE; - } - break; - } - loc = link_order->offset * bfd_octets_per_byte (abfd); - ok = bfd_set_section_contents (abfd, sec, buf, loc, size); - free (buf); - if (! ok) - return FALSE; - - r->addend = 0; - } - - sec->orelocation[sec->reloc_count] = r; - ++sec->reloc_count; - - return TRUE; -} - -/* Allocate a new link_order for a section. */ - -struct bfd_link_order * -bfd_new_link_order (bfd *abfd, asection *section) -{ - bfd_size_type amt = sizeof (struct bfd_link_order); - struct bfd_link_order *new_lo; - - new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt); - if (!new_lo) - return NULL; - - new_lo->type = bfd_undefined_link_order; - - if (section->map_tail.link_order != NULL) - section->map_tail.link_order->next = new_lo; - else - section->map_head.link_order = new_lo; - section->map_tail.link_order = new_lo; - - return new_lo; -} - -/* Default link order processing routine. Note that we can not handle - the reloc_link_order types here, since they depend upon the details - of how the particular backends generates relocs. */ - -bfd_boolean -_bfd_default_link_order (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - struct bfd_link_order *link_order) -{ - switch (link_order->type) - { - case bfd_undefined_link_order: - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - default: - abort (); - case bfd_indirect_link_order: - return default_indirect_link_order (abfd, info, sec, link_order, - FALSE); - case bfd_data_link_order: - return default_data_link_order (abfd, info, sec, link_order); - } -} - -/* Default routine to handle a bfd_data_link_order. */ - -static bfd_boolean -default_data_link_order (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - asection *sec, - struct bfd_link_order *link_order) -{ - bfd_size_type size; - size_t fill_size; - bfd_byte *fill; - file_ptr loc; - bfd_boolean result; - - BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); - - size = link_order->size; - if (size == 0) - return TRUE; - - fill = link_order->u.data.contents; - fill_size = link_order->u.data.size; - if (fill_size != 0 && fill_size < size) - { - bfd_byte *p; - fill = (bfd_byte *) bfd_malloc (size); - if (fill == NULL) - return FALSE; - p = fill; - if (fill_size == 1) - memset (p, (int) link_order->u.data.contents[0], (size_t) size); - else - { - do - { - memcpy (p, link_order->u.data.contents, fill_size); - p += fill_size; - size -= fill_size; - } - while (size >= fill_size); - if (size != 0) - memcpy (p, link_order->u.data.contents, (size_t) size); - size = link_order->size; - } - } - - loc = link_order->offset * bfd_octets_per_byte (abfd); - result = bfd_set_section_contents (abfd, sec, fill, loc, size); - - if (fill != link_order->u.data.contents) - free (fill); - return result; -} - -/* Default routine to handle a bfd_indirect_link_order. */ - -static bfd_boolean -default_indirect_link_order (bfd *output_bfd, - struct bfd_link_info *info, - asection *output_section, - struct bfd_link_order *link_order, - bfd_boolean generic_linker) -{ - asection *input_section; - bfd *input_bfd; - bfd_byte *contents = NULL; - bfd_byte *new_contents; - bfd_size_type sec_size; - file_ptr loc; - - BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); - - input_section = link_order->u.indirect.section; - input_bfd = input_section->owner; - if (input_section->size == 0) - return TRUE; - - BFD_ASSERT (input_section->output_section == output_section); - BFD_ASSERT (input_section->output_offset == link_order->offset); - BFD_ASSERT (input_section->size == link_order->size); - - if (info->relocatable - && input_section->reloc_count > 0 - && output_section->orelocation == NULL) - { - /* Space has not been allocated for the output relocations. - This can happen when we are called by a specific backend - because somebody is attempting to link together different - types of object files. Handling this case correctly is - difficult, and sometimes impossible. */ - (*_bfd_error_handler) - (_("Attempt to do relocatable link with %s input and %s output"), - bfd_get_target (input_bfd), bfd_get_target (output_bfd)); - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - if (! generic_linker) - { - asymbol **sympp; - asymbol **symppend; - - /* Get the canonical symbols. The generic linker will always - have retrieved them by this point, but we are being called by - a specific linker, presumably because we are linking - different types of object files together. */ - if (!bfd_generic_link_read_symbols (input_bfd)) - return FALSE; - - /* Since we have been called by a specific linker, rather than - the generic linker, the values of the symbols will not be - right. They will be the values as seen in the input file, - not the values of the final link. We need to fix them up - before we can relocate the section. */ - sympp = _bfd_generic_link_get_symbols (input_bfd); - symppend = sympp + _bfd_generic_link_get_symcount (input_bfd); - for (; sympp < symppend; sympp++) - { - asymbol *sym; - struct bfd_link_hash_entry *h; - - sym = *sympp; - - if ((sym->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) - { - /* sym->udata may have been set by - generic_link_add_symbol_list. */ - if (sym->udata.p != NULL) - h = (struct bfd_link_hash_entry *) sym->udata.p; - else if (bfd_is_und_section (bfd_get_section (sym))) - h = bfd_wrapped_link_hash_lookup (output_bfd, info, - bfd_asymbol_name (sym), - FALSE, FALSE, TRUE); - else - h = bfd_link_hash_lookup (info->hash, - bfd_asymbol_name (sym), - FALSE, FALSE, TRUE); - if (h != NULL) - set_symbol_from_hash (sym, h); - } - } - } - - if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP - && input_section->size != 0) - { - /* Group section contents are set by bfd_elf_set_group_contents. */ - if (!output_bfd->output_has_begun) - { - /* FIXME: This hack ensures bfd_elf_set_group_contents is called. */ - if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1)) - goto error_return; - } - new_contents = output_section->contents; - BFD_ASSERT (new_contents != NULL); - BFD_ASSERT (input_section->output_offset == 0); - } - else - { - /* Get and relocate the section contents. */ - sec_size = (input_section->rawsize > input_section->size - ? input_section->rawsize - : input_section->size); - contents = (bfd_byte *) bfd_malloc (sec_size); - if (contents == NULL && sec_size != 0) - goto error_return; - new_contents = (bfd_get_relocated_section_contents - (output_bfd, info, link_order, contents, - info->relocatable, - _bfd_generic_link_get_symbols (input_bfd))); - if (!new_contents) - goto error_return; - } - - /* Output the section contents. */ - loc = input_section->output_offset * bfd_octets_per_byte (output_bfd); - if (! bfd_set_section_contents (output_bfd, output_section, - new_contents, loc, input_section->size)) - goto error_return; - - if (contents != NULL) - free (contents); - return TRUE; - - error_return: - if (contents != NULL) - free (contents); - return FALSE; -} - -/* A little routine to count the number of relocs in a link_order - list. */ - -unsigned int -_bfd_count_link_order_relocs (struct bfd_link_order *link_order) -{ - register unsigned int c; - register struct bfd_link_order *l; - - c = 0; - for (l = link_order; l != NULL; l = l->next) - { - if (l->type == bfd_section_reloc_link_order - || l->type == bfd_symbol_reloc_link_order) - ++c; - } - - return c; -} - -/* -FUNCTION - bfd_link_split_section - -SYNOPSIS - bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); - -DESCRIPTION - Return nonzero if @var{sec} should be split during a - reloceatable or final link. - -.#define bfd_link_split_section(abfd, sec) \ -. BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) -. - -*/ - -bfd_boolean -_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED) -{ - return FALSE; -} - -/* -FUNCTION - bfd_section_already_linked - -SYNOPSIS - bfd_boolean bfd_section_already_linked (bfd *abfd, - asection *sec, - struct bfd_link_info *info); - -DESCRIPTION - Check if @var{data} has been already linked during a reloceatable - or final link. Return TRUE if it has. - -.#define bfd_section_already_linked(abfd, sec, info) \ -. BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) -. - -*/ - -/* Sections marked with the SEC_LINK_ONCE flag should only be linked - once into the output. This routine checks each section, and - arrange to discard it if a section of the same name has already - been linked. This code assumes that all relevant sections have the - SEC_LINK_ONCE flag set; that is, it does not depend solely upon the - section name. bfd_section_already_linked is called via - bfd_map_over_sections. */ - -/* The hash table. */ - -static struct bfd_hash_table _bfd_section_already_linked_table; - -/* Support routines for the hash table used by section_already_linked, - initialize the table, traverse, lookup, fill in an entry and remove - the table. */ - -void -bfd_section_already_linked_table_traverse - (bfd_boolean (*func) (struct bfd_section_already_linked_hash_entry *, - void *), void *info) -{ - bfd_hash_traverse (&_bfd_section_already_linked_table, - (bfd_boolean (*) (struct bfd_hash_entry *, - void *)) func, - info); -} - -struct bfd_section_already_linked_hash_entry * -bfd_section_already_linked_table_lookup (const char *name) -{ - return ((struct bfd_section_already_linked_hash_entry *) - bfd_hash_lookup (&_bfd_section_already_linked_table, name, - TRUE, FALSE)); -} - -bfd_boolean -bfd_section_already_linked_table_insert - (struct bfd_section_already_linked_hash_entry *already_linked_list, - asection *sec) -{ - struct bfd_section_already_linked *l; - - /* Allocate the memory from the same obstack as the hash table is - kept in. */ - l = (struct bfd_section_already_linked *) - bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l); - if (l == NULL) - return FALSE; - l->sec = sec; - l->next = already_linked_list->entry; - already_linked_list->entry = l; - return TRUE; -} - -static struct bfd_hash_entry * -already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED, - struct bfd_hash_table *table, - const char *string ATTRIBUTE_UNUSED) -{ - struct bfd_section_already_linked_hash_entry *ret = - (struct bfd_section_already_linked_hash_entry *) - bfd_hash_allocate (table, sizeof *ret); - - if (ret == NULL) - return NULL; - - ret->entry = NULL; - - return &ret->root; -} - -bfd_boolean -bfd_section_already_linked_table_init (void) -{ - return bfd_hash_table_init_n (&_bfd_section_already_linked_table, - already_linked_newfunc, - sizeof (struct bfd_section_already_linked_hash_entry), - 42); -} - -void -bfd_section_already_linked_table_free (void) -{ - bfd_hash_table_free (&_bfd_section_already_linked_table); -} - -/* Report warnings as appropriate for duplicate section SEC. - Return FALSE if we decide to keep SEC after all. */ - -bfd_boolean -_bfd_handle_already_linked (asection *sec, - struct bfd_section_already_linked *l, - struct bfd_link_info *info) -{ - switch (sec->flags & SEC_LINK_DUPLICATES) - { - default: - abort (); - - case SEC_LINK_DUPLICATES_DISCARD: - /* If we found an LTO IR match for this comdat group on - the first pass, replace it with the LTO output on the - second pass. We can't simply choose real object - files over IR because the first pass may contain a - mix of LTO and normal objects and we must keep the - first match, be it IR or real. */ - if (info->loading_lto_outputs - && (l->sec->owner->flags & BFD_PLUGIN) != 0) - { - l->sec = sec; - return FALSE; - } - break; - - case SEC_LINK_DUPLICATES_ONE_ONLY: - info->callbacks->einfo - (_("%B: ignoring duplicate section `%A'\n"), - sec->owner, sec); - break; - - case SEC_LINK_DUPLICATES_SAME_SIZE: - if ((l->sec->owner->flags & BFD_PLUGIN) != 0) - ; - else if (sec->size != l->sec->size) - info->callbacks->einfo - (_("%B: duplicate section `%A' has different size\n"), - sec->owner, sec); - break; - - case SEC_LINK_DUPLICATES_SAME_CONTENTS: - if ((l->sec->owner->flags & BFD_PLUGIN) != 0) - ; - else if (sec->size != l->sec->size) - info->callbacks->einfo - (_("%B: duplicate section `%A' has different size\n"), - sec->owner, sec); - else if (sec->size != 0) - { - bfd_byte *sec_contents, *l_sec_contents = NULL; - - if (!bfd_malloc_and_get_section (sec->owner, sec, &sec_contents)) - info->callbacks->einfo - (_("%B: could not read contents of section `%A'\n"), - sec->owner, sec); - else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec, - &l_sec_contents)) - info->callbacks->einfo - (_("%B: could not read contents of section `%A'\n"), - l->sec->owner, l->sec); - else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) - info->callbacks->einfo - (_("%B: duplicate section `%A' has different contents\n"), - sec->owner, sec); - - if (sec_contents) - free (sec_contents); - if (l_sec_contents) - free (l_sec_contents); - } - break; - } - - /* Set the output_section field so that lang_add_section - does not create a lang_input_section structure for this - section. Since there might be a symbol in the section - being discarded, we must retain a pointer to the section - which we are really going to use. */ - sec->output_section = bfd_abs_section_ptr; - sec->kept_section = l->sec; - return TRUE; -} - -/* This is used on non-ELF inputs. */ - -bfd_boolean -_bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec, - struct bfd_link_info *info) -{ - const char *name; - struct bfd_section_already_linked *l; - struct bfd_section_already_linked_hash_entry *already_linked_list; - - if ((sec->flags & SEC_LINK_ONCE) == 0) - return FALSE; - - /* The generic linker doesn't handle section groups. */ - if ((sec->flags & SEC_GROUP) != 0) - return FALSE; - - /* FIXME: When doing a relocatable link, we may have trouble - copying relocations in other sections that refer to local symbols - in the section being discarded. Those relocations will have to - be converted somehow; as of this writing I'm not sure that any of - the backends handle that correctly. - - It is tempting to instead not discard link once sections when - doing a relocatable link (technically, they should be discarded - whenever we are building constructors). However, that fails, - because the linker winds up combining all the link once sections - into a single large link once section, which defeats the purpose - of having link once sections in the first place. */ - - name = bfd_get_section_name (abfd, sec); - - already_linked_list = bfd_section_already_linked_table_lookup (name); - - l = already_linked_list->entry; - if (l != NULL) - { - /* The section has already been linked. See if we should - issue a warning. */ - return _bfd_handle_already_linked (sec, l, info); - } - - /* This is the first section with this name. Record it. */ - if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) - info->callbacks->einfo (_("%F%P: already_linked_table: %E\n")); - return FALSE; -} - -/* Convert symbols in excluded output sections to use a kept section. */ - -static bfd_boolean -fix_syms (struct bfd_link_hash_entry *h, void *data) -{ - bfd *obfd = (bfd *) data; - - if (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) - { - asection *s = h->u.def.section; - if (s != NULL - && s->output_section != NULL - && (s->output_section->flags & SEC_EXCLUDE) != 0 - && bfd_section_removed_from_list (obfd, s->output_section)) - { - asection *op, *op1; - - h->u.def.value += s->output_offset + s->output_section->vma; - - /* Find preceding kept section. */ - for (op1 = s->output_section->prev; op1 != NULL; op1 = op1->prev) - if ((op1->flags & SEC_EXCLUDE) == 0 - && !bfd_section_removed_from_list (obfd, op1)) - break; - - /* Find following kept section. Start at prev->next because - other sections may have been added after S was removed. */ - if (s->output_section->prev != NULL) - op = s->output_section->prev->next; - else - op = s->output_section->owner->sections; - for (; op != NULL; op = op->next) - if ((op->flags & SEC_EXCLUDE) == 0 - && !bfd_section_removed_from_list (obfd, op)) - break; - - /* Choose better of two sections, based on flags. The idea - is to choose a section that will be in the same segment - as S would have been if it was kept. */ - if (op1 == NULL) - { - if (op == NULL) - op = bfd_abs_section_ptr; - } - else if (op == NULL) - op = op1; - else if (((op1->flags ^ op->flags) - & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0) - { - if (((op->flags ^ s->flags) - & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0 - /* We prefer to choose a loaded section. Section S - doesn't have SEC_LOAD set (it being excluded, that - part of the flag processing didn't happen) so we - can't compare that flag to those of OP and OP1. */ - || ((op1->flags & SEC_LOAD) != 0 - && (op->flags & SEC_LOAD) == 0)) - op = op1; - } - else if (((op1->flags ^ op->flags) & SEC_READONLY) != 0) - { - if (((op->flags ^ s->flags) & SEC_READONLY) != 0) - op = op1; - } - else if (((op1->flags ^ op->flags) & SEC_CODE) != 0) - { - if (((op->flags ^ s->flags) & SEC_CODE) != 0) - op = op1; - } - else - { - /* Flags we care about are the same. Prefer the following - section if that will result in a positive valued sym. */ - if (h->u.def.value < op->vma) - op = op1; - } - - h->u.def.value -= op->vma; - h->u.def.section = op; - } - } - - return TRUE; -} - -void -_bfd_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info) -{ - bfd_link_hash_traverse (info->hash, fix_syms, obfd); -} - -/* -FUNCTION - bfd_generic_define_common_symbol - -SYNOPSIS - bfd_boolean bfd_generic_define_common_symbol - (bfd *output_bfd, struct bfd_link_info *info, - struct bfd_link_hash_entry *h); - -DESCRIPTION - Convert common symbol @var{h} into a defined symbol. - Return TRUE on success and FALSE on failure. - -.#define bfd_define_common_symbol(output_bfd, info, h) \ -. BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) -. -*/ - -bfd_boolean -bfd_generic_define_common_symbol (bfd *output_bfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry *h) -{ - unsigned int power_of_two; - bfd_vma alignment, size; - asection *section; - - BFD_ASSERT (h != NULL && h->type == bfd_link_hash_common); - - size = h->u.c.size; - power_of_two = h->u.c.p->alignment_power; - section = h->u.c.p->section; - - /* Increase the size of the section to align the common symbol. - The alignment must be a power of two. */ - alignment = bfd_octets_per_byte (output_bfd) << power_of_two; - BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment); - section->size += alignment - 1; - section->size &= -alignment; - - /* Adjust the section's overall alignment if necessary. */ - if (power_of_two > section->alignment_power) - section->alignment_power = power_of_two; - - /* Change the symbol from common to defined. */ - h->type = bfd_link_hash_defined; - h->u.def.section = section; - h->u.def.value = section->size; - - /* Increase the size of the section. */ - section->size += size; - - /* Make sure the section is allocated in memory, and make sure that - it is no longer a common section. */ - section->flags |= SEC_ALLOC; - section->flags &= ~SEC_IS_COMMON; - return TRUE; -} - -/* -FUNCTION - bfd_find_version_for_sym - -SYNOPSIS - struct bfd_elf_version_tree * bfd_find_version_for_sym - (struct bfd_elf_version_tree *verdefs, - const char *sym_name, bfd_boolean *hide); - -DESCRIPTION - Search an elf version script tree for symbol versioning - info and export / don't-export status for a given symbol. - Return non-NULL on success and NULL on failure; also sets - the output @samp{hide} boolean parameter. - -*/ - -struct bfd_elf_version_tree * -bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, - const char *sym_name, - bfd_boolean *hide) -{ - struct bfd_elf_version_tree *t; - struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver; - struct bfd_elf_version_tree *star_local_ver, *star_global_ver; - - local_ver = NULL; - global_ver = NULL; - star_local_ver = NULL; - star_global_ver = NULL; - exist_ver = NULL; - for (t = verdefs; t != NULL; t = t->next) - { - if (t->globals.list != NULL) - { - struct bfd_elf_version_expr *d = NULL; - - while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL) - { - if (d->literal || strcmp (d->pattern, "*") != 0) - global_ver = t; - else - star_global_ver = t; - if (d->symver) - exist_ver = t; - d->script = 1; - /* If the match is a wildcard pattern, keep looking for - a more explicit, perhaps even local, match. */ - if (d->literal) - break; - } - - if (d != NULL) - break; - } - - if (t->locals.list != NULL) - { - struct bfd_elf_version_expr *d = NULL; - - while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL) - { - if (d->literal || strcmp (d->pattern, "*") != 0) - local_ver = t; - else - star_local_ver = t; - /* If the match is a wildcard pattern, keep looking for - a more explicit, perhaps even global, match. */ - if (d->literal) - { - /* An exact match overrides a global wildcard. */ - global_ver = NULL; - star_global_ver = NULL; - break; - } - } - - if (d != NULL) - break; - } - } - - if (global_ver == NULL && local_ver == NULL) - global_ver = star_global_ver; - - if (global_ver != NULL) - { - /* If we already have a versioned symbol that matches the - node for this symbol, then we don't want to create a - duplicate from the unversioned symbol. Instead hide the - unversioned symbol. */ - *hide = exist_ver == global_ver; - return global_ver; - } - - if (local_ver == NULL) - local_ver = star_local_ver; - - if (local_ver != NULL) - { - *hide = TRUE; - return local_ver; - } - - return NULL; -} - -/* -FUNCTION - bfd_hide_sym_by_version - -SYNOPSIS - bfd_boolean bfd_hide_sym_by_version - (struct bfd_elf_version_tree *verdefs, const char *sym_name); - -DESCRIPTION - Search an elf version script tree for symbol versioning - info for a given symbol. Return TRUE if the symbol is hidden. - -*/ - -bfd_boolean -bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs, - const char *sym_name) -{ - bfd_boolean hidden = FALSE; - bfd_find_version_for_sym (verdefs, sym_name, &hidden); - return hidden; -} diff --git a/contrib/binutils-2.22/bfd/merge.c b/contrib/binutils-2.22/bfd/merge.c deleted file mode 100644 index aef3cf35a5..0000000000 --- a/contrib/binutils-2.22/bfd/merge.c +++ /dev/null @@ -1,887 +0,0 @@ -/* SEC_MERGE support. - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - Written by Jakub Jelinek . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* This file contains support for merging duplicate entities within sections, - as used in ELF SHF_MERGE. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "hashtab.h" -#include "libiberty.h" - -struct sec_merge_sec_info; - -/* An entry in the section merge hash table. */ - -struct sec_merge_hash_entry -{ - struct bfd_hash_entry root; - /* Length of this entry. This includes the zero terminator. */ - unsigned int len; - /* Start of this string needs to be aligned to - alignment octets (not 1 << align). */ - unsigned int alignment; - union - { - /* Index within the merged section. */ - bfd_size_type index; - /* Entry this is a suffix of (if alignment is 0). */ - struct sec_merge_hash_entry *suffix; - } u; - /* Which section is it in. */ - struct sec_merge_sec_info *secinfo; - /* Next entity in the hash table. */ - struct sec_merge_hash_entry *next; -}; - -/* The section merge hash table. */ - -struct sec_merge_hash -{ - struct bfd_hash_table table; - /* Next available index. */ - bfd_size_type size; - /* First entity in the SEC_MERGE sections of this type. */ - struct sec_merge_hash_entry *first; - /* Last entity in the SEC_MERGE sections of this type. */ - struct sec_merge_hash_entry *last; - /* Entity size. */ - unsigned int entsize; - /* Are entries fixed size or zero terminated strings? */ - bfd_boolean strings; -}; - -struct sec_merge_info -{ - /* Chain of sec_merge_infos. */ - struct sec_merge_info *next; - /* Chain of sec_merge_sec_infos. */ - struct sec_merge_sec_info *chain; - /* A hash table used to hold section content. */ - struct sec_merge_hash *htab; -}; - -struct sec_merge_sec_info -{ - /* Chain of sec_merge_sec_infos. */ - struct sec_merge_sec_info *next; - /* The corresponding section. */ - asection *sec; - /* Pointer to merge_info pointing to us. */ - void **psecinfo; - /* A hash table used to hold section content. */ - struct sec_merge_hash *htab; - /* First string in this section. */ - struct sec_merge_hash_entry *first_str; - /* Original section content. */ - unsigned char contents[1]; -}; - - -/* Routine to create an entry in a section merge hashtab. */ - -static struct bfd_hash_entry * -sec_merge_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry)); - if (entry == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - entry = bfd_hash_newfunc (entry, table, string); - - if (entry != NULL) - { - /* Initialize the local fields. */ - struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry; - - ret->u.suffix = NULL; - ret->alignment = 0; - ret->secinfo = NULL; - ret->next = NULL; - } - - return entry; -} - -/* Look up an entry in a section merge hash table. */ - -static struct sec_merge_hash_entry * -sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, - unsigned int alignment, bfd_boolean create) -{ - const unsigned char *s; - unsigned long hash; - unsigned int c; - struct sec_merge_hash_entry *hashp; - unsigned int len, i; - unsigned int _index; - - hash = 0; - len = 0; - s = (const unsigned char *) string; - if (table->strings) - { - if (table->entsize == 1) - { - while ((c = *s++) != '\0') - { - hash += c + (c << 17); - hash ^= hash >> 2; - ++len; - } - hash += len + (len << 17); - } - else - { - for (;;) - { - for (i = 0; i < table->entsize; ++i) - if (s[i] != '\0') - break; - if (i == table->entsize) - break; - for (i = 0; i < table->entsize; ++i) - { - c = *s++; - hash += c + (c << 17); - hash ^= hash >> 2; - } - ++len; - } - hash += len + (len << 17); - len *= table->entsize; - } - hash ^= hash >> 2; - len += table->entsize; - } - else - { - for (i = 0; i < table->entsize; ++i) - { - c = *s++; - hash += c + (c << 17); - hash ^= hash >> 2; - } - len = table->entsize; - } - - _index = hash % table->table.size; - for (hashp = (struct sec_merge_hash_entry *) table->table.table[_index]; - hashp != NULL; - hashp = (struct sec_merge_hash_entry *) hashp->root.next) - { - if (hashp->root.hash == hash - && len == hashp->len - && memcmp (hashp->root.string, string, len) == 0) - { - /* If the string we found does not have at least the required - alignment, we need to insert another copy. */ - if (hashp->alignment < alignment) - { - if (create) - { - /* Mark the less aligned copy as deleted. */ - hashp->len = 0; - hashp->alignment = 0; - } - break; - } - return hashp; - } - } - - if (! create) - return NULL; - - hashp = ((struct sec_merge_hash_entry *) - bfd_hash_insert (&table->table, string, hash)); - if (hashp == NULL) - return NULL; - hashp->len = len; - hashp->alignment = alignment; - return hashp; -} - -/* Create a new hash table. */ - -static struct sec_merge_hash * -sec_merge_init (unsigned int entsize, bfd_boolean strings) -{ - struct sec_merge_hash *table; - - table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash)); - if (table == NULL) - return NULL; - - if (! bfd_hash_table_init_n (&table->table, sec_merge_hash_newfunc, - sizeof (struct sec_merge_hash_entry), 16699)) - { - free (table); - return NULL; - } - - table->size = 0; - table->first = NULL; - table->last = NULL; - table->entsize = entsize; - table->strings = strings; - - return table; -} - -/* Get the index of an entity in a hash table, adding it if it is not - already present. */ - -static struct sec_merge_hash_entry * -sec_merge_add (struct sec_merge_hash *tab, const char *str, - unsigned int alignment, struct sec_merge_sec_info *secinfo) -{ - struct sec_merge_hash_entry *entry; - - entry = sec_merge_hash_lookup (tab, str, alignment, TRUE); - if (entry == NULL) - return NULL; - - if (entry->secinfo == NULL) - { - tab->size++; - entry->secinfo = secinfo; - if (tab->first == NULL) - tab->first = entry; - else - tab->last->next = entry; - tab->last = entry; - } - - return entry; -} - -static bfd_boolean -sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) -{ - struct sec_merge_sec_info *secinfo = entry->secinfo; - asection *sec = secinfo->sec; - char *pad = NULL; - bfd_size_type off = 0; - int alignment_power = sec->output_section->alignment_power; - - if (alignment_power) - { - pad = (char *) bfd_zmalloc ((bfd_size_type) 1 << alignment_power); - if (pad == NULL) - return FALSE; - } - - for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next) - { - const char *str; - bfd_size_type len; - - len = -off & (entry->alignment - 1); - if (len != 0) - { - if (bfd_bwrite (pad, len, abfd) != len) - goto err; - off += len; - } - - str = entry->root.string; - len = entry->len; - - if (bfd_bwrite (str, len, abfd) != len) - goto err; - - off += len; - } - - /* Trailing alignment needed? */ - off = sec->size - off; - if (off != 0 - && bfd_bwrite (pad, off, abfd) != off) - goto err; - - if (pad != NULL) - free (pad); - return TRUE; - - err: - if (pad != NULL) - free (pad); - return FALSE; -} - -/* Register a SEC_MERGE section as a candidate for merging. - This function is called for all non-dynamic SEC_MERGE input sections. */ - -bfd_boolean -_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec, - void **psecinfo) -{ - struct sec_merge_info *sinfo; - struct sec_merge_sec_info *secinfo; - unsigned int align; - bfd_size_type amt; - bfd_byte *contents; - - if ((abfd->flags & DYNAMIC) != 0 - || (sec->flags & SEC_MERGE) == 0) - abort (); - - if (sec->size == 0 - || (sec->flags & SEC_EXCLUDE) != 0 - || sec->entsize == 0) - return TRUE; - - if ((sec->flags & SEC_RELOC) != 0) - { - /* We aren't prepared to handle relocations in merged sections. */ - return TRUE; - } - - align = sec->alignment_power; - if ((sec->entsize < (unsigned) 1 << align - && ((sec->entsize & (sec->entsize - 1)) - || !(sec->flags & SEC_STRINGS))) - || (sec->entsize > (unsigned) 1 << align - && (sec->entsize & (((unsigned) 1 << align) - 1)))) - { - /* Sanity check. If string character size is smaller than - alignment, then we require character size to be a power - of 2, otherwise character size must be integer multiple - of alignment. For non-string constants, alignment must - be smaller than or equal to entity size and entity size - must be integer multiple of alignment. */ - return TRUE; - } - - for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next) - if ((secinfo = sinfo->chain) - && ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS)) - && secinfo->sec->entsize == sec->entsize - && secinfo->sec->alignment_power == sec->alignment_power - && secinfo->sec->output_section == sec->output_section) - break; - - if (sinfo == NULL) - { - /* Initialize the information we need to keep track of. */ - sinfo = (struct sec_merge_info *) - bfd_alloc (abfd, sizeof (struct sec_merge_info)); - if (sinfo == NULL) - goto error_return; - sinfo->next = (struct sec_merge_info *) *psinfo; - sinfo->chain = NULL; - *psinfo = sinfo; - sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS)); - if (sinfo->htab == NULL) - goto error_return; - } - - /* Read the section from abfd. */ - - amt = sizeof (struct sec_merge_sec_info) - 1 + sec->size; - if (sec->flags & SEC_STRINGS) - /* Some versions of gcc may emit a string without a zero terminator. - See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html - Allocate space for an extra zero. */ - amt += sec->entsize; - *psecinfo = bfd_alloc (abfd, amt); - if (*psecinfo == NULL) - goto error_return; - - secinfo = (struct sec_merge_sec_info *) *psecinfo; - if (sinfo->chain) - { - secinfo->next = sinfo->chain->next; - sinfo->chain->next = secinfo; - } - else - secinfo->next = secinfo; - sinfo->chain = secinfo; - secinfo->sec = sec; - secinfo->psecinfo = psecinfo; - secinfo->htab = sinfo->htab; - secinfo->first_str = NULL; - - sec->rawsize = sec->size; - if (sec->flags & SEC_STRINGS) - memset (secinfo->contents + sec->size, 0, sec->entsize); - contents = secinfo->contents; - if (! bfd_get_full_section_contents (sec->owner, sec, &contents)) - goto error_return; - - return TRUE; - - error_return: - *psecinfo = NULL; - return FALSE; -} - -/* Record one section into the hash table. */ -static bfd_boolean -record_section (struct sec_merge_info *sinfo, - struct sec_merge_sec_info *secinfo) -{ - asection *sec = secinfo->sec; - struct sec_merge_hash_entry *entry; - bfd_boolean nul; - unsigned char *p, *end; - bfd_vma mask, eltalign; - unsigned int align, i; - - align = sec->alignment_power; - end = secinfo->contents + sec->size; - nul = FALSE; - mask = ((bfd_vma) 1 << align) - 1; - if (sec->flags & SEC_STRINGS) - { - for (p = secinfo->contents; p < end; ) - { - eltalign = p - secinfo->contents; - eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1; - if (!eltalign || eltalign > mask) - eltalign = mask + 1; - entry = sec_merge_add (sinfo->htab, (char *) p, (unsigned) eltalign, - secinfo); - if (! entry) - goto error_return; - p += entry->len; - if (sec->entsize == 1) - { - while (p < end && *p == 0) - { - if (!nul && !((p - secinfo->contents) & mask)) - { - nul = TRUE; - entry = sec_merge_add (sinfo->htab, "", - (unsigned) mask + 1, secinfo); - if (! entry) - goto error_return; - } - p++; - } - } - else - { - while (p < end) - { - for (i = 0; i < sec->entsize; i++) - if (p[i] != '\0') - break; - if (i != sec->entsize) - break; - if (!nul && !((p - secinfo->contents) & mask)) - { - nul = TRUE; - entry = sec_merge_add (sinfo->htab, (char *) p, - (unsigned) mask + 1, secinfo); - if (! entry) - goto error_return; - } - p += sec->entsize; - } - } - } - } - else - { - for (p = secinfo->contents; p < end; p += sec->entsize) - { - entry = sec_merge_add (sinfo->htab, (char *) p, 1, secinfo); - if (! entry) - goto error_return; - } - } - - return TRUE; - -error_return: - for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) - *secinfo->psecinfo = NULL; - return FALSE; -} - -static int -strrevcmp (const void *a, const void *b) -{ - struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a; - struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b; - unsigned int lenA = A->len; - unsigned int lenB = B->len; - const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1; - const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1; - int l = lenA < lenB ? lenA : lenB; - - while (l) - { - if (*s != *t) - return (int) *s - (int) *t; - s--; - t--; - l--; - } - return lenA - lenB; -} - -/* Like strrevcmp, but for the case where all strings have the same - alignment > entsize. */ - -static int -strrevcmp_align (const void *a, const void *b) -{ - struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a; - struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b; - unsigned int lenA = A->len; - unsigned int lenB = B->len; - const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1; - const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1; - int l = lenA < lenB ? lenA : lenB; - int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1)); - - if (tail_align != 0) - return tail_align; - - while (l) - { - if (*s != *t) - return (int) *s - (int) *t; - s--; - t--; - l--; - } - return lenA - lenB; -} - -static inline int -is_suffix (const struct sec_merge_hash_entry *A, - const struct sec_merge_hash_entry *B) -{ - if (A->len <= B->len) - /* B cannot be a suffix of A unless A is equal to B, which is guaranteed - not to be equal by the hash table. */ - return 0; - - return memcmp (A->root.string + (A->len - B->len), - B->root.string, B->len) == 0; -} - -/* This is a helper function for _bfd_merge_sections. It attempts to - merge strings matching suffixes of longer strings. */ -static void -merge_strings (struct sec_merge_info *sinfo) -{ - struct sec_merge_hash_entry **array, **a, *e; - struct sec_merge_sec_info *secinfo; - bfd_size_type size, amt; - unsigned int alignment = 0; - - /* Now sort the strings */ - amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *); - array = (struct sec_merge_hash_entry **) bfd_malloc (amt); - if (array == NULL) - goto alloc_failure; - - for (e = sinfo->htab->first, a = array; e; e = e->next) - if (e->alignment) - { - *a++ = e; - /* Adjust the length to not include the zero terminator. */ - e->len -= sinfo->htab->entsize; - if (alignment != e->alignment) - { - if (alignment == 0) - alignment = e->alignment; - else - alignment = (unsigned) -1; - } - } - - sinfo->htab->size = a - array; - if (sinfo->htab->size != 0) - { - qsort (array, (size_t) sinfo->htab->size, - sizeof (struct sec_merge_hash_entry *), - (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize - ? strrevcmp_align : strrevcmp)); - - /* Loop over the sorted array and merge suffixes */ - e = *--a; - e->len += sinfo->htab->entsize; - while (--a >= array) - { - struct sec_merge_hash_entry *cmp = *a; - - cmp->len += sinfo->htab->entsize; - if (e->alignment >= cmp->alignment - && !((e->len - cmp->len) & (cmp->alignment - 1)) - && is_suffix (e, cmp)) - { - cmp->u.suffix = e; - cmp->alignment = 0; - } - else - e = cmp; - } - } - -alloc_failure: - if (array) - free (array); - - /* Now assign positions to the strings we want to keep. */ - size = 0; - secinfo = sinfo->htab->first->secinfo; - for (e = sinfo->htab->first; e; e = e->next) - { - if (e->secinfo != secinfo) - { - secinfo->sec->size = size; - secinfo = e->secinfo; - } - if (e->alignment) - { - if (e->secinfo->first_str == NULL) - { - e->secinfo->first_str = e; - size = 0; - } - size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1); - e->u.index = size; - size += e->len; - } - } - secinfo->sec->size = size; - if (secinfo->sec->alignment_power != 0) - { - bfd_size_type align = (bfd_size_type) 1 << secinfo->sec->alignment_power; - secinfo->sec->size = (secinfo->sec->size + align - 1) & -align; - } - - /* And now adjust the rest, removing them from the chain (but not hashtable) - at the same time. */ - for (a = &sinfo->htab->first, e = *a; e; e = e->next) - if (e->alignment) - a = &e->next; - else - { - *a = e->next; - if (e->len) - { - e->secinfo = e->u.suffix->secinfo; - e->alignment = e->u.suffix->alignment; - e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len); - } - } -} - -/* This function is called once after all SEC_MERGE sections are registered - with _bfd_merge_section. */ - -bfd_boolean -_bfd_merge_sections (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, - void *xsinfo, - void (*remove_hook) (bfd *, asection *)) -{ - struct sec_merge_info *sinfo; - - for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next) - { - struct sec_merge_sec_info * secinfo; - - if (! sinfo->chain) - continue; - - /* Move sinfo->chain to head of the chain, terminate it. */ - secinfo = sinfo->chain; - sinfo->chain = secinfo->next; - secinfo->next = NULL; - - /* Record the sections into the hash table. */ - for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) - if (secinfo->sec->flags & SEC_EXCLUDE) - { - *secinfo->psecinfo = NULL; - if (remove_hook) - (*remove_hook) (abfd, secinfo->sec); - } - else if (! record_section (sinfo, secinfo)) - break; - - if (secinfo) - continue; - - if (sinfo->htab->first == NULL) - continue; - - if (sinfo->htab->strings) - merge_strings (sinfo); - else - { - struct sec_merge_hash_entry *e; - bfd_size_type size = 0; - - /* Things are much simpler for non-strings. - Just assign them slots in the section. */ - secinfo = NULL; - for (e = sinfo->htab->first; e; e = e->next) - { - if (e->secinfo->first_str == NULL) - { - if (secinfo) - secinfo->sec->size = size; - e->secinfo->first_str = e; - size = 0; - } - size = (size + e->alignment - 1) - & ~((bfd_vma) e->alignment - 1); - e->u.index = size; - size += e->len; - secinfo = e->secinfo; - } - secinfo->sec->size = size; - } - - /* Finally remove all input sections which have not made it into - the hash table at all. */ - for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) - if (secinfo->first_str == NULL) - secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP; - } - - return TRUE; -} - -/* Write out the merged section. */ - -bfd_boolean -_bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo) -{ - struct sec_merge_sec_info *secinfo; - file_ptr pos; - - secinfo = (struct sec_merge_sec_info *) psecinfo; - - if (!secinfo) - return FALSE; - - if (secinfo->first_str == NULL) - return TRUE; - - /* FIXME: octets_per_byte. */ - pos = sec->output_section->filepos + sec->output_offset; - if (bfd_seek (output_bfd, pos, SEEK_SET) != 0) - return FALSE; - - if (! sec_merge_emit (output_bfd, secinfo->first_str)) - return FALSE; - - return TRUE; -} - -/* Adjust an address in the SEC_MERGE section. Given OFFSET within - *PSEC, this returns the new offset in the adjusted SEC_MERGE - section and writes the new section back into *PSEC. */ - -bfd_vma -_bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec, - void *psecinfo, bfd_vma offset) -{ - struct sec_merge_sec_info *secinfo; - struct sec_merge_hash_entry *entry; - unsigned char *p; - asection *sec = *psec; - - secinfo = (struct sec_merge_sec_info *) psecinfo; - - if (!secinfo) - return offset; - - if (offset >= sec->rawsize) - { - if (offset > sec->rawsize) - { - (*_bfd_error_handler) - (_("%s: access beyond end of merged section (%ld)"), - bfd_get_filename (sec->owner), (long) offset); - } - return secinfo->first_str ? sec->size : 0; - } - - if (secinfo->htab->strings) - { - if (sec->entsize == 1) - { - p = secinfo->contents + offset - 1; - while (p >= secinfo->contents && *p) - --p; - ++p; - } - else - { - p = secinfo->contents + (offset / sec->entsize) * sec->entsize; - p -= sec->entsize; - while (p >= secinfo->contents) - { - unsigned int i; - - for (i = 0; i < sec->entsize; ++i) - if (p[i] != '\0') - break; - if (i == sec->entsize) - break; - p -= sec->entsize; - } - p += sec->entsize; - } - } - else - { - p = secinfo->contents + (offset / sec->entsize) * sec->entsize; - } - entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, FALSE); - if (!entry) - { - if (! secinfo->htab->strings) - abort (); - /* This should only happen if somebody points into the padding - after a NUL character but before next entity. */ - if (*p) - abort (); - if (! secinfo->htab->first) - abort (); - entry = secinfo->htab->first; - p = (secinfo->contents + (offset / sec->entsize + 1) * sec->entsize - - entry->len); - } - - *psec = entry->secinfo->sec; - return entry->u.index + (secinfo->contents + offset - p); -} diff --git a/contrib/binutils-2.22/bfd/opncls.c b/contrib/binutils-2.22/bfd/opncls.c deleted file mode 100644 index 9d33f3974f..0000000000 --- a/contrib/binutils-2.22/bfd/opncls.c +++ /dev/null @@ -1,1531 +0,0 @@ -/* opncls.c -- open and close a BFD. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "objalloc.h" -#include "libbfd.h" -#include "libiberty.h" - -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 /* Execute by group. */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 /* Execute by others. */ -#endif - -/* Counters used to initialize the bfd identifier. */ - -static unsigned int bfd_id_counter = 0; -static unsigned int bfd_reserved_id_counter = 0; - -/* -CODE_FRAGMENT -.{* Set to N to open the next N BFDs using an alternate id space. *} -.extern unsigned int bfd_use_reserved_id; -*/ -unsigned int bfd_use_reserved_id = 0; - -/* fdopen is a loser -- we should use stdio exclusively. Unfortunately - if we do that we can't use fcntl. */ - -/* Return a new BFD. All BFD's are allocated through this routine. */ - -bfd * -_bfd_new_bfd (void) -{ - bfd *nbfd; - - nbfd = (bfd *) bfd_zmalloc (sizeof (bfd)); - if (nbfd == NULL) - return NULL; - - if (bfd_use_reserved_id) - { - nbfd->id = --bfd_reserved_id_counter; - --bfd_use_reserved_id; - } - else - nbfd->id = bfd_id_counter++; - - nbfd->memory = objalloc_create (); - if (nbfd->memory == NULL) - { - bfd_set_error (bfd_error_no_memory); - free (nbfd); - return NULL; - } - - nbfd->arch_info = &bfd_default_arch_struct; - - nbfd->direction = no_direction; - nbfd->iostream = NULL; - nbfd->where = 0; - if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc, - sizeof (struct section_hash_entry), 251)) - { - free (nbfd); - return NULL; - } - nbfd->sections = NULL; - nbfd->section_last = NULL; - nbfd->format = bfd_unknown; - nbfd->my_archive = NULL; - nbfd->origin = 0; - nbfd->opened_once = FALSE; - nbfd->output_has_begun = FALSE; - nbfd->section_count = 0; - nbfd->usrdata = NULL; - nbfd->cacheable = FALSE; - nbfd->flags = BFD_NO_FLAGS; - nbfd->mtime_set = FALSE; - - return nbfd; -} - -/* Allocate a new BFD as a member of archive OBFD. */ - -bfd * -_bfd_new_bfd_contained_in (bfd *obfd) -{ - bfd *nbfd; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - nbfd->xvec = obfd->xvec; - nbfd->iovec = obfd->iovec; - nbfd->my_archive = obfd; - nbfd->direction = read_direction; - nbfd->target_defaulted = obfd->target_defaulted; - return nbfd; -} - -/* Delete a BFD. */ - -void -_bfd_delete_bfd (bfd *abfd) -{ - if (abfd->memory) - { - bfd_hash_table_free (&abfd->section_htab); - objalloc_free ((struct objalloc *) abfd->memory); - } - free (abfd); -} - -/* Free objalloc memory. */ - -bfd_boolean -_bfd_free_cached_info (bfd *abfd) -{ - if (abfd->memory) - { - bfd_hash_table_free (&abfd->section_htab); - objalloc_free ((struct objalloc *) abfd->memory); - - abfd->sections = NULL; - abfd->section_last = NULL; - abfd->outsymbols = NULL; - abfd->tdata.any = NULL; - abfd->usrdata = NULL; - abfd->memory = NULL; - } - - return TRUE; -} - -/* -SECTION - Opening and closing BFDs - -SUBSECTION - Functions for opening and closing -*/ - -/* -FUNCTION - bfd_fopen - -SYNOPSIS - bfd *bfd_fopen (const char *filename, const char *target, - const char *mode, int fd); - -DESCRIPTION - Open the file @var{filename} with the target @var{target}. - Return a pointer to the created BFD. If @var{fd} is not -1, - then <> is used to open the file; otherwise, <> - is used. @var{mode} is passed directly to <> or - <>. - - Calls <>, so @var{target} is interpreted as by - that function. - - The new BFD is marked as cacheable iff @var{fd} is -1. - - If <> is returned then an error has occured. Possible errors - are <>, <> or - <> error. -*/ - -bfd * -bfd_fopen (const char *filename, const char *target, const char *mode, int fd) -{ - bfd *nbfd; - const bfd_target *target_vec; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - -#ifdef HAVE_FDOPEN - if (fd != -1) - nbfd->iostream = fdopen (fd, mode); - else -#endif - nbfd->iostream = real_fopen (filename, mode); - if (nbfd->iostream == NULL) - { - bfd_set_error (bfd_error_system_call); - _bfd_delete_bfd (nbfd); - return NULL; - } - - /* OK, put everything where it belongs. */ - nbfd->filename = filename; - - /* Figure out whether the user is opening the file for reading, - writing, or both, by looking at the MODE argument. */ - if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a') - && mode[1] == '+') - nbfd->direction = both_direction; - else if (mode[0] == 'r') - nbfd->direction = read_direction; - else - nbfd->direction = write_direction; - - if (! bfd_cache_init (nbfd)) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - nbfd->opened_once = TRUE; - /* If we opened the file by name, mark it cacheable; we can close it - and reopen it later. However, if a file descriptor was provided, - then it may have been opened with special flags that make it - unsafe to close and reopen the file. */ - if (fd == -1) - bfd_set_cacheable (nbfd, TRUE); - - return nbfd; -} - -/* -FUNCTION - bfd_openr - -SYNOPSIS - bfd *bfd_openr (const char *filename, const char *target); - -DESCRIPTION - Open the file @var{filename} (using <>) with the target - @var{target}. Return a pointer to the created BFD. - - Calls <>, so @var{target} is interpreted as by - that function. - - If <> is returned then an error has occured. Possible errors - are <>, <> or - <> error. -*/ - -bfd * -bfd_openr (const char *filename, const char *target) -{ - return bfd_fopen (filename, target, FOPEN_RB, -1); -} - -/* Don't try to `optimize' this function: - - o - We lock using stack space so that interrupting the locking - won't cause a storage leak. - o - We open the file stream last, since we don't want to have to - close it if anything goes wrong. Closing the stream means closing - the file descriptor too, even though we didn't open it. */ -/* -FUNCTION - bfd_fdopenr - -SYNOPSIS - bfd *bfd_fdopenr (const char *filename, const char *target, int fd); - -DESCRIPTION - <> is to <> much like <> is to - <>. It opens a BFD on a file already described by the - @var{fd} supplied. - - When the file is later <>d, the file descriptor will - be closed. If the caller desires that this file descriptor be - cached by BFD (opened as needed, closed as needed to free - descriptors for other opens), with the supplied @var{fd} used as - an initial file descriptor (but subject to closure at any time), - call bfd_set_cacheable(bfd, 1) on the returned BFD. The default - is to assume no caching; the file descriptor will remain open - until <>, and will not be affected by BFD operations - on other files. - - Possible errors are <>, - <> and <>. -*/ - -bfd * -bfd_fdopenr (const char *filename, const char *target, int fd) -{ - const char *mode; -#if defined(HAVE_FCNTL) && defined(F_GETFL) - int fdflags; -#endif - -#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL) - mode = FOPEN_RUB; /* Assume full access. */ -#else - fdflags = fcntl (fd, F_GETFL, NULL); - if (fdflags == -1) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */ - switch (fdflags & (O_ACCMODE)) - { - case O_RDONLY: mode = FOPEN_RB; break; - case O_WRONLY: mode = FOPEN_RUB; break; - case O_RDWR: mode = FOPEN_RUB; break; - default: abort (); - } -#endif - - return bfd_fopen (filename, target, mode, fd); -} - -/* -FUNCTION - bfd_openstreamr - -SYNOPSIS - bfd *bfd_openstreamr (const char *, const char *, void *); - -DESCRIPTION - - Open a BFD for read access on an existing stdio stream. When - the BFD is passed to <>, the stream will be closed. -*/ - -bfd * -bfd_openstreamr (const char *filename, const char *target, void *streamarg) -{ - FILE *stream = (FILE *) streamarg; - bfd *nbfd; - const bfd_target *target_vec; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - - nbfd->iostream = stream; - nbfd->filename = filename; - nbfd->direction = read_direction; - - if (! bfd_cache_init (nbfd)) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - - return nbfd; -} - -/* -FUNCTION - bfd_openr_iovec - -SYNOPSIS - bfd *bfd_openr_iovec (const char *filename, const char *target, - void *(*open_func) (struct bfd *nbfd, - void *open_closure), - void *open_closure, - file_ptr (*pread_func) (struct bfd *nbfd, - void *stream, - void *buf, - file_ptr nbytes, - file_ptr offset), - int (*close_func) (struct bfd *nbfd, - void *stream), - int (*stat_func) (struct bfd *abfd, - void *stream, - struct stat *sb)); - -DESCRIPTION - - Create and return a BFD backed by a read-only @var{stream}. - The @var{stream} is created using @var{open_func}, accessed using - @var{pread_func} and destroyed using @var{close_func}. - - Calls <>, so @var{target} is interpreted as by - that function. - - Calls @var{open_func} (which can call <> and - <>) to obtain the read-only stream backing - the BFD. @var{open_func} either succeeds returning the - non-<> @var{stream}, or fails returning <> - (setting <>). - - Calls @var{pread_func} to request @var{nbytes} of data from - @var{stream} starting at @var{offset} (e.g., via a call to - <>). @var{pread_func} either succeeds returning the - number of bytes read (which can be less than @var{nbytes} when - end-of-file), or fails returning -1 (setting <>). - - Calls @var{close_func} when the BFD is later closed using - <>. @var{close_func} either succeeds returning 0, or - fails returning -1 (setting <>). - - Calls @var{stat_func} to fill in a stat structure for bfd_stat, - bfd_get_size, and bfd_get_mtime calls. @var{stat_func} returns 0 - on success, or returns -1 on failure (setting <>). - - If <> returns <> then an error has - occurred. Possible errors are <>, - <> and <>. - -*/ - -struct opncls -{ - void *stream; - file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf, - file_ptr nbytes, file_ptr offset); - int (*close) (struct bfd *abfd, void *stream); - int (*stat) (struct bfd *abfd, void *stream, struct stat *sb); - file_ptr where; -}; - -static file_ptr -opncls_btell (struct bfd *abfd) -{ - struct opncls *vec = (struct opncls *) abfd->iostream; - return vec->where; -} - -static int -opncls_bseek (struct bfd *abfd, file_ptr offset, int whence) -{ - struct opncls *vec = (struct opncls *) abfd->iostream; - switch (whence) - { - case SEEK_SET: vec->where = offset; break; - case SEEK_CUR: vec->where += offset; break; - case SEEK_END: return -1; - } - return 0; -} - -static file_ptr -opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes) -{ - struct opncls *vec = (struct opncls *) abfd->iostream; - file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where); - if (nread < 0) - return nread; - vec->where += nread; - return nread; -} - -static file_ptr -opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED, - const void *where ATTRIBUTE_UNUSED, - file_ptr nbytes ATTRIBUTE_UNUSED) -{ - return -1; -} - -static int -opncls_bclose (struct bfd *abfd) -{ - struct opncls *vec = (struct opncls *) abfd->iostream; - /* Since the VEC's memory is bound to the bfd deleting the bfd will - free it. */ - int status = 0; - if (vec->close != NULL) - status = (vec->close) (abfd, vec->stream); - abfd->iostream = NULL; - return status; -} - -static int -opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED) -{ - return 0; -} - -static int -opncls_bstat (struct bfd *abfd, struct stat *sb) -{ - struct opncls *vec = (struct opncls *) abfd->iostream; - - memset (sb, 0, sizeof (*sb)); - if (vec->stat == NULL) - return 0; - - return (vec->stat) (abfd, vec->stream, sb); -} - -static void * -opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED, - void *addr ATTRIBUTE_UNUSED, - bfd_size_type len ATTRIBUTE_UNUSED, - int prot ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, - file_ptr offset ATTRIBUTE_UNUSED, - void **map_addr ATTRIBUTE_UNUSED, - bfd_size_type *map_len ATTRIBUTE_UNUSED) -{ - return (void *) -1; -} - -static const struct bfd_iovec opncls_iovec = { - &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek, - &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap -}; - -bfd * -bfd_openr_iovec (const char *filename, const char *target, - void *(*open_p) (struct bfd *, void *), - void *open_closure, - file_ptr (*pread_p) (struct bfd *, void *, void *, - file_ptr, file_ptr), - int (*close_p) (struct bfd *, void *), - int (*stat_p) (struct bfd *, void *, struct stat *)) -{ - bfd *nbfd; - const bfd_target *target_vec; - struct opncls *vec; - void *stream; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - - nbfd->filename = filename; - nbfd->direction = read_direction; - - /* `open_p (...)' would get expanded by an the open(2) syscall macro. */ - stream = (*open_p) (nbfd, open_closure); - if (stream == NULL) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - - vec = (struct opncls *) bfd_zalloc (nbfd, sizeof (struct opncls)); - vec->stream = stream; - vec->pread = pread_p; - vec->close = close_p; - vec->stat = stat_p; - - nbfd->iovec = &opncls_iovec; - nbfd->iostream = vec; - - return nbfd; -} - -/* bfd_openw -- open for writing. - Returns a pointer to a freshly-allocated BFD on success, or NULL. - - See comment by bfd_fdopenr before you try to modify this function. */ - -/* -FUNCTION - bfd_openw - -SYNOPSIS - bfd *bfd_openw (const char *filename, const char *target); - -DESCRIPTION - Create a BFD, associated with file @var{filename}, using the - file format @var{target}, and return a pointer to it. - - Possible errors are <>, <>, - <>. -*/ - -bfd * -bfd_openw (const char *filename, const char *target) -{ - bfd *nbfd; - const bfd_target *target_vec; - - /* nbfd has to point to head of malloc'ed block so that bfd_close may - reclaim it correctly. */ - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) - { - _bfd_delete_bfd (nbfd); - return NULL; - } - - nbfd->filename = filename; - nbfd->direction = write_direction; - - if (bfd_open_file (nbfd) == NULL) - { - /* File not writeable, etc. */ - bfd_set_error (bfd_error_system_call); - _bfd_delete_bfd (nbfd); - return NULL; - } - - return nbfd; -} - -static inline void -_maybe_make_executable (bfd * abfd) -{ - /* If the file was open for writing and is now executable, - make it so. */ - if (abfd->direction == write_direction - && (abfd->flags & (EXEC_P | DYNAMIC)) != 0) - { - struct stat buf; - - if (stat (abfd->filename, &buf) == 0 - /* Do not attempt to change non-regular files. This is - here especially for configure scripts and kernel builds - which run tests with "ld [...] -o /dev/null". */ - && S_ISREG(buf.st_mode)) - { - unsigned int mask = umask (0); - - umask (mask); - chmod (abfd->filename, - (0777 - & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask)))); - } - } -} - -/* - -FUNCTION - bfd_close - -SYNOPSIS - bfd_boolean bfd_close (bfd *abfd); - -DESCRIPTION - - Close a BFD. If the BFD was open for writing, then pending - operations are completed and the file written out and closed. - If the created file is executable, then <> is called - to mark it as such. - - All memory attached to the BFD is released. - - The file descriptor associated with the BFD is closed (even - if it was passed in to BFD by <>). - -RETURNS - <> is returned if all is ok, otherwise <>. -*/ - - -bfd_boolean -bfd_close (bfd *abfd) -{ - bfd_boolean ret; - bfd *nbfd; - bfd *next; - - if (bfd_write_p (abfd)) - { - if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) - return FALSE; - } - - /* Close nested archives (if this bfd is a thin archive). */ - for (nbfd = abfd->nested_archives; nbfd; nbfd = next) - { - next = nbfd->archive_next; - bfd_close (nbfd); - } - - if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return FALSE; - - ret = abfd->iovec->bclose (abfd); - - if (ret) - _maybe_make_executable (abfd); - - _bfd_delete_bfd (abfd); - - return ret; -} - -/* -FUNCTION - bfd_close_all_done - -SYNOPSIS - bfd_boolean bfd_close_all_done (bfd *); - -DESCRIPTION - Close a BFD. Differs from <> since it does not - complete any pending operations. This routine would be used - if the application had just used BFD for swapping and didn't - want to use any of the writing code. - - If the created file is executable, then <> is called - to mark it as such. - - All memory attached to the BFD is released. - -RETURNS - <> is returned if all is ok, otherwise <>. -*/ - -bfd_boolean -bfd_close_all_done (bfd *abfd) -{ - bfd_boolean ret; - - ret = bfd_cache_close (abfd); - - if (ret) - _maybe_make_executable (abfd); - - _bfd_delete_bfd (abfd); - - return ret; -} - -/* -FUNCTION - bfd_create - -SYNOPSIS - bfd *bfd_create (const char *filename, bfd *templ); - -DESCRIPTION - Create a new BFD in the manner of <>, but without - opening a file. The new BFD takes the target from the target - used by @var{templ}. The format is always set to <>. -*/ - -bfd * -bfd_create (const char *filename, bfd *templ) -{ - bfd *nbfd; - - nbfd = _bfd_new_bfd (); - if (nbfd == NULL) - return NULL; - nbfd->filename = filename; - if (templ) - nbfd->xvec = templ->xvec; - nbfd->direction = no_direction; - bfd_set_format (nbfd, bfd_object); - - return nbfd; -} - -/* -FUNCTION - bfd_make_writable - -SYNOPSIS - bfd_boolean bfd_make_writable (bfd *abfd); - -DESCRIPTION - Takes a BFD as created by <> and converts it - into one like as returned by <>. It does this - by converting the BFD to BFD_IN_MEMORY. It's assumed that - you will call <> on this bfd later. - -RETURNS - <> is returned if all is ok, otherwise <>. -*/ - -bfd_boolean -bfd_make_writable (bfd *abfd) -{ - struct bfd_in_memory *bim; - - if (abfd->direction != no_direction) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory)); - if (bim == NULL) - return FALSE; /* bfd_error already set. */ - abfd->iostream = bim; - /* bfd_bwrite will grow these as needed. */ - bim->size = 0; - bim->buffer = 0; - - abfd->flags |= BFD_IN_MEMORY; - abfd->iovec = &_bfd_memory_iovec; - abfd->origin = 0; - abfd->direction = write_direction; - abfd->where = 0; - - return TRUE; -} - -/* -FUNCTION - bfd_make_readable - -SYNOPSIS - bfd_boolean bfd_make_readable (bfd *abfd); - -DESCRIPTION - Takes a BFD as created by <> and - <> and converts it into one like as - returned by <>. It does this by writing the - contents out to the memory buffer, then reversing the - direction. - -RETURNS - <> is returned if all is ok, otherwise <>. */ - -bfd_boolean -bfd_make_readable (bfd *abfd) -{ - if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) - return FALSE; - - if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return FALSE; - - abfd->arch_info = &bfd_default_arch_struct; - - abfd->where = 0; - abfd->format = bfd_unknown; - abfd->my_archive = NULL; - abfd->origin = 0; - abfd->opened_once = FALSE; - abfd->output_has_begun = FALSE; - abfd->section_count = 0; - abfd->usrdata = NULL; - abfd->cacheable = FALSE; - abfd->flags |= BFD_IN_MEMORY; - abfd->mtime_set = FALSE; - - abfd->target_defaulted = TRUE; - abfd->direction = read_direction; - abfd->sections = 0; - abfd->symcount = 0; - abfd->outsymbols = 0; - abfd->tdata.any = 0; - - bfd_section_list_clear (abfd); - bfd_check_format (abfd, bfd_object); - - return TRUE; -} - -/* -FUNCTION - bfd_alloc - -SYNOPSIS - void *bfd_alloc (bfd *abfd, bfd_size_type wanted); - -DESCRIPTION - Allocate a block of @var{wanted} bytes of memory attached to - <> and return a pointer to it. -*/ - -void * -bfd_alloc (bfd *abfd, bfd_size_type size) -{ - void *ret; - - if (size != (unsigned long) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -/* -INTERNAL_FUNCTION - bfd_alloc2 - -SYNOPSIS - void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); - -DESCRIPTION - Allocate a block of @var{nmemb} elements of @var{size} bytes each - of memory attached to <> and return a pointer to it. -*/ - -void * -bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size) -{ - void *ret; - - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE - && size != 0 - && nmemb > ~(bfd_size_type) 0 / size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - size *= nmemb; - - if (size != (unsigned long) size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - ret = objalloc_alloc ((struct objalloc *) abfd->memory, (unsigned long) size); - if (ret == NULL) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -/* -FUNCTION - bfd_zalloc - -SYNOPSIS - void *bfd_zalloc (bfd *abfd, bfd_size_type wanted); - -DESCRIPTION - Allocate a block of @var{wanted} bytes of zeroed memory - attached to <> and return a pointer to it. -*/ - -void * -bfd_zalloc (bfd *abfd, bfd_size_type size) -{ - void *res; - - res = bfd_alloc (abfd, size); - if (res) - memset (res, 0, (size_t) size); - return res; -} - -/* -INTERNAL_FUNCTION - bfd_zalloc2 - -SYNOPSIS - void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); - -DESCRIPTION - Allocate a block of @var{nmemb} elements of @var{size} bytes each - of zeroed memory attached to <> and return a pointer to it. -*/ - -void * -bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size) -{ - void *res; - - if ((nmemb | size) >= HALF_BFD_SIZE_TYPE - && size != 0 - && nmemb > ~(bfd_size_type) 0 / size) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - size *= nmemb; - - res = bfd_alloc (abfd, size); - if (res) - memset (res, 0, (size_t) size); - return res; -} - -/* Free a block allocated for a BFD. - Note: Also frees all more recently allocated blocks! */ - -void -bfd_release (bfd *abfd, void *block) -{ - objalloc_free_block ((struct objalloc *) abfd->memory, block); -} - - -/* - GNU Extension: separate debug-info files - - The idea here is that a special section called .gnu_debuglink might be - embedded in a binary file, which indicates that some *other* file - contains the real debugging information. This special section contains a - filename and CRC32 checksum, which we read and resolve to another file, - if it exists. - - This facilitates "optional" provision of debugging information, without - having to provide two complete copies of every binary object (with and - without debug symbols). -*/ - -#define GNU_DEBUGLINK ".gnu_debuglink" -/* -FUNCTION - bfd_calc_gnu_debuglink_crc32 - -SYNOPSIS - unsigned long bfd_calc_gnu_debuglink_crc32 - (unsigned long crc, const unsigned char *buf, bfd_size_type len); - -DESCRIPTION - Computes a CRC value as used in the .gnu_debuglink section. - Advances the previously computed @var{crc} value by computing - and adding in the crc32 for @var{len} bytes of @var{buf}. - -RETURNS - Return the updated CRC32 value. -*/ - -unsigned long -bfd_calc_gnu_debuglink_crc32 (unsigned long crc, - const unsigned char *buf, - bfd_size_type len) -{ - static const unsigned long crc32_table[256] = - { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d - }; - const unsigned char *end; - - crc = ~crc & 0xffffffff; - for (end = buf + len; buf < end; ++ buf) - crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); - return ~crc & 0xffffffff;; -} - - -/* -INTERNAL_FUNCTION - get_debug_link_info - -SYNOPSIS - char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out); - -DESCRIPTION - fetch the filename and CRC32 value for any separate debuginfo - associated with @var{abfd}. Return NULL if no such info found, - otherwise return filename and update @var{crc32_out}. -*/ - -static char * -get_debug_link_info (bfd *abfd, unsigned long *crc32_out) -{ - asection *sect; - unsigned long crc32; - bfd_byte *contents; - int crc_offset; - char *name; - - BFD_ASSERT (abfd); - BFD_ASSERT (crc32_out); - - sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK); - - if (sect == NULL) - return NULL; - - if (!bfd_malloc_and_get_section (abfd, sect, &contents)) - { - if (contents != NULL) - free (contents); - return NULL; - } - - /* Crc value is stored after the filename, aligned up to 4 bytes. */ - name = (char *) contents; - crc_offset = strlen (name) + 1; - crc_offset = (crc_offset + 3) & ~3; - - crc32 = bfd_get_32 (abfd, contents + crc_offset); - - *crc32_out = crc32; - return name; -} - -/* -INTERNAL_FUNCTION - separate_debug_file_exists - -SYNOPSIS - bfd_boolean separate_debug_file_exists - (char *name, unsigned long crc32); - -DESCRIPTION - Checks to see if @var{name} is a file and if its contents - match @var{crc32}. -*/ - -static bfd_boolean -separate_debug_file_exists (const char *name, const unsigned long crc) -{ - static unsigned char buffer [8 * 1024]; - unsigned long file_crc = 0; - FILE *f; - bfd_size_type count; - - BFD_ASSERT (name); - - f = real_fopen (name, FOPEN_RB); - if (f == NULL) - return FALSE; - - while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0) - file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count); - - fclose (f); - - return crc == file_crc; -} - - -/* -INTERNAL_FUNCTION - find_separate_debug_file - -SYNOPSIS - char *find_separate_debug_file (bfd *abfd); - -DESCRIPTION - Searches @var{abfd} for a reference to separate debugging - information, scans various locations in the filesystem, including - the file tree rooted at @var{debug_file_directory}, and returns a - filename of such debugging information if the file is found and has - matching CRC32. Returns NULL if no reference to debugging file - exists, or file cannot be found. -*/ - -static char * -find_separate_debug_file (bfd *abfd, const char *debug_file_directory) -{ - char *base; - char *dir; - char *debugfile; - char *canon_dir; - unsigned long crc32; - size_t dirlen; - size_t canon_dirlen; - - BFD_ASSERT (abfd); - if (debug_file_directory == NULL) - debug_file_directory = "."; - - /* BFD may have been opened from a stream. */ - if (abfd->filename == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - base = get_debug_link_info (abfd, & crc32); - if (base == NULL) - return NULL; - - if (base[0] == '\0') - { - free (base); - bfd_set_error (bfd_error_no_debug_section); - return NULL; - } - - for (dirlen = strlen (abfd->filename); dirlen > 0; dirlen--) - if (IS_DIR_SEPARATOR (abfd->filename[dirlen - 1])) - break; - - dir = (char *) bfd_malloc (dirlen + 1); - if (dir == NULL) - { - free (base); - return NULL; - } - memcpy (dir, abfd->filename, dirlen); - dir[dirlen] = '\0'; - - /* Compute the canonical name of the bfd object with all symbolic links - resolved, for use in the global debugfile directory. */ - canon_dir = lrealpath (abfd->filename); - for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--) - if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1])) - break; - canon_dir[canon_dirlen] = '\0'; - - debugfile = (char *) - bfd_malloc (strlen (debug_file_directory) + 1 - + (canon_dirlen > dirlen ? canon_dirlen : dirlen) - + strlen (".debug/") - + strlen (base) - + 1); - if (debugfile == NULL) - { - free (base); - free (dir); - free (canon_dir); - return NULL; - } - - /* First try in the same directory as the original file: */ - strcpy (debugfile, dir); - strcat (debugfile, base); - - if (separate_debug_file_exists (debugfile, crc32)) - { - free (base); - free (dir); - free (canon_dir); - return debugfile; - } - - /* Then try in a subdirectory called .debug. */ - strcpy (debugfile, dir); - strcat (debugfile, ".debug/"); - strcat (debugfile, base); - - if (separate_debug_file_exists (debugfile, crc32)) - { - free (base); - free (dir); - free (canon_dir); - return debugfile; - } - - /* Then try in the global debugfile directory. */ - strcpy (debugfile, debug_file_directory); - dirlen = strlen (debug_file_directory) - 1; - if (dirlen > 0 - && debug_file_directory[dirlen] != '/' - && canon_dir[0] != '/') - strcat (debugfile, "/"); - strcat (debugfile, canon_dir); - strcat (debugfile, base); - - if (separate_debug_file_exists (debugfile, crc32)) - { - free (base); - free (dir); - free (canon_dir); - return debugfile; - } - - free (debugfile); - free (base); - free (dir); - free (canon_dir); - return NULL; -} - - -/* -FUNCTION - bfd_follow_gnu_debuglink - -SYNOPSIS - char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); - -DESCRIPTION - - Takes a BFD and searches it for a .gnu_debuglink section. If this - section is found, it examines the section for the name and checksum - of a '.debug' file containing auxiliary debugging information. It - then searches the filesystem for this .debug file in some standard - locations, including the directory tree rooted at @var{dir}, and if - found returns the full filename. - - If @var{dir} is NULL, it will search a default path configured into - libbfd at build time. [XXX this feature is not currently - implemented]. - -RETURNS - <> on any errors or failure to locate the .debug file, - otherwise a pointer to a heap-allocated string containing the - filename. The caller is responsible for freeing this string. -*/ - -char * -bfd_follow_gnu_debuglink (bfd *abfd, const char *dir) -{ - return find_separate_debug_file (abfd, dir); -} - -/* -FUNCTION - bfd_create_gnu_debuglink_section - -SYNOPSIS - struct bfd_section *bfd_create_gnu_debuglink_section - (bfd *abfd, const char *filename); - -DESCRIPTION - - Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized - to be big enough to contain a link to the specified @var{filename}. - -RETURNS - A pointer to the new section is returned if all is ok. Otherwise <> is - returned and bfd_error is set. -*/ - -asection * -bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename) -{ - asection *sect; - bfd_size_type debuglink_size; - flagword flags; - - if (abfd == NULL || filename == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - /* Strip off any path components in filename. */ - filename = lbasename (filename); - - sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK); - if (sect) - { - /* Section already exists. */ - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING; - sect = bfd_make_section_with_flags (abfd, GNU_DEBUGLINK, flags); - if (sect == NULL) - return NULL; - - debuglink_size = strlen (filename) + 1; - debuglink_size += 3; - debuglink_size &= ~3; - debuglink_size += 4; - - if (! bfd_set_section_size (abfd, sect, debuglink_size)) - /* XXX Should we delete the section from the bfd ? */ - return NULL; - - return sect; -} - - -/* -FUNCTION - bfd_fill_in_gnu_debuglink_section - -SYNOPSIS - bfd_boolean bfd_fill_in_gnu_debuglink_section - (bfd *abfd, struct bfd_section *sect, const char *filename); - -DESCRIPTION - - Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT} - and fills in the contents of the section to contain a link to the - specified @var{filename}. The filename should be relative to the - current directory. - -RETURNS - <> is returned if all is ok. Otherwise <> is returned - and bfd_error is set. -*/ - -bfd_boolean -bfd_fill_in_gnu_debuglink_section (bfd *abfd, - struct bfd_section *sect, - const char *filename) -{ - bfd_size_type debuglink_size; - unsigned long crc32; - char * contents; - bfd_size_type crc_offset; - FILE * handle; - static unsigned char buffer[8 * 1024]; - size_t count; - size_t filelen; - - if (abfd == NULL || sect == NULL || filename == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* Make sure that we can read the file. - XXX - Should we attempt to locate the debug info file using the same - algorithm as gdb ? At the moment, since we are creating the - .gnu_debuglink section, we insist upon the user providing us with a - correct-for-section-creation-time path, but this need not conform to - the gdb location algorithm. */ - handle = real_fopen (filename, FOPEN_RB); - if (handle == NULL) - { - bfd_set_error (bfd_error_system_call); - return FALSE; - } - - crc32 = 0; - while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0) - crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count); - fclose (handle); - - /* Strip off any path components in filename, - now that we no longer need them. */ - filename = lbasename (filename); - - filelen = strlen (filename); - debuglink_size = filelen + 1; - debuglink_size += 3; - debuglink_size &= ~3; - debuglink_size += 4; - - contents = (char *) bfd_malloc (debuglink_size); - if (contents == NULL) - { - /* XXX Should we delete the section from the bfd ? */ - return FALSE; - } - - crc_offset = debuglink_size - 4; - memcpy (contents, filename, filelen); - memset (contents + filelen, 0, crc_offset - filelen); - - bfd_put_32 (abfd, crc32, contents + crc_offset); - - if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size)) - { - /* XXX Should we delete the section from the bfd ? */ - free (contents); - return FALSE; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/plugin.h b/contrib/binutils-2.22/bfd/plugin.h deleted file mode 100644 index 3091f9705a..0000000000 --- a/contrib/binutils-2.22/bfd/plugin.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Plugin support for BFD. - Copyright 2009 Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef _PLUGIN_H_ -#define _PLUGIN_H_ - -#include "bfd.h" - -void bfd_plugin_set_program_name (const char *); -void bfd_plugin_set_plugin (const char *); - -typedef struct plugin_data_struct -{ - int nsyms; - const struct ld_plugin_symbol *syms; -} -plugin_data_struct; - -#endif diff --git a/contrib/binutils-2.22/bfd/reloc.c b/contrib/binutils-2.22/bfd/reloc.c deleted file mode 100644 index 6ac7148902..0000000000 --- a/contrib/binutils-2.22/bfd/reloc.c +++ /dev/null @@ -1,6295 +0,0 @@ -/* BFD support for handling relocation entries. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - Relocations - - BFD maintains relocations in much the same way it maintains - symbols: they are left alone until required, then read in - en-masse and translated into an internal form. A common - routine <> acts upon the - canonical form to do the fixup. - - Relocations are maintained on a per section basis, - while symbols are maintained on a per BFD basis. - - All that a back end has to do to fit the BFD interface is to create - a <> for each relocation - in a particular section, and fill in the right bits of the structures. - -@menu -@* typedef arelent:: -@* howto manager:: -@end menu - -*/ - -/* DO compile in the reloc_code name table from libbfd.h. */ -#define _BFD_MAKE_TABLE_bfd_reloc_code_real - -#include "sysdep.h" -#include "bfd.h" -#include "bfdlink.h" -#include "libbfd.h" -/* -DOCDD -INODE - typedef arelent, howto manager, Relocations, Relocations - -SUBSECTION - typedef arelent - - This is the structure of a relocation entry: - -CODE_FRAGMENT -. -.typedef enum bfd_reloc_status -.{ -. {* No errors detected. *} -. bfd_reloc_ok, -. -. {* The relocation was performed, but there was an overflow. *} -. bfd_reloc_overflow, -. -. {* The address to relocate was not within the section supplied. *} -. bfd_reloc_outofrange, -. -. {* Used by special functions. *} -. bfd_reloc_continue, -. -. {* Unsupported relocation size requested. *} -. bfd_reloc_notsupported, -. -. {* Unused. *} -. bfd_reloc_other, -. -. {* The symbol to relocate against was undefined. *} -. bfd_reloc_undefined, -. -. {* The relocation was performed, but may not be ok - presently -. generated only when linking i960 coff files with i960 b.out -. symbols. If this type is returned, the error_message argument -. to bfd_perform_relocation will be set. *} -. bfd_reloc_dangerous -. } -. bfd_reloc_status_type; -. -. -.typedef struct reloc_cache_entry -.{ -. {* A pointer into the canonical table of pointers. *} -. struct bfd_symbol **sym_ptr_ptr; -. -. {* offset in section. *} -. bfd_size_type address; -. -. {* addend for relocation value. *} -. bfd_vma addend; -. -. {* Pointer to how to perform the required relocation. *} -. reloc_howto_type *howto; -. -.} -.arelent; -. -*/ - -/* -DESCRIPTION - - Here is a description of each of the fields within an <>: - - o <> - - The symbol table pointer points to a pointer to the symbol - associated with the relocation request. It is the pointer - into the table returned by the back end's - <> action. @xref{Symbols}. The symbol is - referenced through a pointer to a pointer so that tools like - the linker can fix up all the symbols of the same name by - modifying only one pointer. The relocation routine looks in - the symbol and uses the base of the section the symbol is - attached to and the value of the symbol as the initial - relocation offset. If the symbol pointer is zero, then the - section provided is looked up. - - o <
> - - The <
> field gives the offset in bytes from the base of - the section data which owns the relocation record to the first - byte of relocatable information. The actual data relocated - will be relative to this point; for example, a relocation - type which modifies the bottom two bytes of a four byte word - would not touch the first byte pointed to in a big endian - world. - - o <> - - The <> is a value provided by the back end to be added (!) - to the relocation offset. Its interpretation is dependent upon - the howto. For example, on the 68k the code: - -| char foo[]; -| main() -| { -| return foo[0x12345678]; -| } - - Could be compiled into: - -| linkw fp,#-4 -| moveb @@#12345678,d0 -| extbl d0 -| unlk fp -| rts - - This could create a reloc pointing to <>, but leave the - offset in the data, something like: - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000006 32 _foo -| -|00000000 4e56 fffc ; linkw fp,#-4 -|00000004 1039 1234 5678 ; moveb @@#12345678,d0 -|0000000a 49c0 ; extbl d0 -|0000000c 4e5e ; unlk fp -|0000000e 4e75 ; rts - - Using coff and an 88k, some instructions don't have enough - space in them to represent the full address range, and - pointers have to be loaded in two parts. So you'd get something like: - -| or.u r13,r0,hi16(_foo+0x12345678) -| ld.b r2,r13,lo16(_foo+0x12345678) -| jmp r1 - - This should create two relocs, both pointing to <<_foo>>, and with - 0x12340000 in their addend field. The data would consist of: - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000002 HVRT16 _foo+0x12340000 -|00000006 LVRT16 _foo+0x12340000 -| -|00000000 5da05678 ; or.u r13,r0,0x5678 -|00000004 1c4d5678 ; ld.b r2,r13,0x5678 -|00000008 f400c001 ; jmp r1 - - The relocation routine digs out the value from the data, adds - it to the addend to get the original offset, and then adds the - value of <<_foo>>. Note that all 32 bits have to be kept around - somewhere, to cope with carry from bit 15 to bit 16. - - One further example is the sparc and the a.out format. The - sparc has a similar problem to the 88k, in that some - instructions don't have room for an entire offset, but on the - sparc the parts are created in odd sized lumps. The designers of - the a.out format chose to not use the data within the section - for storing part of the offset; all the offset is kept within - the reloc. Anything in the data should be ignored. - -| save %sp,-112,%sp -| sethi %hi(_foo+0x12345678),%g2 -| ldsb [%g2+%lo(_foo+0x12345678)],%i0 -| ret -| restore - - Both relocs contain a pointer to <>, and the offsets - contain junk. - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000004 HI22 _foo+0x12345678 -|00000008 LO10 _foo+0x12345678 -| -|00000000 9de3bf90 ; save %sp,-112,%sp -|00000004 05000000 ; sethi %hi(_foo+0),%g2 -|00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 -|0000000c 81c7e008 ; ret -|00000010 81e80000 ; restore - - o <> - - The <> field can be imagined as a - relocation instruction. It is a pointer to a structure which - contains information on what to do with all of the other - information in the reloc record and data section. A back end - would normally have a relocation instruction set and turn - relocations into pointers to the correct structure on input - - but it would be possible to create each howto field on demand. - -*/ - -/* -SUBSUBSECTION - <> - - Indicates what sort of overflow checking should be done when - performing a relocation. - -CODE_FRAGMENT -. -.enum complain_overflow -.{ -. {* Do not complain on overflow. *} -. complain_overflow_dont, -. -. {* Complain if the value overflows when considered as a signed -. number one bit larger than the field. ie. A bitfield of N bits -. is allowed to represent -2**n to 2**n-1. *} -. complain_overflow_bitfield, -. -. {* Complain if the value overflows when considered as a signed -. number. *} -. complain_overflow_signed, -. -. {* Complain if the value overflows when considered as an -. unsigned number. *} -. complain_overflow_unsigned -.}; - -*/ - -/* -SUBSUBSECTION - <> - - The <> is a structure which contains all the - information that libbfd needs to know to tie up a back end's data. - -CODE_FRAGMENT -.struct bfd_symbol; {* Forward declaration. *} -. -.struct reloc_howto_struct -.{ -. {* The type field has mainly a documentary use - the back end can -. do what it wants with it, though normally the back end's -. external idea of what a reloc number is stored -. in this field. For example, a PC relative word relocation -. in a coff environment has the type 023 - because that's -. what the outside world calls a R_PCRWORD reloc. *} -. unsigned int type; -. -. {* The value the final relocation is shifted right by. This drops -. unwanted data from the relocation. *} -. unsigned int rightshift; -. -. {* The size of the item to be relocated. This is *not* a -. power-of-two measure. To get the number of bytes operated -. on by a type of relocation, use bfd_get_reloc_size. *} -. int size; -. -. {* The number of bits in the item to be relocated. This is used -. when doing overflow checking. *} -. unsigned int bitsize; -. -. {* The relocation is relative to the field being relocated. *} -. bfd_boolean pc_relative; -. -. {* The bit position of the reloc value in the destination. -. The relocated value is left shifted by this amount. *} -. unsigned int bitpos; -. -. {* What type of overflow error should be checked for when -. relocating. *} -. enum complain_overflow complain_on_overflow; -. -. {* If this field is non null, then the supplied function is -. called rather than the normal function. This allows really -. strange relocation methods to be accommodated (e.g., i960 callj -. instructions). *} -. bfd_reloc_status_type (*special_function) -. (bfd *, arelent *, struct bfd_symbol *, void *, asection *, -. bfd *, char **); -. -. {* The textual name of the relocation type. *} -. char *name; -. -. {* Some formats record a relocation addend in the section contents -. rather than with the relocation. For ELF formats this is the -. distinction between USE_REL and USE_RELA (though the code checks -. for USE_REL == 1/0). The value of this field is TRUE if the -. addend is recorded with the section contents; when performing a -. partial link (ld -r) the section contents (the data) will be -. modified. The value of this field is FALSE if addends are -. recorded with the relocation (in arelent.addend); when performing -. a partial link the relocation will be modified. -. All relocations for all ELF USE_RELA targets should set this field -. to FALSE (values of TRUE should be looked on with suspicion). -. However, the converse is not true: not all relocations of all ELF -. USE_REL targets set this field to TRUE. Why this is so is peculiar -. to each particular target. For relocs that aren't used in partial -. links (e.g. GOT stuff) it doesn't matter what this is set to. *} -. bfd_boolean partial_inplace; -. -. {* src_mask selects the part of the instruction (or data) to be used -. in the relocation sum. If the target relocations don't have an -. addend in the reloc, eg. ELF USE_REL, src_mask will normally equal -. dst_mask to extract the addend from the section contents. If -. relocations do have an addend in the reloc, eg. ELF USE_RELA, this -. field should be zero. Non-zero values for ELF USE_RELA targets are -. bogus as in those cases the value in the dst_mask part of the -. section contents should be treated as garbage. *} -. bfd_vma src_mask; -. -. {* dst_mask selects which parts of the instruction (or data) are -. replaced with a relocated value. *} -. bfd_vma dst_mask; -. -. {* When some formats create PC relative instructions, they leave -. the value of the pc of the place being relocated in the offset -. slot of the instruction, so that a PC relative relocation can -. be made just by adding in an ordinary offset (e.g., sun3 a.out). -. Some formats leave the displacement part of an instruction -. empty (e.g., m88k bcs); this flag signals the fact. *} -. bfd_boolean pcrel_offset; -.}; -. -*/ - -/* -FUNCTION - The HOWTO Macro - -DESCRIPTION - The HOWTO define is horrible and will go away. - -.#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ -. { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } - -DESCRIPTION - And will be replaced with the totally magic way. But for the - moment, we are compatible, so do it this way. - -.#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ -. HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ -. NAME, FALSE, 0, 0, IN) -. - -DESCRIPTION - This is used to fill in an empty howto entry in an array. - -.#define EMPTY_HOWTO(C) \ -. HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ -. NULL, FALSE, 0, 0, FALSE) -. - -DESCRIPTION - Helper routine to turn a symbol into a relocation value. - -.#define HOWTO_PREPARE(relocation, symbol) \ -. { \ -. if (symbol != NULL) \ -. { \ -. if (bfd_is_com_section (symbol->section)) \ -. { \ -. relocation = 0; \ -. } \ -. else \ -. { \ -. relocation = symbol->value; \ -. } \ -. } \ -. } -. -*/ - -/* -FUNCTION - bfd_get_reloc_size - -SYNOPSIS - unsigned int bfd_get_reloc_size (reloc_howto_type *); - -DESCRIPTION - For a reloc_howto_type that operates on a fixed number of bytes, - this returns the number of bytes operated on. - */ - -unsigned int -bfd_get_reloc_size (reloc_howto_type *howto) -{ - switch (howto->size) - { - case 0: return 1; - case 1: return 2; - case 2: return 4; - case 3: return 0; - case 4: return 8; - case 8: return 16; - case -2: return 4; - default: abort (); - } -} - -/* -TYPEDEF - arelent_chain - -DESCRIPTION - - How relocs are tied together in an <>: - -.typedef struct relent_chain -.{ -. arelent relent; -. struct relent_chain *next; -.} -.arelent_chain; -. -*/ - -/* N_ONES produces N one bits, without overflowing machine arithmetic. */ -#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1) - -/* -FUNCTION - bfd_check_overflow - -SYNOPSIS - bfd_reloc_status_type bfd_check_overflow - (enum complain_overflow how, - unsigned int bitsize, - unsigned int rightshift, - unsigned int addrsize, - bfd_vma relocation); - -DESCRIPTION - Perform overflow checking on @var{relocation} which has - @var{bitsize} significant bits and will be shifted right by - @var{rightshift} bits, on a machine with addresses containing - @var{addrsize} significant bits. The result is either of - @code{bfd_reloc_ok} or @code{bfd_reloc_overflow}. - -*/ - -bfd_reloc_status_type -bfd_check_overflow (enum complain_overflow how, - unsigned int bitsize, - unsigned int rightshift, - unsigned int addrsize, - bfd_vma relocation) -{ - bfd_vma fieldmask, addrmask, signmask, ss, a; - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not, - we'll be permissive: extra bits in the field mask will - automatically extend the address mask for purposes of the - overflow check. */ - fieldmask = N_ONES (bitsize); - signmask = ~fieldmask; - addrmask = N_ONES (addrsize) | (fieldmask << rightshift); - a = (relocation & addrmask) >> rightshift;; - - switch (how) - { - case complain_overflow_dont: - break; - - case complain_overflow_signed: - /* If any sign bits are set, all sign bits must be set. That - is, A must be a valid negative address after shifting. */ - signmask = ~ (fieldmask >> 1); - /* Fall thru */ - - case complain_overflow_bitfield: - /* Bitfields are sometimes signed, sometimes unsigned. We - explicitly allow an address wrap too, which means a bitfield - of n bits is allowed to store -2**n to 2**n-1. Thus overflow - if the value has some, but not all, bits set outside the - field. */ - ss = a & signmask; - if (ss != 0 && ss != ((addrmask >> rightshift) & signmask)) - flag = bfd_reloc_overflow; - break; - - case complain_overflow_unsigned: - /* We have an overflow if the address does not fit in the field. */ - if ((a & signmask) != 0) - flag = bfd_reloc_overflow; - break; - - default: - abort (); - } - - return flag; -} - -/* -FUNCTION - bfd_perform_relocation - -SYNOPSIS - bfd_reloc_status_type bfd_perform_relocation - (bfd *abfd, - arelent *reloc_entry, - void *data, - asection *input_section, - bfd *output_bfd, - char **error_message); - -DESCRIPTION - If @var{output_bfd} is supplied to this function, the - generated image will be relocatable; the relocations are - copied to the output file after they have been changed to - reflect the new state of the world. There are two ways of - reflecting the results of partial linkage in an output file: - by modifying the output data in place, and by modifying the - relocation record. Some native formats (e.g., basic a.out and - basic coff) have no way of specifying an addend in the - relocation type, so the addend has to go in the output data. - This is no big deal since in these formats the output data - slot will always be big enough for the addend. Complex reloc - types with addends were invented to solve just this problem. - The @var{error_message} argument is set to an error message if - this return @code{bfd_reloc_dangerous}. - -*/ - -bfd_reloc_status_type -bfd_perform_relocation (bfd *abfd, - arelent *reloc_entry, - void *data, - asection *input_section, - bfd *output_bfd, - char **error_message) -{ - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd); - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asymbol *symbol; - - symbol = *(reloc_entry->sym_ptr_ptr); - if (bfd_is_abs_section (symbol->section) - && output_bfd != NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we are not producing relocatable output, return an error if - the symbol is not defined. An undefined weak symbol is - considered to have a value of zero (SVR4 ABI, p. 4-27). */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == NULL) - flag = bfd_reloc_undefined; - - /* If there is a function supplied to handle this relocation type, - call it. It'll return `bfd_reloc_continue' if further processing - can be done. */ - if (howto->special_function) - { - bfd_reloc_status_type cont; - cont = howto->special_function (abfd, reloc_entry, symbol, data, - input_section, output_bfd, - error_message); - if (cont != bfd_reloc_continue) - return cont; - } - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targeted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if ((output_bfd && ! howto->partial_inplace) - || reloc_target_output_section == NULL) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is FALSE. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is TRUE. - - If we are producing relocatable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is FALSE we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is TRUE - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocatable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset) - relocation -= reloc_entry->address; - } - - if (output_bfd != NULL) - { - if (! howto->partial_inplace) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "coff-Intel-little") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-big") != 0) - { - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_perform_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocatable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocatable output. When -we are producing relocatable output, logically we should do exactly -what we do when not producing relocatable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocatable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_perform_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - } - else - { - reloc_entry->addend = 0; - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont - && flag == bfd_reloc_ok) - flag = bfd_check_overflow (howto->complain_on_overflow, - howto->bitsize, - howto->rightshift, - bfd_arch_bits_per_address (abfd), - relocation); - - /* Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs). */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used. */ - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them. */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - (( i i i i i o o o o o from bfd_get - and S S S S S) to get the size offset we want - + r r r r r r r r r r) to get the final value to place - and D D D D D to chop to right size - ----------------------- - = A A A A A - And this: - ( i i i i i o o o o o from bfd_get - and N N N N N ) get instruction - ----------------------- - = B B B B B - - And then: - ( B B B B B - or A A A A A) - ----------------------- - = R R R R R R R R R R put into bfd_put - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, (char *) data + octets); - DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data + octets); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, (bfd_byte *) data + octets); - DOIT (x); - bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + octets); - } - break; - case 2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + octets); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); - } - break; - - case -1: - { - long x = bfd_get_16 (abfd, (bfd_byte *) data + octets); - relocation = -relocation; - DOIT (x); - bfd_put_16 (abfd, (bfd_vma) x, (bfd_byte *) data + octets); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: -#ifdef BFD64 - { - bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets); - DOIT (x); - bfd_put_64 (abfd, x, (bfd_byte *) data + octets); - } -#else - abort (); -#endif - break; - default: - return bfd_reloc_other; - } - - return flag; -} - -/* -FUNCTION - bfd_install_relocation - -SYNOPSIS - bfd_reloc_status_type bfd_install_relocation - (bfd *abfd, - arelent *reloc_entry, - void *data, bfd_vma data_start, - asection *input_section, - char **error_message); - -DESCRIPTION - This looks remarkably like <>, except it - does not expect that the section contents have been filled in. - I.e., it's suitable for use when creating, rather than applying - a relocation. - - For now, this function should be considered reserved for the - assembler. -*/ - -bfd_reloc_status_type -bfd_install_relocation (bfd *abfd, - arelent *reloc_entry, - void *data_start, - bfd_vma data_start_offset, - asection *input_section, - char **error_message) -{ - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd); - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asymbol *symbol; - bfd_byte *data; - - symbol = *(reloc_entry->sym_ptr_ptr); - if (bfd_is_abs_section (symbol->section)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If there is a function supplied to handle this relocation type, - call it. It'll return `bfd_reloc_continue' if further processing - can be done. */ - if (howto->special_function) - { - bfd_reloc_status_type cont; - - /* XXX - The special_function calls haven't been fixed up to deal - with creating new relocations and section contents. */ - cont = howto->special_function (abfd, reloc_entry, symbol, - /* XXX - Non-portable! */ - ((bfd_byte *) data_start - - data_start_offset), - input_section, abfd, error_message); - if (cont != bfd_reloc_continue) - return cont; - } - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targeted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (! howto->partial_inplace) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is FALSE. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is TRUE. - - If we are producing relocatable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is FALSE we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is TRUE - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocatable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset && howto->partial_inplace) - relocation -= reloc_entry->address; - } - - if (! howto->partial_inplace) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "coff-Intel-little") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-big") != 0) - { - - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_install_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocatable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocatable output. When -we are producing relocatable output, logically we should do exactly -what we do when not producing relocatable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocatable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_install_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right. */ - relocation -= reloc_entry->addend; - /* FIXME: There should be no target specific code here... */ - if (strcmp (abfd->xvec->name, "coff-z8k") != 0) - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont) - flag = bfd_check_overflow (howto->complain_on_overflow, - howto->bitsize, - howto->rightshift, - bfd_arch_bits_per_address (abfd), - relocation); - - /* Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs). */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used. */ - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them. */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - (( i i i i i o o o o o from bfd_get - and S S S S S) to get the size offset we want - + r r r r r r r r r r) to get the final value to place - and D D D D D to chop to right size - ----------------------- - = A A A A A - And this: - ( i i i i i o o o o o from bfd_get - and N N N N N ) get instruction - ----------------------- - = B B B B B - - And then: - ( B B B B B - or A A A A A) - ----------------------- - = R R R R R R R R R R put into bfd_put - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - data = (bfd_byte *) data_start + (octets - data_start_offset); - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, data); - DOIT (x); - bfd_put_8 (abfd, x, data); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, data); - DOIT (x); - bfd_put_16 (abfd, (bfd_vma) x, data); - } - break; - case 2: - { - long x = bfd_get_32 (abfd, data); - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, data); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, data); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, (bfd_vma) x, data); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: - { - bfd_vma x = bfd_get_64 (abfd, data); - DOIT (x); - bfd_put_64 (abfd, x, data); - } - break; - default: - return bfd_reloc_other; - } - - return flag; -} - -/* This relocation routine is used by some of the backend linkers. - They do not construct asymbol or arelent structures, so there is no - reason for them to use bfd_perform_relocation. Also, - bfd_perform_relocation is so hacked up it is easier to write a new - function than to try to deal with it. - - This routine does a final relocation. Whether it is useful for a - relocatable link depends upon how the object format defines - relocations. - - FIXME: This routine ignores any special_function in the HOWTO, - since the existing special_function values have been written for - bfd_perform_relocation. - - HOWTO is the reloc howto information. - INPUT_BFD is the BFD which the reloc applies to. - INPUT_SECTION is the section which the reloc applies to. - CONTENTS is the contents of the section. - ADDRESS is the address of the reloc within INPUT_SECTION. - VALUE is the value of the symbol the reloc refers to. - ADDEND is the addend of the reloc. */ - -bfd_reloc_status_type -_bfd_final_link_relocate (reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - bfd_vma address, - bfd_vma value, - bfd_vma addend) -{ - bfd_vma relocation; - - /* Sanity check the address. */ - if (address > bfd_get_section_limit (input_bfd, input_section)) - return bfd_reloc_outofrange; - - /* This function assumes that we are dealing with a basic relocation - against a symbol. We want to compute the value of the symbol to - relocate to. This is just VALUE, the value of the symbol, plus - ADDEND, any addend associated with the reloc. */ - relocation = value + addend; - - /* If the relocation is PC relative, we want to set RELOCATION to - the distance between the symbol (currently in RELOCATION) and the - location we are relocating. Some targets (e.g., i386-aout) - arrange for the contents of the section to be the negative of the - offset of the location within the section; for such targets - pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF) - simply leave the contents of the section as zero; for such - targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not - need to subtract out the offset of the location within the - section (which is just ADDRESS). */ - if (howto->pc_relative) - { - relocation -= (input_section->output_section->vma - + input_section->output_offset); - if (howto->pcrel_offset) - relocation -= address; - } - - return _bfd_relocate_contents (howto, input_bfd, relocation, - contents + address); -} - -/* Relocate a given location using a given value and howto. */ - -bfd_reloc_status_type -_bfd_relocate_contents (reloc_howto_type *howto, - bfd *input_bfd, - bfd_vma relocation, - bfd_byte *location) -{ - int size; - bfd_vma x = 0; - bfd_reloc_status_type flag; - unsigned int rightshift = howto->rightshift; - unsigned int bitpos = howto->bitpos; - - /* If the size is negative, negate RELOCATION. This isn't very - general. */ - if (howto->size < 0) - relocation = -relocation; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } - - /* Check for overflow. FIXME: We may drop bits during the addition - which we don't check for. We must either check at every single - operation, which would be tedious, or we must do the computations - in a type larger than bfd_vma, which would be inefficient. */ - flag = bfd_reloc_ok; - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma addrmask, fieldmask, signmask, ss; - bfd_vma a, b, sum; - - /* Get the values to be added together. For signed and unsigned - relocations, we assume that all values should be truncated to - the size of an address. For bitfields, all the bits matter. - See also bfd_check_overflow. */ - fieldmask = N_ONES (howto->bitsize); - signmask = ~fieldmask; - addrmask = (N_ONES (bfd_arch_bits_per_address (input_bfd)) - | (fieldmask << rightshift)); - a = (relocation & addrmask) >> rightshift; - b = (x & howto->src_mask & addrmask) >> bitpos; - addrmask >>= rightshift; - - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - /* If any sign bits are set, all sign bits must be set. - That is, A must be a valid negative address after - shifting. */ - signmask = ~(fieldmask >> 1); - /* Fall thru */ - - case complain_overflow_bitfield: - /* Much like the signed check, but for a field one bit - wider. We allow a bitfield to represent numbers in the - range -2**n to 2**n-1, where n is the number of bits in the - field. Note that when bfd_vma is 32 bits, a 32-bit reloc - can't overflow, which is exactly what we want. */ - ss = a & signmask; - if (ss != 0 && ss != (addrmask & signmask)) - flag = bfd_reloc_overflow; - - /* We only need this next bit of code if the sign bit of B - is below the sign bit of A. This would only happen if - SRC_MASK had fewer bits than BITSIZE. Note that if - SRC_MASK has more bits than BITSIZE, we can get into - trouble; we would need to verify that B is in range, as - we do for A above. */ - ss = ((~howto->src_mask) >> 1) & howto->src_mask; - ss >>= bitpos; - - /* Set all the bits above the sign bit. */ - b = (b ^ ss) - ss; - - /* Now we can do the addition. */ - sum = a + b; - - /* See if the result has the correct sign. Bits above the - sign bit are junk now; ignore them. If the sum is - positive, make sure we did not have all negative inputs; - if the sum is negative, make sure we did not have all - positive inputs. The test below looks only at the sign - bits, and it really just - SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM) - - We mask with addrmask here to explicitly allow an address - wrap-around. The Linux kernel relies on it, and it is - the only way to write assembler code which can run when - loaded at a location 0x80000000 away from the location at - which it is linked. */ - if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask) - flag = bfd_reloc_overflow; - break; - - case complain_overflow_unsigned: - /* Checking for an unsigned overflow is relatively easy: - trim the addresses and add, and trim the result as well. - Overflow is normally indicated when the result does not - fit in the field. However, we also need to consider the - case when, e.g., fieldmask is 0x7fffffff or smaller, an - input is 0x80000000, and bfd_vma is only 32 bits; then we - will get sum == 0, but there is an overflow, since the - inputs did not fit in the field. Instead of doing a - separate test, we can check for this by or-ing in the - operands when testing for the sum overflowing its final - field. */ - sum = (a + b) & addrmask; - if ((a | b | sum) & signmask) - flag = bfd_reloc_overflow; - break; - - default: - abort (); - } - } - - /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) rightshift; - relocation <<= (bfd_vma) bitpos; - - /* Add RELOCATION to the right bits of X. */ - x = ((x & ~howto->dst_mask) - | (((x & howto->src_mask) + relocation) & howto->dst_mask)); - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } - - return flag; -} - -/* Clear a given location using a given howto, by applying a fixed relocation - value and discarding any in-place addend. This is used for fixed-up - relocations against discarded symbols, to make ignorable debug or unwind - information more obvious. */ - -void -_bfd_clear_contents (reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *location) -{ - int size; - bfd_vma x = 0; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } - - /* Zero out the unwanted bits of X. */ - x &= ~howto->dst_mask; - - /* For a range list, use 1 instead of 0 as placeholder. 0 - would terminate the list, hiding any later entries. */ - if (strcmp (bfd_get_section_name (input_bfd, input_section), - ".debug_ranges") == 0 - && (howto->dst_mask & 1) != 0) - x |= 1; - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } -} - -/* -DOCDD -INODE - howto manager, , typedef arelent, Relocations - -SUBSECTION - The howto manager - - When an application wants to create a relocation, but doesn't - know what the target machine might call it, it can find out by - using this bit of code. - -*/ - -/* -TYPEDEF - bfd_reloc_code_type - -DESCRIPTION - The insides of a reloc code. The idea is that, eventually, there - will be one enumerator for every type of relocation we ever do. - Pass one of these values to <>, and it'll - return a howto pointer. - - This does mean that the application must determine the correct - enumerator value; you can't get a howto pointer from a random set - of attributes. - -SENUM - bfd_reloc_code_real - -ENUM - BFD_RELOC_64 -ENUMX - BFD_RELOC_32 -ENUMX - BFD_RELOC_26 -ENUMX - BFD_RELOC_24 -ENUMX - BFD_RELOC_16 -ENUMX - BFD_RELOC_14 -ENUMX - BFD_RELOC_8 -ENUMDOC - Basic absolute relocations of N bits. - -ENUM - BFD_RELOC_64_PCREL -ENUMX - BFD_RELOC_32_PCREL -ENUMX - BFD_RELOC_24_PCREL -ENUMX - BFD_RELOC_16_PCREL -ENUMX - BFD_RELOC_12_PCREL -ENUMX - BFD_RELOC_8_PCREL -ENUMDOC - PC-relative relocations. Sometimes these are relative to the address -of the relocation itself; sometimes they are relative to the start of -the section containing the relocation. It depends on the specific target. - -The 24-bit relocation is used in some Intel 960 configurations. - -ENUM - BFD_RELOC_32_SECREL -ENUMDOC - Section relative relocations. Some targets need this for DWARF2. - -ENUM - BFD_RELOC_32_GOT_PCREL -ENUMX - BFD_RELOC_16_GOT_PCREL -ENUMX - BFD_RELOC_8_GOT_PCREL -ENUMX - BFD_RELOC_32_GOTOFF -ENUMX - BFD_RELOC_16_GOTOFF -ENUMX - BFD_RELOC_LO16_GOTOFF -ENUMX - BFD_RELOC_HI16_GOTOFF -ENUMX - BFD_RELOC_HI16_S_GOTOFF -ENUMX - BFD_RELOC_8_GOTOFF -ENUMX - BFD_RELOC_64_PLT_PCREL -ENUMX - BFD_RELOC_32_PLT_PCREL -ENUMX - BFD_RELOC_24_PLT_PCREL -ENUMX - BFD_RELOC_16_PLT_PCREL -ENUMX - BFD_RELOC_8_PLT_PCREL -ENUMX - BFD_RELOC_64_PLTOFF -ENUMX - BFD_RELOC_32_PLTOFF -ENUMX - BFD_RELOC_16_PLTOFF -ENUMX - BFD_RELOC_LO16_PLTOFF -ENUMX - BFD_RELOC_HI16_PLTOFF -ENUMX - BFD_RELOC_HI16_S_PLTOFF -ENUMX - BFD_RELOC_8_PLTOFF -ENUMDOC - For ELF. - -ENUM - BFD_RELOC_68K_GLOB_DAT -ENUMX - BFD_RELOC_68K_JMP_SLOT -ENUMX - BFD_RELOC_68K_RELATIVE -ENUMX - BFD_RELOC_68K_TLS_GD32 -ENUMX - BFD_RELOC_68K_TLS_GD16 -ENUMX - BFD_RELOC_68K_TLS_GD8 -ENUMX - BFD_RELOC_68K_TLS_LDM32 -ENUMX - BFD_RELOC_68K_TLS_LDM16 -ENUMX - BFD_RELOC_68K_TLS_LDM8 -ENUMX - BFD_RELOC_68K_TLS_LDO32 -ENUMX - BFD_RELOC_68K_TLS_LDO16 -ENUMX - BFD_RELOC_68K_TLS_LDO8 -ENUMX - BFD_RELOC_68K_TLS_IE32 -ENUMX - BFD_RELOC_68K_TLS_IE16 -ENUMX - BFD_RELOC_68K_TLS_IE8 -ENUMX - BFD_RELOC_68K_TLS_LE32 -ENUMX - BFD_RELOC_68K_TLS_LE16 -ENUMX - BFD_RELOC_68K_TLS_LE8 -ENUMDOC - Relocations used by 68K ELF. - -ENUM - BFD_RELOC_32_BASEREL -ENUMX - BFD_RELOC_16_BASEREL -ENUMX - BFD_RELOC_LO16_BASEREL -ENUMX - BFD_RELOC_HI16_BASEREL -ENUMX - BFD_RELOC_HI16_S_BASEREL -ENUMX - BFD_RELOC_8_BASEREL -ENUMX - BFD_RELOC_RVA -ENUMDOC - Linkage-table relative. - -ENUM - BFD_RELOC_8_FFnn -ENUMDOC - Absolute 8-bit relocation, but used to form an address like 0xFFnn. - -ENUM - BFD_RELOC_32_PCREL_S2 -ENUMX - BFD_RELOC_16_PCREL_S2 -ENUMX - BFD_RELOC_23_PCREL_S2 -ENUMDOC - These PC-relative relocations are stored as word displacements -- -i.e., byte displacements shifted right two bits. The 30-bit word -displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the -SPARC. (SPARC tools generally refer to this as <>.) The -signed 16-bit displacement is used on the MIPS, and the 23-bit -displacement is used on the Alpha. - -ENUM - BFD_RELOC_HI22 -ENUMX - BFD_RELOC_LO10 -ENUMDOC - High 22 bits and low 10 bits of 32-bit value, placed into lower bits of -the target word. These are used on the SPARC. - -ENUM - BFD_RELOC_GPREL16 -ENUMX - BFD_RELOC_GPREL32 -ENUMDOC - For systems that allocate a Global Pointer register, these are -displacements off that register. These relocation types are -handled specially, because the value the register will have is -decided relatively late. - -ENUM - BFD_RELOC_I960_CALLJ -ENUMDOC - Reloc types used for i960/b.out. - -ENUM - BFD_RELOC_NONE -ENUMX - BFD_RELOC_SPARC_WDISP22 -ENUMX - BFD_RELOC_SPARC22 -ENUMX - BFD_RELOC_SPARC13 -ENUMX - BFD_RELOC_SPARC_GOT10 -ENUMX - BFD_RELOC_SPARC_GOT13 -ENUMX - BFD_RELOC_SPARC_GOT22 -ENUMX - BFD_RELOC_SPARC_PC10 -ENUMX - BFD_RELOC_SPARC_PC22 -ENUMX - BFD_RELOC_SPARC_WPLT30 -ENUMX - BFD_RELOC_SPARC_COPY -ENUMX - BFD_RELOC_SPARC_GLOB_DAT -ENUMX - BFD_RELOC_SPARC_JMP_SLOT -ENUMX - BFD_RELOC_SPARC_RELATIVE -ENUMX - BFD_RELOC_SPARC_UA16 -ENUMX - BFD_RELOC_SPARC_UA32 -ENUMX - BFD_RELOC_SPARC_UA64 -ENUMX - BFD_RELOC_SPARC_GOTDATA_HIX22 -ENUMX - BFD_RELOC_SPARC_GOTDATA_LOX10 -ENUMX - BFD_RELOC_SPARC_GOTDATA_OP_HIX22 -ENUMX - BFD_RELOC_SPARC_GOTDATA_OP_LOX10 -ENUMX - BFD_RELOC_SPARC_GOTDATA_OP -ENUMX - BFD_RELOC_SPARC_JMP_IREL -ENUMX - BFD_RELOC_SPARC_IRELATIVE -ENUMDOC - SPARC ELF relocations. There is probably some overlap with other - relocation types already defined. - -ENUM - BFD_RELOC_SPARC_BASE13 -ENUMX - BFD_RELOC_SPARC_BASE22 -ENUMDOC - I think these are specific to SPARC a.out (e.g., Sun 4). - -ENUMEQ - BFD_RELOC_SPARC_64 - BFD_RELOC_64 -ENUMX - BFD_RELOC_SPARC_10 -ENUMX - BFD_RELOC_SPARC_11 -ENUMX - BFD_RELOC_SPARC_OLO10 -ENUMX - BFD_RELOC_SPARC_HH22 -ENUMX - BFD_RELOC_SPARC_HM10 -ENUMX - BFD_RELOC_SPARC_LM22 -ENUMX - BFD_RELOC_SPARC_PC_HH22 -ENUMX - BFD_RELOC_SPARC_PC_HM10 -ENUMX - BFD_RELOC_SPARC_PC_LM22 -ENUMX - BFD_RELOC_SPARC_WDISP16 -ENUMX - BFD_RELOC_SPARC_WDISP19 -ENUMX - BFD_RELOC_SPARC_7 -ENUMX - BFD_RELOC_SPARC_6 -ENUMX - BFD_RELOC_SPARC_5 -ENUMEQX - BFD_RELOC_SPARC_DISP64 - BFD_RELOC_64_PCREL -ENUMX - BFD_RELOC_SPARC_PLT32 -ENUMX - BFD_RELOC_SPARC_PLT64 -ENUMX - BFD_RELOC_SPARC_HIX22 -ENUMX - BFD_RELOC_SPARC_LOX10 -ENUMX - BFD_RELOC_SPARC_H44 -ENUMX - BFD_RELOC_SPARC_M44 -ENUMX - BFD_RELOC_SPARC_L44 -ENUMX - BFD_RELOC_SPARC_REGISTER -ENUMDOC - SPARC64 relocations - -ENUM - BFD_RELOC_SPARC_REV32 -ENUMDOC - SPARC little endian relocation -ENUM - BFD_RELOC_SPARC_TLS_GD_HI22 -ENUMX - BFD_RELOC_SPARC_TLS_GD_LO10 -ENUMX - BFD_RELOC_SPARC_TLS_GD_ADD -ENUMX - BFD_RELOC_SPARC_TLS_GD_CALL -ENUMX - BFD_RELOC_SPARC_TLS_LDM_HI22 -ENUMX - BFD_RELOC_SPARC_TLS_LDM_LO10 -ENUMX - BFD_RELOC_SPARC_TLS_LDM_ADD -ENUMX - BFD_RELOC_SPARC_TLS_LDM_CALL -ENUMX - BFD_RELOC_SPARC_TLS_LDO_HIX22 -ENUMX - BFD_RELOC_SPARC_TLS_LDO_LOX10 -ENUMX - BFD_RELOC_SPARC_TLS_LDO_ADD -ENUMX - BFD_RELOC_SPARC_TLS_IE_HI22 -ENUMX - BFD_RELOC_SPARC_TLS_IE_LO10 -ENUMX - BFD_RELOC_SPARC_TLS_IE_LD -ENUMX - BFD_RELOC_SPARC_TLS_IE_LDX -ENUMX - BFD_RELOC_SPARC_TLS_IE_ADD -ENUMX - BFD_RELOC_SPARC_TLS_LE_HIX22 -ENUMX - BFD_RELOC_SPARC_TLS_LE_LOX10 -ENUMX - BFD_RELOC_SPARC_TLS_DTPMOD32 -ENUMX - BFD_RELOC_SPARC_TLS_DTPMOD64 -ENUMX - BFD_RELOC_SPARC_TLS_DTPOFF32 -ENUMX - BFD_RELOC_SPARC_TLS_DTPOFF64 -ENUMX - BFD_RELOC_SPARC_TLS_TPOFF32 -ENUMX - BFD_RELOC_SPARC_TLS_TPOFF64 -ENUMDOC - SPARC TLS relocations - -ENUM - BFD_RELOC_SPU_IMM7 -ENUMX - BFD_RELOC_SPU_IMM8 -ENUMX - BFD_RELOC_SPU_IMM10 -ENUMX - BFD_RELOC_SPU_IMM10W -ENUMX - BFD_RELOC_SPU_IMM16 -ENUMX - BFD_RELOC_SPU_IMM16W -ENUMX - BFD_RELOC_SPU_IMM18 -ENUMX - BFD_RELOC_SPU_PCREL9a -ENUMX - BFD_RELOC_SPU_PCREL9b -ENUMX - BFD_RELOC_SPU_PCREL16 -ENUMX - BFD_RELOC_SPU_LO16 -ENUMX - BFD_RELOC_SPU_HI16 -ENUMX - BFD_RELOC_SPU_PPU32 -ENUMX - BFD_RELOC_SPU_PPU64 -ENUMX - BFD_RELOC_SPU_ADD_PIC -ENUMDOC - SPU Relocations. - -ENUM - BFD_RELOC_ALPHA_GPDISP_HI16 -ENUMDOC - Alpha ECOFF and ELF relocations. Some of these treat the symbol or - "addend" in some special way. - For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when - writing; when reading, it will be the absolute section symbol. The - addend is the displacement in bytes of the "lda" instruction from - the "ldah" instruction (which is at the address of this reloc). -ENUM - BFD_RELOC_ALPHA_GPDISP_LO16 -ENUMDOC - For GPDISP_LO16 ("ignore") relocations, the symbol is handled as - with GPDISP_HI16 relocs. The addend is ignored when writing the - relocations out, and is filled in with the file's GP value on - reading, for convenience. - -ENUM - BFD_RELOC_ALPHA_GPDISP -ENUMDOC - The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 - relocation except that there is no accompanying GPDISP_LO16 - relocation. - -ENUM - BFD_RELOC_ALPHA_LITERAL -ENUMX - BFD_RELOC_ALPHA_ELF_LITERAL -ENUMX - BFD_RELOC_ALPHA_LITUSE -ENUMDOC - The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; - the assembler turns it into a LDQ instruction to load the address of - the symbol, and then fills in a register in the real instruction. - - The LITERAL reloc, at the LDQ instruction, refers to the .lita - section symbol. The addend is ignored when writing, but is filled - in with the file's GP value on reading, for convenience, as with the - GPDISP_LO16 reloc. - - The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. - It should refer to the symbol to be referenced, as with 16_GOTOFF, - but it generates output not based on the position within the .got - section, but relative to the GP value chosen for the file during the - final link stage. - - The LITUSE reloc, on the instruction using the loaded address, gives - information to the linker that it might be able to use to optimize - away some literal section references. The symbol is ignored (read - as the absolute section symbol), and the "addend" indicates the type - of instruction using the register: - 1 - "memory" fmt insn - 2 - byte-manipulation (byte offset reg) - 3 - jsr (target of branch) - -ENUM - BFD_RELOC_ALPHA_HINT -ENUMDOC - The HINT relocation indicates a value that should be filled into the - "hint" field of a jmp/jsr/ret instruction, for possible branch- - prediction logic which may be provided on some processors. - -ENUM - BFD_RELOC_ALPHA_LINKAGE -ENUMDOC - The LINKAGE relocation outputs a linkage pair in the object file, - which is filled by the linker. - -ENUM - BFD_RELOC_ALPHA_CODEADDR -ENUMDOC - The CODEADDR relocation outputs a STO_CA in the object file, - which is filled by the linker. - -ENUM - BFD_RELOC_ALPHA_GPREL_HI16 -ENUMX - BFD_RELOC_ALPHA_GPREL_LO16 -ENUMDOC - The GPREL_HI/LO relocations together form a 32-bit offset from the - GP register. - -ENUM - BFD_RELOC_ALPHA_BRSGP -ENUMDOC - Like BFD_RELOC_23_PCREL_S2, except that the source and target must - share a common GP, and the target address is adjusted for - STO_ALPHA_STD_GPLOAD. - -ENUM - BFD_RELOC_ALPHA_NOP -ENUMDOC - The NOP relocation outputs a NOP if the longword displacement - between two procedure entry points is < 2^21. - -ENUM - BFD_RELOC_ALPHA_BSR -ENUMDOC - The BSR relocation outputs a BSR if the longword displacement - between two procedure entry points is < 2^21. - -ENUM - BFD_RELOC_ALPHA_LDA -ENUMDOC - The LDA relocation outputs a LDA if the longword displacement - between two procedure entry points is < 2^16. - -ENUM - BFD_RELOC_ALPHA_BOH -ENUMDOC - The BOH relocation outputs a BSR if the longword displacement - between two procedure entry points is < 2^21, or else a hint. - -ENUM - BFD_RELOC_ALPHA_TLSGD -ENUMX - BFD_RELOC_ALPHA_TLSLDM -ENUMX - BFD_RELOC_ALPHA_DTPMOD64 -ENUMX - BFD_RELOC_ALPHA_GOTDTPREL16 -ENUMX - BFD_RELOC_ALPHA_DTPREL64 -ENUMX - BFD_RELOC_ALPHA_DTPREL_HI16 -ENUMX - BFD_RELOC_ALPHA_DTPREL_LO16 -ENUMX - BFD_RELOC_ALPHA_DTPREL16 -ENUMX - BFD_RELOC_ALPHA_GOTTPREL16 -ENUMX - BFD_RELOC_ALPHA_TPREL64 -ENUMX - BFD_RELOC_ALPHA_TPREL_HI16 -ENUMX - BFD_RELOC_ALPHA_TPREL_LO16 -ENUMX - BFD_RELOC_ALPHA_TPREL16 -ENUMDOC - Alpha thread-local storage relocations. - -ENUM - BFD_RELOC_MIPS_JMP -ENUMX - BFD_RELOC_MICROMIPS_JMP -ENUMDOC - The MIPS jump instruction. - -ENUM - BFD_RELOC_MIPS16_JMP -ENUMDOC - The MIPS16 jump instruction. - -ENUM - BFD_RELOC_MIPS16_GPREL -ENUMDOC - MIPS16 GP relative reloc. - -ENUM - BFD_RELOC_HI16 -ENUMDOC - High 16 bits of 32-bit value; simple reloc. - -ENUM - BFD_RELOC_HI16_S -ENUMDOC - High 16 bits of 32-bit value but the low 16 bits will be sign - extended and added to form the final result. If the low 16 - bits form a negative number, we need to add one to the high value - to compensate for the borrow when the low bits are added. - -ENUM - BFD_RELOC_LO16 -ENUMDOC - Low 16 bits. - -ENUM - BFD_RELOC_HI16_PCREL -ENUMDOC - High 16 bits of 32-bit pc-relative value -ENUM - BFD_RELOC_HI16_S_PCREL -ENUMDOC - High 16 bits of 32-bit pc-relative value, adjusted -ENUM - BFD_RELOC_LO16_PCREL -ENUMDOC - Low 16 bits of pc-relative value - -ENUM - BFD_RELOC_MIPS16_GOT16 -ENUMX - BFD_RELOC_MIPS16_CALL16 -ENUMDOC - Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of - 16-bit immediate fields -ENUM - BFD_RELOC_MIPS16_HI16 -ENUMDOC - MIPS16 high 16 bits of 32-bit value. -ENUM - BFD_RELOC_MIPS16_HI16_S -ENUMDOC - MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign - extended and added to form the final result. If the low 16 - bits form a negative number, we need to add one to the high value - to compensate for the borrow when the low bits are added. -ENUM - BFD_RELOC_MIPS16_LO16 -ENUMDOC - MIPS16 low 16 bits. - -ENUM - BFD_RELOC_MIPS_LITERAL -ENUMX - BFD_RELOC_MICROMIPS_LITERAL -ENUMDOC - Relocation against a MIPS literal section. - -ENUM - BFD_RELOC_MICROMIPS_7_PCREL_S1 -ENUMX - BFD_RELOC_MICROMIPS_10_PCREL_S1 -ENUMX - BFD_RELOC_MICROMIPS_16_PCREL_S1 -ENUMDOC - microMIPS PC-relative relocations. - -ENUM - BFD_RELOC_MICROMIPS_GPREL16 -ENUMX - BFD_RELOC_MICROMIPS_HI16 -ENUMX - BFD_RELOC_MICROMIPS_HI16_S -ENUMX - BFD_RELOC_MICROMIPS_LO16 -ENUMDOC - microMIPS versions of generic BFD relocs. - -ENUM - BFD_RELOC_MIPS_GOT16 -ENUMX - BFD_RELOC_MICROMIPS_GOT16 -ENUMX - BFD_RELOC_MIPS_CALL16 -ENUMX - BFD_RELOC_MICROMIPS_CALL16 -ENUMX - BFD_RELOC_MIPS_GOT_HI16 -ENUMX - BFD_RELOC_MICROMIPS_GOT_HI16 -ENUMX - BFD_RELOC_MIPS_GOT_LO16 -ENUMX - BFD_RELOC_MICROMIPS_GOT_LO16 -ENUMX - BFD_RELOC_MIPS_CALL_HI16 -ENUMX - BFD_RELOC_MICROMIPS_CALL_HI16 -ENUMX - BFD_RELOC_MIPS_CALL_LO16 -ENUMX - BFD_RELOC_MICROMIPS_CALL_LO16 -ENUMX - BFD_RELOC_MIPS_SUB -ENUMX - BFD_RELOC_MICROMIPS_SUB -ENUMX - BFD_RELOC_MIPS_GOT_PAGE -ENUMX - BFD_RELOC_MICROMIPS_GOT_PAGE -ENUMX - BFD_RELOC_MIPS_GOT_OFST -ENUMX - BFD_RELOC_MICROMIPS_GOT_OFST -ENUMX - BFD_RELOC_MIPS_GOT_DISP -ENUMX - BFD_RELOC_MICROMIPS_GOT_DISP -ENUMX - BFD_RELOC_MIPS_SHIFT5 -ENUMX - BFD_RELOC_MIPS_SHIFT6 -ENUMX - BFD_RELOC_MIPS_INSERT_A -ENUMX - BFD_RELOC_MIPS_INSERT_B -ENUMX - BFD_RELOC_MIPS_DELETE -ENUMX - BFD_RELOC_MIPS_HIGHEST -ENUMX - BFD_RELOC_MICROMIPS_HIGHEST -ENUMX - BFD_RELOC_MIPS_HIGHER -ENUMX - BFD_RELOC_MICROMIPS_HIGHER -ENUMX - BFD_RELOC_MIPS_SCN_DISP -ENUMX - BFD_RELOC_MICROMIPS_SCN_DISP -ENUMX - BFD_RELOC_MIPS_REL16 -ENUMX - BFD_RELOC_MIPS_RELGOT -ENUMX - BFD_RELOC_MIPS_JALR -ENUMX - BFD_RELOC_MICROMIPS_JALR -ENUMX - BFD_RELOC_MIPS_TLS_DTPMOD32 -ENUMX - BFD_RELOC_MIPS_TLS_DTPREL32 -ENUMX - BFD_RELOC_MIPS_TLS_DTPMOD64 -ENUMX - BFD_RELOC_MIPS_TLS_DTPREL64 -ENUMX - BFD_RELOC_MIPS_TLS_GD -ENUMX - BFD_RELOC_MICROMIPS_TLS_GD -ENUMX - BFD_RELOC_MIPS_TLS_LDM -ENUMX - BFD_RELOC_MICROMIPS_TLS_LDM -ENUMX - BFD_RELOC_MIPS_TLS_DTPREL_HI16 -ENUMX - BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16 -ENUMX - BFD_RELOC_MIPS_TLS_DTPREL_LO16 -ENUMX - BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16 -ENUMX - BFD_RELOC_MIPS_TLS_GOTTPREL -ENUMX - BFD_RELOC_MICROMIPS_TLS_GOTTPREL -ENUMX - BFD_RELOC_MIPS_TLS_TPREL32 -ENUMX - BFD_RELOC_MIPS_TLS_TPREL64 -ENUMX - BFD_RELOC_MIPS_TLS_TPREL_HI16 -ENUMX - BFD_RELOC_MICROMIPS_TLS_TPREL_HI16 -ENUMX - BFD_RELOC_MIPS_TLS_TPREL_LO16 -ENUMX - BFD_RELOC_MICROMIPS_TLS_TPREL_LO16 -ENUMDOC - MIPS ELF relocations. -COMMENT - -ENUM - BFD_RELOC_MIPS_COPY -ENUMX - BFD_RELOC_MIPS_JUMP_SLOT -ENUMDOC - MIPS ELF relocations (VxWorks and PLT extensions). -COMMENT - -ENUM - BFD_RELOC_MOXIE_10_PCREL -ENUMDOC - Moxie ELF relocations. -COMMENT - -ENUM - BFD_RELOC_FRV_LABEL16 -ENUMX - BFD_RELOC_FRV_LABEL24 -ENUMX - BFD_RELOC_FRV_LO16 -ENUMX - BFD_RELOC_FRV_HI16 -ENUMX - BFD_RELOC_FRV_GPREL12 -ENUMX - BFD_RELOC_FRV_GPRELU12 -ENUMX - BFD_RELOC_FRV_GPREL32 -ENUMX - BFD_RELOC_FRV_GPRELHI -ENUMX - BFD_RELOC_FRV_GPRELLO -ENUMX - BFD_RELOC_FRV_GOT12 -ENUMX - BFD_RELOC_FRV_GOTHI -ENUMX - BFD_RELOC_FRV_GOTLO -ENUMX - BFD_RELOC_FRV_FUNCDESC -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOT12 -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOTHI -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOTLO -ENUMX - BFD_RELOC_FRV_FUNCDESC_VALUE -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOTOFF12 -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOTOFFHI -ENUMX - BFD_RELOC_FRV_FUNCDESC_GOTOFFLO -ENUMX - BFD_RELOC_FRV_GOTOFF12 -ENUMX - BFD_RELOC_FRV_GOTOFFHI -ENUMX - BFD_RELOC_FRV_GOTOFFLO -ENUMX - BFD_RELOC_FRV_GETTLSOFF -ENUMX - BFD_RELOC_FRV_TLSDESC_VALUE -ENUMX - BFD_RELOC_FRV_GOTTLSDESC12 -ENUMX - BFD_RELOC_FRV_GOTTLSDESCHI -ENUMX - BFD_RELOC_FRV_GOTTLSDESCLO -ENUMX - BFD_RELOC_FRV_TLSMOFF12 -ENUMX - BFD_RELOC_FRV_TLSMOFFHI -ENUMX - BFD_RELOC_FRV_TLSMOFFLO -ENUMX - BFD_RELOC_FRV_GOTTLSOFF12 -ENUMX - BFD_RELOC_FRV_GOTTLSOFFHI -ENUMX - BFD_RELOC_FRV_GOTTLSOFFLO -ENUMX - BFD_RELOC_FRV_TLSOFF -ENUMX - BFD_RELOC_FRV_TLSDESC_RELAX -ENUMX - BFD_RELOC_FRV_GETTLSOFF_RELAX -ENUMX - BFD_RELOC_FRV_TLSOFF_RELAX -ENUMX - BFD_RELOC_FRV_TLSMOFF -ENUMDOC - Fujitsu Frv Relocations. -COMMENT - -ENUM - BFD_RELOC_MN10300_GOTOFF24 -ENUMDOC - This is a 24bit GOT-relative reloc for the mn10300. -ENUM - BFD_RELOC_MN10300_GOT32 -ENUMDOC - This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes - in the instruction. -ENUM - BFD_RELOC_MN10300_GOT24 -ENUMDOC - This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes - in the instruction. -ENUM - BFD_RELOC_MN10300_GOT16 -ENUMDOC - This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes - in the instruction. -ENUM - BFD_RELOC_MN10300_COPY -ENUMDOC - Copy symbol at runtime. -ENUM - BFD_RELOC_MN10300_GLOB_DAT -ENUMDOC - Create GOT entry. -ENUM - BFD_RELOC_MN10300_JMP_SLOT -ENUMDOC - Create PLT entry. -ENUM - BFD_RELOC_MN10300_RELATIVE -ENUMDOC - Adjust by program base. -ENUM - BFD_RELOC_MN10300_SYM_DIFF -ENUMDOC - Together with another reloc targeted at the same location, - allows for a value that is the difference of two symbols - in the same section. -ENUM - BFD_RELOC_MN10300_ALIGN -ENUMDOC - The addend of this reloc is an alignment power that must - be honoured at the offset's location, regardless of linker - relaxation. -COMMENT - -ENUM - BFD_RELOC_386_GOT32 -ENUMX - BFD_RELOC_386_PLT32 -ENUMX - BFD_RELOC_386_COPY -ENUMX - BFD_RELOC_386_GLOB_DAT -ENUMX - BFD_RELOC_386_JUMP_SLOT -ENUMX - BFD_RELOC_386_RELATIVE -ENUMX - BFD_RELOC_386_GOTOFF -ENUMX - BFD_RELOC_386_GOTPC -ENUMX - BFD_RELOC_386_TLS_TPOFF -ENUMX - BFD_RELOC_386_TLS_IE -ENUMX - BFD_RELOC_386_TLS_GOTIE -ENUMX - BFD_RELOC_386_TLS_LE -ENUMX - BFD_RELOC_386_TLS_GD -ENUMX - BFD_RELOC_386_TLS_LDM -ENUMX - BFD_RELOC_386_TLS_LDO_32 -ENUMX - BFD_RELOC_386_TLS_IE_32 -ENUMX - BFD_RELOC_386_TLS_LE_32 -ENUMX - BFD_RELOC_386_TLS_DTPMOD32 -ENUMX - BFD_RELOC_386_TLS_DTPOFF32 -ENUMX - BFD_RELOC_386_TLS_TPOFF32 -ENUMX - BFD_RELOC_386_TLS_GOTDESC -ENUMX - BFD_RELOC_386_TLS_DESC_CALL -ENUMX - BFD_RELOC_386_TLS_DESC -ENUMX - BFD_RELOC_386_IRELATIVE -ENUMDOC - i386/elf relocations - -ENUM - BFD_RELOC_X86_64_GOT32 -ENUMX - BFD_RELOC_X86_64_PLT32 -ENUMX - BFD_RELOC_X86_64_COPY -ENUMX - BFD_RELOC_X86_64_GLOB_DAT -ENUMX - BFD_RELOC_X86_64_JUMP_SLOT -ENUMX - BFD_RELOC_X86_64_RELATIVE -ENUMX - BFD_RELOC_X86_64_GOTPCREL -ENUMX - BFD_RELOC_X86_64_32S -ENUMX - BFD_RELOC_X86_64_DTPMOD64 -ENUMX - BFD_RELOC_X86_64_DTPOFF64 -ENUMX - BFD_RELOC_X86_64_TPOFF64 -ENUMX - BFD_RELOC_X86_64_TLSGD -ENUMX - BFD_RELOC_X86_64_TLSLD -ENUMX - BFD_RELOC_X86_64_DTPOFF32 -ENUMX - BFD_RELOC_X86_64_GOTTPOFF -ENUMX - BFD_RELOC_X86_64_TPOFF32 -ENUMX - BFD_RELOC_X86_64_GOTOFF64 -ENUMX - BFD_RELOC_X86_64_GOTPC32 -ENUMX - BFD_RELOC_X86_64_GOT64 -ENUMX - BFD_RELOC_X86_64_GOTPCREL64 -ENUMX - BFD_RELOC_X86_64_GOTPC64 -ENUMX - BFD_RELOC_X86_64_GOTPLT64 -ENUMX - BFD_RELOC_X86_64_PLTOFF64 -ENUMX - BFD_RELOC_X86_64_GOTPC32_TLSDESC -ENUMX - BFD_RELOC_X86_64_TLSDESC_CALL -ENUMX - BFD_RELOC_X86_64_TLSDESC -ENUMX - BFD_RELOC_X86_64_IRELATIVE -ENUMDOC - x86-64/elf relocations - -ENUM - BFD_RELOC_NS32K_IMM_8 -ENUMX - BFD_RELOC_NS32K_IMM_16 -ENUMX - BFD_RELOC_NS32K_IMM_32 -ENUMX - BFD_RELOC_NS32K_IMM_8_PCREL -ENUMX - BFD_RELOC_NS32K_IMM_16_PCREL -ENUMX - BFD_RELOC_NS32K_IMM_32_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_8 -ENUMX - BFD_RELOC_NS32K_DISP_16 -ENUMX - BFD_RELOC_NS32K_DISP_32 -ENUMX - BFD_RELOC_NS32K_DISP_8_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_16_PCREL -ENUMX - BFD_RELOC_NS32K_DISP_32_PCREL -ENUMDOC - ns32k relocations - -ENUM - BFD_RELOC_PDP11_DISP_8_PCREL -ENUMX - BFD_RELOC_PDP11_DISP_6_PCREL -ENUMDOC - PDP11 relocations - -ENUM - BFD_RELOC_PJ_CODE_HI16 -ENUMX - BFD_RELOC_PJ_CODE_LO16 -ENUMX - BFD_RELOC_PJ_CODE_DIR16 -ENUMX - BFD_RELOC_PJ_CODE_DIR32 -ENUMX - BFD_RELOC_PJ_CODE_REL16 -ENUMX - BFD_RELOC_PJ_CODE_REL32 -ENUMDOC - Picojava relocs. Not all of these appear in object files. - -ENUM - BFD_RELOC_PPC_B26 -ENUMX - BFD_RELOC_PPC_BA26 -ENUMX - BFD_RELOC_PPC_TOC16 -ENUMX - BFD_RELOC_PPC_B16 -ENUMX - BFD_RELOC_PPC_B16_BRTAKEN -ENUMX - BFD_RELOC_PPC_B16_BRNTAKEN -ENUMX - BFD_RELOC_PPC_BA16 -ENUMX - BFD_RELOC_PPC_BA16_BRTAKEN -ENUMX - BFD_RELOC_PPC_BA16_BRNTAKEN -ENUMX - BFD_RELOC_PPC_COPY -ENUMX - BFD_RELOC_PPC_GLOB_DAT -ENUMX - BFD_RELOC_PPC_JMP_SLOT -ENUMX - BFD_RELOC_PPC_RELATIVE -ENUMX - BFD_RELOC_PPC_LOCAL24PC -ENUMX - BFD_RELOC_PPC_EMB_NADDR32 -ENUMX - BFD_RELOC_PPC_EMB_NADDR16 -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_LO -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_HI -ENUMX - BFD_RELOC_PPC_EMB_NADDR16_HA -ENUMX - BFD_RELOC_PPC_EMB_SDAI16 -ENUMX - BFD_RELOC_PPC_EMB_SDA2I16 -ENUMX - BFD_RELOC_PPC_EMB_SDA2REL -ENUMX - BFD_RELOC_PPC_EMB_SDA21 -ENUMX - BFD_RELOC_PPC_EMB_MRKREF -ENUMX - BFD_RELOC_PPC_EMB_RELSEC16 -ENUMX - BFD_RELOC_PPC_EMB_RELST_LO -ENUMX - BFD_RELOC_PPC_EMB_RELST_HI -ENUMX - BFD_RELOC_PPC_EMB_RELST_HA -ENUMX - BFD_RELOC_PPC_EMB_BIT_FLD -ENUMX - BFD_RELOC_PPC_EMB_RELSDA -ENUMX - BFD_RELOC_PPC64_HIGHER -ENUMX - BFD_RELOC_PPC64_HIGHER_S -ENUMX - BFD_RELOC_PPC64_HIGHEST -ENUMX - BFD_RELOC_PPC64_HIGHEST_S -ENUMX - BFD_RELOC_PPC64_TOC16_LO -ENUMX - BFD_RELOC_PPC64_TOC16_HI -ENUMX - BFD_RELOC_PPC64_TOC16_HA -ENUMX - BFD_RELOC_PPC64_TOC -ENUMX - BFD_RELOC_PPC64_PLTGOT16 -ENUMX - BFD_RELOC_PPC64_PLTGOT16_LO -ENUMX - BFD_RELOC_PPC64_PLTGOT16_HI -ENUMX - BFD_RELOC_PPC64_PLTGOT16_HA -ENUMX - BFD_RELOC_PPC64_ADDR16_DS -ENUMX - BFD_RELOC_PPC64_ADDR16_LO_DS -ENUMX - BFD_RELOC_PPC64_GOT16_DS -ENUMX - BFD_RELOC_PPC64_GOT16_LO_DS -ENUMX - BFD_RELOC_PPC64_PLT16_LO_DS -ENUMX - BFD_RELOC_PPC64_SECTOFF_DS -ENUMX - BFD_RELOC_PPC64_SECTOFF_LO_DS -ENUMX - BFD_RELOC_PPC64_TOC16_DS -ENUMX - BFD_RELOC_PPC64_TOC16_LO_DS -ENUMX - BFD_RELOC_PPC64_PLTGOT16_DS -ENUMX - BFD_RELOC_PPC64_PLTGOT16_LO_DS -ENUMDOC - Power(rs6000) and PowerPC relocations. - -ENUM - BFD_RELOC_PPC_TLS -ENUMX - BFD_RELOC_PPC_TLSGD -ENUMX - BFD_RELOC_PPC_TLSLD -ENUMX - BFD_RELOC_PPC_DTPMOD -ENUMX - BFD_RELOC_PPC_TPREL16 -ENUMX - BFD_RELOC_PPC_TPREL16_LO -ENUMX - BFD_RELOC_PPC_TPREL16_HI -ENUMX - BFD_RELOC_PPC_TPREL16_HA -ENUMX - BFD_RELOC_PPC_TPREL -ENUMX - BFD_RELOC_PPC_DTPREL16 -ENUMX - BFD_RELOC_PPC_DTPREL16_LO -ENUMX - BFD_RELOC_PPC_DTPREL16_HI -ENUMX - BFD_RELOC_PPC_DTPREL16_HA -ENUMX - BFD_RELOC_PPC_DTPREL -ENUMX - BFD_RELOC_PPC_GOT_TLSGD16 -ENUMX - BFD_RELOC_PPC_GOT_TLSGD16_LO -ENUMX - BFD_RELOC_PPC_GOT_TLSGD16_HI -ENUMX - BFD_RELOC_PPC_GOT_TLSGD16_HA -ENUMX - BFD_RELOC_PPC_GOT_TLSLD16 -ENUMX - BFD_RELOC_PPC_GOT_TLSLD16_LO -ENUMX - BFD_RELOC_PPC_GOT_TLSLD16_HI -ENUMX - BFD_RELOC_PPC_GOT_TLSLD16_HA -ENUMX - BFD_RELOC_PPC_GOT_TPREL16 -ENUMX - BFD_RELOC_PPC_GOT_TPREL16_LO -ENUMX - BFD_RELOC_PPC_GOT_TPREL16_HI -ENUMX - BFD_RELOC_PPC_GOT_TPREL16_HA -ENUMX - BFD_RELOC_PPC_GOT_DTPREL16 -ENUMX - BFD_RELOC_PPC_GOT_DTPREL16_LO -ENUMX - BFD_RELOC_PPC_GOT_DTPREL16_HI -ENUMX - BFD_RELOC_PPC_GOT_DTPREL16_HA -ENUMX - BFD_RELOC_PPC64_TPREL16_DS -ENUMX - BFD_RELOC_PPC64_TPREL16_LO_DS -ENUMX - BFD_RELOC_PPC64_TPREL16_HIGHER -ENUMX - BFD_RELOC_PPC64_TPREL16_HIGHERA -ENUMX - BFD_RELOC_PPC64_TPREL16_HIGHEST -ENUMX - BFD_RELOC_PPC64_TPREL16_HIGHESTA -ENUMX - BFD_RELOC_PPC64_DTPREL16_DS -ENUMX - BFD_RELOC_PPC64_DTPREL16_LO_DS -ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGHER -ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGHERA -ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGHEST -ENUMX - BFD_RELOC_PPC64_DTPREL16_HIGHESTA -ENUMDOC - PowerPC and PowerPC64 thread-local storage relocations. - -ENUM - BFD_RELOC_I370_D12 -ENUMDOC - IBM 370/390 relocations - -ENUM - BFD_RELOC_CTOR -ENUMDOC - The type of reloc used to build a constructor table - at the moment - probably a 32 bit wide absolute relocation, but the target can choose. - It generally does map to one of the other relocation types. - -ENUM - BFD_RELOC_ARM_PCREL_BRANCH -ENUMDOC - ARM 26 bit pc-relative branch. The lowest two bits must be zero and are - not stored in the instruction. -ENUM - BFD_RELOC_ARM_PCREL_BLX -ENUMDOC - ARM 26 bit pc-relative branch. The lowest bit must be zero and is - not stored in the instruction. The 2nd lowest bit comes from a 1 bit - field in the instruction. -ENUM - BFD_RELOC_THUMB_PCREL_BLX -ENUMDOC - Thumb 22 bit pc-relative branch. The lowest bit must be zero and is - not stored in the instruction. The 2nd lowest bit comes from a 1 bit - field in the instruction. -ENUM - BFD_RELOC_ARM_PCREL_CALL -ENUMDOC - ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. -ENUM - BFD_RELOC_ARM_PCREL_JUMP -ENUMDOC - ARM 26-bit pc-relative branch for B or conditional BL instruction. - -ENUM - BFD_RELOC_THUMB_PCREL_BRANCH7 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH9 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH12 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH20 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH23 -ENUMX - BFD_RELOC_THUMB_PCREL_BRANCH25 -ENUMDOC - Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. - The lowest bit must be zero and is not stored in the instruction. - Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an - "nn" one smaller in all cases. Note further that BRANCH23 - corresponds to R_ARM_THM_CALL. - -ENUM - BFD_RELOC_ARM_OFFSET_IMM -ENUMDOC - 12-bit immediate offset, used in ARM-format ldr and str instructions. - -ENUM - BFD_RELOC_ARM_THUMB_OFFSET -ENUMDOC - 5-bit immediate offset, used in Thumb-format ldr and str instructions. - -ENUM - BFD_RELOC_ARM_TARGET1 -ENUMDOC - Pc-relative or absolute relocation depending on target. Used for - entries in .init_array sections. -ENUM - BFD_RELOC_ARM_ROSEGREL32 -ENUMDOC - Read-only segment base relative address. -ENUM - BFD_RELOC_ARM_SBREL32 -ENUMDOC - Data segment base relative address. -ENUM - BFD_RELOC_ARM_TARGET2 -ENUMDOC - This reloc is used for references to RTTI data from exception handling - tables. The actual definition depends on the target. It may be a - pc-relative or some form of GOT-indirect relocation. -ENUM - BFD_RELOC_ARM_PREL31 -ENUMDOC - 31-bit PC relative address. -ENUM - BFD_RELOC_ARM_MOVW -ENUMX - BFD_RELOC_ARM_MOVT -ENUMX - BFD_RELOC_ARM_MOVW_PCREL -ENUMX - BFD_RELOC_ARM_MOVT_PCREL -ENUMX - BFD_RELOC_ARM_THUMB_MOVW -ENUMX - BFD_RELOC_ARM_THUMB_MOVT -ENUMX - BFD_RELOC_ARM_THUMB_MOVW_PCREL -ENUMX - BFD_RELOC_ARM_THUMB_MOVT_PCREL -ENUMDOC - Low and High halfword relocations for MOVW and MOVT instructions. - -ENUM - BFD_RELOC_ARM_JUMP_SLOT -ENUMX - BFD_RELOC_ARM_GLOB_DAT -ENUMX - BFD_RELOC_ARM_GOT32 -ENUMX - BFD_RELOC_ARM_PLT32 -ENUMX - BFD_RELOC_ARM_RELATIVE -ENUMX - BFD_RELOC_ARM_GOTOFF -ENUMX - BFD_RELOC_ARM_GOTPC -ENUMX - BFD_RELOC_ARM_GOT_PREL -ENUMDOC - Relocations for setting up GOTs and PLTs for shared libraries. - -ENUM - BFD_RELOC_ARM_TLS_GD32 -ENUMX - BFD_RELOC_ARM_TLS_LDO32 -ENUMX - BFD_RELOC_ARM_TLS_LDM32 -ENUMX - BFD_RELOC_ARM_TLS_DTPOFF32 -ENUMX - BFD_RELOC_ARM_TLS_DTPMOD32 -ENUMX - BFD_RELOC_ARM_TLS_TPOFF32 -ENUMX - BFD_RELOC_ARM_TLS_IE32 -ENUMX - BFD_RELOC_ARM_TLS_LE32 -ENUMX - BFD_RELOC_ARM_TLS_GOTDESC -ENUMX - BFD_RELOC_ARM_TLS_CALL -ENUMX - BFD_RELOC_ARM_THM_TLS_CALL -ENUMX - BFD_RELOC_ARM_TLS_DESCSEQ -ENUMX - BFD_RELOC_ARM_THM_TLS_DESCSEQ -ENUMX - BFD_RELOC_ARM_TLS_DESC -ENUMDOC - ARM thread-local storage relocations. - -ENUM - BFD_RELOC_ARM_ALU_PC_G0_NC -ENUMX - BFD_RELOC_ARM_ALU_PC_G0 -ENUMX - BFD_RELOC_ARM_ALU_PC_G1_NC -ENUMX - BFD_RELOC_ARM_ALU_PC_G1 -ENUMX - BFD_RELOC_ARM_ALU_PC_G2 -ENUMX - BFD_RELOC_ARM_LDR_PC_G0 -ENUMX - BFD_RELOC_ARM_LDR_PC_G1 -ENUMX - BFD_RELOC_ARM_LDR_PC_G2 -ENUMX - BFD_RELOC_ARM_LDRS_PC_G0 -ENUMX - BFD_RELOC_ARM_LDRS_PC_G1 -ENUMX - BFD_RELOC_ARM_LDRS_PC_G2 -ENUMX - BFD_RELOC_ARM_LDC_PC_G0 -ENUMX - BFD_RELOC_ARM_LDC_PC_G1 -ENUMX - BFD_RELOC_ARM_LDC_PC_G2 -ENUMX - BFD_RELOC_ARM_ALU_SB_G0_NC -ENUMX - BFD_RELOC_ARM_ALU_SB_G0 -ENUMX - BFD_RELOC_ARM_ALU_SB_G1_NC -ENUMX - BFD_RELOC_ARM_ALU_SB_G1 -ENUMX - BFD_RELOC_ARM_ALU_SB_G2 -ENUMX - BFD_RELOC_ARM_LDR_SB_G0 -ENUMX - BFD_RELOC_ARM_LDR_SB_G1 -ENUMX - BFD_RELOC_ARM_LDR_SB_G2 -ENUMX - BFD_RELOC_ARM_LDRS_SB_G0 -ENUMX - BFD_RELOC_ARM_LDRS_SB_G1 -ENUMX - BFD_RELOC_ARM_LDRS_SB_G2 -ENUMX - BFD_RELOC_ARM_LDC_SB_G0 -ENUMX - BFD_RELOC_ARM_LDC_SB_G1 -ENUMX - BFD_RELOC_ARM_LDC_SB_G2 -ENUMDOC - ARM group relocations. - -ENUM - BFD_RELOC_ARM_V4BX -ENUMDOC - Annotation of BX instructions. - -ENUM - BFD_RELOC_ARM_IRELATIVE -ENUMDOC - ARM support for STT_GNU_IFUNC. - -ENUM - BFD_RELOC_ARM_IMMEDIATE -ENUMX - BFD_RELOC_ARM_ADRL_IMMEDIATE -ENUMX - BFD_RELOC_ARM_T32_IMMEDIATE -ENUMX - BFD_RELOC_ARM_T32_ADD_IMM -ENUMX - BFD_RELOC_ARM_T32_IMM12 -ENUMX - BFD_RELOC_ARM_T32_ADD_PC12 -ENUMX - BFD_RELOC_ARM_SHIFT_IMM -ENUMX - BFD_RELOC_ARM_SMC -ENUMX - BFD_RELOC_ARM_HVC -ENUMX - BFD_RELOC_ARM_SWI -ENUMX - BFD_RELOC_ARM_MULTI -ENUMX - BFD_RELOC_ARM_CP_OFF_IMM -ENUMX - BFD_RELOC_ARM_CP_OFF_IMM_S2 -ENUMX - BFD_RELOC_ARM_T32_CP_OFF_IMM -ENUMX - BFD_RELOC_ARM_T32_CP_OFF_IMM_S2 -ENUMX - BFD_RELOC_ARM_ADR_IMM -ENUMX - BFD_RELOC_ARM_LDR_IMM -ENUMX - BFD_RELOC_ARM_LITERAL -ENUMX - BFD_RELOC_ARM_IN_POOL -ENUMX - BFD_RELOC_ARM_OFFSET_IMM8 -ENUMX - BFD_RELOC_ARM_T32_OFFSET_U8 -ENUMX - BFD_RELOC_ARM_T32_OFFSET_IMM -ENUMX - BFD_RELOC_ARM_HWLITERAL -ENUMX - BFD_RELOC_ARM_THUMB_ADD -ENUMX - BFD_RELOC_ARM_THUMB_IMM -ENUMX - BFD_RELOC_ARM_THUMB_SHIFT -ENUMDOC - These relocs are only used within the ARM assembler. They are not - (at present) written to any object files. - -ENUM - BFD_RELOC_SH_PCDISP8BY2 -ENUMX - BFD_RELOC_SH_PCDISP12BY2 -ENUMX - BFD_RELOC_SH_IMM3 -ENUMX - BFD_RELOC_SH_IMM3U -ENUMX - BFD_RELOC_SH_DISP12 -ENUMX - BFD_RELOC_SH_DISP12BY2 -ENUMX - BFD_RELOC_SH_DISP12BY4 -ENUMX - BFD_RELOC_SH_DISP12BY8 -ENUMX - BFD_RELOC_SH_DISP20 -ENUMX - BFD_RELOC_SH_DISP20BY8 -ENUMX - BFD_RELOC_SH_IMM4 -ENUMX - BFD_RELOC_SH_IMM4BY2 -ENUMX - BFD_RELOC_SH_IMM4BY4 -ENUMX - BFD_RELOC_SH_IMM8 -ENUMX - BFD_RELOC_SH_IMM8BY2 -ENUMX - BFD_RELOC_SH_IMM8BY4 -ENUMX - BFD_RELOC_SH_PCRELIMM8BY2 -ENUMX - BFD_RELOC_SH_PCRELIMM8BY4 -ENUMX - BFD_RELOC_SH_SWITCH16 -ENUMX - BFD_RELOC_SH_SWITCH32 -ENUMX - BFD_RELOC_SH_USES -ENUMX - BFD_RELOC_SH_COUNT -ENUMX - BFD_RELOC_SH_ALIGN -ENUMX - BFD_RELOC_SH_CODE -ENUMX - BFD_RELOC_SH_DATA -ENUMX - BFD_RELOC_SH_LABEL -ENUMX - BFD_RELOC_SH_LOOP_START -ENUMX - BFD_RELOC_SH_LOOP_END -ENUMX - BFD_RELOC_SH_COPY -ENUMX - BFD_RELOC_SH_GLOB_DAT -ENUMX - BFD_RELOC_SH_JMP_SLOT -ENUMX - BFD_RELOC_SH_RELATIVE -ENUMX - BFD_RELOC_SH_GOTPC -ENUMX - BFD_RELOC_SH_GOT_LOW16 -ENUMX - BFD_RELOC_SH_GOT_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOT_MEDHI16 -ENUMX - BFD_RELOC_SH_GOT_HI16 -ENUMX - BFD_RELOC_SH_GOTPLT_LOW16 -ENUMX - BFD_RELOC_SH_GOTPLT_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTPLT_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTPLT_HI16 -ENUMX - BFD_RELOC_SH_PLT_LOW16 -ENUMX - BFD_RELOC_SH_PLT_MEDLOW16 -ENUMX - BFD_RELOC_SH_PLT_MEDHI16 -ENUMX - BFD_RELOC_SH_PLT_HI16 -ENUMX - BFD_RELOC_SH_GOTOFF_LOW16 -ENUMX - BFD_RELOC_SH_GOTOFF_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTOFF_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTOFF_HI16 -ENUMX - BFD_RELOC_SH_GOTPC_LOW16 -ENUMX - BFD_RELOC_SH_GOTPC_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTPC_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTPC_HI16 -ENUMX - BFD_RELOC_SH_COPY64 -ENUMX - BFD_RELOC_SH_GLOB_DAT64 -ENUMX - BFD_RELOC_SH_JMP_SLOT64 -ENUMX - BFD_RELOC_SH_RELATIVE64 -ENUMX - BFD_RELOC_SH_GOT10BY4 -ENUMX - BFD_RELOC_SH_GOT10BY8 -ENUMX - BFD_RELOC_SH_GOTPLT10BY4 -ENUMX - BFD_RELOC_SH_GOTPLT10BY8 -ENUMX - BFD_RELOC_SH_GOTPLT32 -ENUMX - BFD_RELOC_SH_SHMEDIA_CODE -ENUMX - BFD_RELOC_SH_IMMU5 -ENUMX - BFD_RELOC_SH_IMMS6 -ENUMX - BFD_RELOC_SH_IMMS6BY32 -ENUMX - BFD_RELOC_SH_IMMU6 -ENUMX - BFD_RELOC_SH_IMMS10 -ENUMX - BFD_RELOC_SH_IMMS10BY2 -ENUMX - BFD_RELOC_SH_IMMS10BY4 -ENUMX - BFD_RELOC_SH_IMMS10BY8 -ENUMX - BFD_RELOC_SH_IMMS16 -ENUMX - BFD_RELOC_SH_IMMU16 -ENUMX - BFD_RELOC_SH_IMM_LOW16 -ENUMX - BFD_RELOC_SH_IMM_LOW16_PCREL -ENUMX - BFD_RELOC_SH_IMM_MEDLOW16 -ENUMX - BFD_RELOC_SH_IMM_MEDLOW16_PCREL -ENUMX - BFD_RELOC_SH_IMM_MEDHI16 -ENUMX - BFD_RELOC_SH_IMM_MEDHI16_PCREL -ENUMX - BFD_RELOC_SH_IMM_HI16 -ENUMX - BFD_RELOC_SH_IMM_HI16_PCREL -ENUMX - BFD_RELOC_SH_PT_16 -ENUMX - BFD_RELOC_SH_TLS_GD_32 -ENUMX - BFD_RELOC_SH_TLS_LD_32 -ENUMX - BFD_RELOC_SH_TLS_LDO_32 -ENUMX - BFD_RELOC_SH_TLS_IE_32 -ENUMX - BFD_RELOC_SH_TLS_LE_32 -ENUMX - BFD_RELOC_SH_TLS_DTPMOD32 -ENUMX - BFD_RELOC_SH_TLS_DTPOFF32 -ENUMX - BFD_RELOC_SH_TLS_TPOFF32 -ENUMX - BFD_RELOC_SH_GOT20 -ENUMX - BFD_RELOC_SH_GOTOFF20 -ENUMX - BFD_RELOC_SH_GOTFUNCDESC -ENUMX - BFD_RELOC_SH_GOTFUNCDESC20 -ENUMX - BFD_RELOC_SH_GOTOFFFUNCDESC -ENUMX - BFD_RELOC_SH_GOTOFFFUNCDESC20 -ENUMX - BFD_RELOC_SH_FUNCDESC -ENUMDOC - Renesas / SuperH SH relocs. Not all of these appear in object files. - -ENUM - BFD_RELOC_ARC_B22_PCREL -ENUMDOC - ARC Cores relocs. - ARC 22 bit pc-relative branch. The lowest two bits must be zero and are - not stored in the instruction. The high 20 bits are installed in bits 26 - through 7 of the instruction. -ENUM - BFD_RELOC_ARC_B26 -ENUMDOC - ARC 26 bit absolute branch. The lowest two bits must be zero and are not - stored in the instruction. The high 24 bits are installed in bits 23 - through 0. - -ENUM - BFD_RELOC_BFIN_16_IMM -ENUMDOC - ADI Blackfin 16 bit immediate absolute reloc. -ENUM - BFD_RELOC_BFIN_16_HIGH -ENUMDOC - ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. -ENUM - BFD_RELOC_BFIN_4_PCREL -ENUMDOC - ADI Blackfin 'a' part of LSETUP. -ENUM - BFD_RELOC_BFIN_5_PCREL -ENUMDOC - ADI Blackfin. -ENUM - BFD_RELOC_BFIN_16_LOW -ENUMDOC - ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. -ENUM - BFD_RELOC_BFIN_10_PCREL -ENUMDOC - ADI Blackfin. -ENUM - BFD_RELOC_BFIN_11_PCREL -ENUMDOC - ADI Blackfin 'b' part of LSETUP. -ENUM - BFD_RELOC_BFIN_12_PCREL_JUMP -ENUMDOC - ADI Blackfin. -ENUM - BFD_RELOC_BFIN_12_PCREL_JUMP_S -ENUMDOC - ADI Blackfin Short jump, pcrel. -ENUM - BFD_RELOC_BFIN_24_PCREL_CALL_X -ENUMDOC - ADI Blackfin Call.x not implemented. -ENUM - BFD_RELOC_BFIN_24_PCREL_JUMP_L -ENUMDOC - ADI Blackfin Long Jump pcrel. -ENUM - BFD_RELOC_BFIN_GOT17M4 -ENUMX - BFD_RELOC_BFIN_GOTHI -ENUMX - BFD_RELOC_BFIN_GOTLO -ENUMX - BFD_RELOC_BFIN_FUNCDESC -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOT17M4 -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOTHI -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOTLO -ENUMX - BFD_RELOC_BFIN_FUNCDESC_VALUE -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4 -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI -ENUMX - BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO -ENUMX - BFD_RELOC_BFIN_GOTOFF17M4 -ENUMX - BFD_RELOC_BFIN_GOTOFFHI -ENUMX - BFD_RELOC_BFIN_GOTOFFLO -ENUMDOC - ADI Blackfin FD-PIC relocations. -ENUM - BFD_RELOC_BFIN_GOT -ENUMDOC - ADI Blackfin GOT relocation. -ENUM - BFD_RELOC_BFIN_PLTPC -ENUMDOC - ADI Blackfin PLTPC relocation. -ENUM - BFD_ARELOC_BFIN_PUSH -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_CONST -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_ADD -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_SUB -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_MULT -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_DIV -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_MOD -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_LSHIFT -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_RSHIFT -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_AND -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_OR -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_XOR -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_LAND -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_LOR -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_LEN -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_NEG -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_COMP -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_PAGE -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_HWPAGE -ENUMDOC - ADI Blackfin arithmetic relocation. -ENUM - BFD_ARELOC_BFIN_ADDR -ENUMDOC - ADI Blackfin arithmetic relocation. - -ENUM - BFD_RELOC_D10V_10_PCREL_R -ENUMDOC - Mitsubishi D10V relocs. - This is a 10-bit reloc with the right 2 bits - assumed to be 0. -ENUM - BFD_RELOC_D10V_10_PCREL_L -ENUMDOC - Mitsubishi D10V relocs. - This is a 10-bit reloc with the right 2 bits - assumed to be 0. This is the same as the previous reloc - except it is in the left container, i.e., - shifted left 15 bits. -ENUM - BFD_RELOC_D10V_18 -ENUMDOC - This is an 18-bit reloc with the right 2 bits - assumed to be 0. -ENUM - BFD_RELOC_D10V_18_PCREL -ENUMDOC - This is an 18-bit reloc with the right 2 bits - assumed to be 0. - -ENUM - BFD_RELOC_D30V_6 -ENUMDOC - Mitsubishi D30V relocs. - This is a 6-bit absolute reloc. -ENUM - BFD_RELOC_D30V_9_PCREL -ENUMDOC - This is a 6-bit pc-relative reloc with - the right 3 bits assumed to be 0. -ENUM - BFD_RELOC_D30V_9_PCREL_R -ENUMDOC - This is a 6-bit pc-relative reloc with - the right 3 bits assumed to be 0. Same - as the previous reloc but on the right side - of the container. -ENUM - BFD_RELOC_D30V_15 -ENUMDOC - This is a 12-bit absolute reloc with the - right 3 bitsassumed to be 0. -ENUM - BFD_RELOC_D30V_15_PCREL -ENUMDOC - This is a 12-bit pc-relative reloc with - the right 3 bits assumed to be 0. -ENUM - BFD_RELOC_D30V_15_PCREL_R -ENUMDOC - This is a 12-bit pc-relative reloc with - the right 3 bits assumed to be 0. Same - as the previous reloc but on the right side - of the container. -ENUM - BFD_RELOC_D30V_21 -ENUMDOC - This is an 18-bit absolute reloc with - the right 3 bits assumed to be 0. -ENUM - BFD_RELOC_D30V_21_PCREL -ENUMDOC - This is an 18-bit pc-relative reloc with - the right 3 bits assumed to be 0. -ENUM - BFD_RELOC_D30V_21_PCREL_R -ENUMDOC - This is an 18-bit pc-relative reloc with - the right 3 bits assumed to be 0. Same - as the previous reloc but on the right side - of the container. -ENUM - BFD_RELOC_D30V_32 -ENUMDOC - This is a 32-bit absolute reloc. -ENUM - BFD_RELOC_D30V_32_PCREL -ENUMDOC - This is a 32-bit pc-relative reloc. - -ENUM - BFD_RELOC_DLX_HI16_S -ENUMDOC - DLX relocs -ENUM - BFD_RELOC_DLX_LO16 -ENUMDOC - DLX relocs -ENUM - BFD_RELOC_DLX_JMP26 -ENUMDOC - DLX relocs - -ENUM - BFD_RELOC_M32C_HI8 -ENUMX - BFD_RELOC_M32C_RL_JUMP -ENUMX - BFD_RELOC_M32C_RL_1ADDR -ENUMX - BFD_RELOC_M32C_RL_2ADDR -ENUMDOC - Renesas M16C/M32C Relocations. - -ENUM - BFD_RELOC_M32R_24 -ENUMDOC - Renesas M32R (formerly Mitsubishi M32R) relocs. - This is a 24 bit absolute address. -ENUM - BFD_RELOC_M32R_10_PCREL -ENUMDOC - This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. -ENUM - BFD_RELOC_M32R_18_PCREL -ENUMDOC - This is an 18-bit reloc with the right 2 bits assumed to be 0. -ENUM - BFD_RELOC_M32R_26_PCREL -ENUMDOC - This is a 26-bit reloc with the right 2 bits assumed to be 0. -ENUM - BFD_RELOC_M32R_HI16_ULO -ENUMDOC - This is a 16-bit reloc containing the high 16 bits of an address - used when the lower 16 bits are treated as unsigned. -ENUM - BFD_RELOC_M32R_HI16_SLO -ENUMDOC - This is a 16-bit reloc containing the high 16 bits of an address - used when the lower 16 bits are treated as signed. -ENUM - BFD_RELOC_M32R_LO16 -ENUMDOC - This is a 16-bit reloc containing the lower 16 bits of an address. -ENUM - BFD_RELOC_M32R_SDA16 -ENUMDOC - This is a 16-bit reloc containing the small data area offset for use in - add3, load, and store instructions. -ENUM - BFD_RELOC_M32R_GOT24 -ENUMX - BFD_RELOC_M32R_26_PLTREL -ENUMX - BFD_RELOC_M32R_COPY -ENUMX - BFD_RELOC_M32R_GLOB_DAT -ENUMX - BFD_RELOC_M32R_JMP_SLOT -ENUMX - BFD_RELOC_M32R_RELATIVE -ENUMX - BFD_RELOC_M32R_GOTOFF -ENUMX - BFD_RELOC_M32R_GOTOFF_HI_ULO -ENUMX - BFD_RELOC_M32R_GOTOFF_HI_SLO -ENUMX - BFD_RELOC_M32R_GOTOFF_LO -ENUMX - BFD_RELOC_M32R_GOTPC24 -ENUMX - BFD_RELOC_M32R_GOT16_HI_ULO -ENUMX - BFD_RELOC_M32R_GOT16_HI_SLO -ENUMX - BFD_RELOC_M32R_GOT16_LO -ENUMX - BFD_RELOC_M32R_GOTPC_HI_ULO -ENUMX - BFD_RELOC_M32R_GOTPC_HI_SLO -ENUMX - BFD_RELOC_M32R_GOTPC_LO -ENUMDOC - For PIC. - - -ENUM - BFD_RELOC_V850_9_PCREL -ENUMDOC - This is a 9-bit reloc -ENUM - BFD_RELOC_V850_22_PCREL -ENUMDOC - This is a 22-bit reloc - -ENUM - BFD_RELOC_V850_SDA_16_16_OFFSET -ENUMDOC - This is a 16 bit offset from the short data area pointer. -ENUM - BFD_RELOC_V850_SDA_15_16_OFFSET -ENUMDOC - This is a 16 bit offset (of which only 15 bits are used) from the - short data area pointer. -ENUM - BFD_RELOC_V850_ZDA_16_16_OFFSET -ENUMDOC - This is a 16 bit offset from the zero data area pointer. -ENUM - BFD_RELOC_V850_ZDA_15_16_OFFSET -ENUMDOC - This is a 16 bit offset (of which only 15 bits are used) from the - zero data area pointer. -ENUM - BFD_RELOC_V850_TDA_6_8_OFFSET -ENUMDOC - This is an 8 bit offset (of which only 6 bits are used) from the - tiny data area pointer. -ENUM - BFD_RELOC_V850_TDA_7_8_OFFSET -ENUMDOC - This is an 8bit offset (of which only 7 bits are used) from the tiny - data area pointer. -ENUM - BFD_RELOC_V850_TDA_7_7_OFFSET -ENUMDOC - This is a 7 bit offset from the tiny data area pointer. -ENUM - BFD_RELOC_V850_TDA_16_16_OFFSET -ENUMDOC - This is a 16 bit offset from the tiny data area pointer. -COMMENT -ENUM - BFD_RELOC_V850_TDA_4_5_OFFSET -ENUMDOC - This is a 5 bit offset (of which only 4 bits are used) from the tiny - data area pointer. -ENUM - BFD_RELOC_V850_TDA_4_4_OFFSET -ENUMDOC - This is a 4 bit offset from the tiny data area pointer. -ENUM - BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET -ENUMDOC - This is a 16 bit offset from the short data area pointer, with the - bits placed non-contiguously in the instruction. -ENUM - BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET -ENUMDOC - This is a 16 bit offset from the zero data area pointer, with the - bits placed non-contiguously in the instruction. -ENUM - BFD_RELOC_V850_CALLT_6_7_OFFSET -ENUMDOC - This is a 6 bit offset from the call table base pointer. -ENUM - BFD_RELOC_V850_CALLT_16_16_OFFSET -ENUMDOC - This is a 16 bit offset from the call table base pointer. -ENUM - BFD_RELOC_V850_LONGCALL -ENUMDOC - Used for relaxing indirect function calls. -ENUM - BFD_RELOC_V850_LONGJUMP -ENUMDOC - Used for relaxing indirect jumps. -ENUM - BFD_RELOC_V850_ALIGN -ENUMDOC - Used to maintain alignment whilst relaxing. -ENUM - BFD_RELOC_V850_LO16_SPLIT_OFFSET -ENUMDOC - This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu - instructions. -ENUM - BFD_RELOC_V850_16_PCREL -ENUMDOC - This is a 16-bit reloc. -ENUM - BFD_RELOC_V850_17_PCREL -ENUMDOC - This is a 17-bit reloc. -ENUM - BFD_RELOC_V850_23 -ENUMDOC - This is a 23-bit reloc. -ENUM - BFD_RELOC_V850_32_PCREL -ENUMDOC - This is a 32-bit reloc. -ENUM - BFD_RELOC_V850_32_ABS -ENUMDOC - This is a 32-bit reloc. -ENUM - BFD_RELOC_V850_16_SPLIT_OFFSET -ENUMDOC - This is a 16-bit reloc. -ENUM - BFD_RELOC_V850_16_S1 -ENUMDOC - This is a 16-bit reloc. -ENUM - BFD_RELOC_V850_LO16_S1 -ENUMDOC - Low 16 bits. 16 bit shifted by 1. -ENUM - BFD_RELOC_V850_CALLT_15_16_OFFSET -ENUMDOC - This is a 16 bit offset from the call table base pointer. -ENUM - BFD_RELOC_V850_32_GOTPCREL -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_16_GOT -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_32_GOT -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_22_PLT_PCREL -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_32_PLT_PCREL -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_COPY -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_GLOB_DAT -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_JMP_SLOT -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_RELATIVE -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_16_GOTOFF -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_32_GOTOFF -ENUMDOC - DSO relocations. -ENUM - BFD_RELOC_V850_CODE -ENUMDOC - start code. -ENUM - BFD_RELOC_V850_DATA -ENUMDOC - start data in text. -ENUM - BFD_RELOC_MN10300_32_PCREL -ENUMDOC - This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the - instruction. -ENUM - BFD_RELOC_MN10300_16_PCREL -ENUMDOC - This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the - instruction. - -ENUM - BFD_RELOC_TIC30_LDP -ENUMDOC - This is a 8bit DP reloc for the tms320c30, where the most - significant 8 bits of a 24 bit word are placed into the least - significant 8 bits of the opcode. - -ENUM - BFD_RELOC_TIC54X_PARTLS7 -ENUMDOC - This is a 7bit reloc for the tms320c54x, where the least - significant 7 bits of a 16 bit word are placed into the least - significant 7 bits of the opcode. - -ENUM - BFD_RELOC_TIC54X_PARTMS9 -ENUMDOC - This is a 9bit DP reloc for the tms320c54x, where the most - significant 9 bits of a 16 bit word are placed into the least - significant 9 bits of the opcode. - -ENUM - BFD_RELOC_TIC54X_23 -ENUMDOC - This is an extended address 23-bit reloc for the tms320c54x. - -ENUM - BFD_RELOC_TIC54X_16_OF_23 -ENUMDOC - This is a 16-bit reloc for the tms320c54x, where the least - significant 16 bits of a 23-bit extended address are placed into - the opcode. - -ENUM - BFD_RELOC_TIC54X_MS7_OF_23 -ENUMDOC - This is a reloc for the tms320c54x, where the most - significant 7 bits of a 23-bit extended address are placed into - the opcode. - -ENUM - BFD_RELOC_C6000_PCR_S21 -ENUMX - BFD_RELOC_C6000_PCR_S12 -ENUMX - BFD_RELOC_C6000_PCR_S10 -ENUMX - BFD_RELOC_C6000_PCR_S7 -ENUMX - BFD_RELOC_C6000_ABS_S16 -ENUMX - BFD_RELOC_C6000_ABS_L16 -ENUMX - BFD_RELOC_C6000_ABS_H16 -ENUMX - BFD_RELOC_C6000_SBR_U15_B -ENUMX - BFD_RELOC_C6000_SBR_U15_H -ENUMX - BFD_RELOC_C6000_SBR_U15_W -ENUMX - BFD_RELOC_C6000_SBR_S16 -ENUMX - BFD_RELOC_C6000_SBR_L16_B -ENUMX - BFD_RELOC_C6000_SBR_L16_H -ENUMX - BFD_RELOC_C6000_SBR_L16_W -ENUMX - BFD_RELOC_C6000_SBR_H16_B -ENUMX - BFD_RELOC_C6000_SBR_H16_H -ENUMX - BFD_RELOC_C6000_SBR_H16_W -ENUMX - BFD_RELOC_C6000_SBR_GOT_U15_W -ENUMX - BFD_RELOC_C6000_SBR_GOT_L16_W -ENUMX - BFD_RELOC_C6000_SBR_GOT_H16_W -ENUMX - BFD_RELOC_C6000_DSBT_INDEX -ENUMX - BFD_RELOC_C6000_PREL31 -ENUMX - BFD_RELOC_C6000_COPY -ENUMX - BFD_RELOC_C6000_JUMP_SLOT -ENUMX - BFD_RELOC_C6000_EHTYPE -ENUMX - BFD_RELOC_C6000_PCR_H16 -ENUMX - BFD_RELOC_C6000_PCR_L16 -ENUMX - BFD_RELOC_C6000_ALIGN -ENUMX - BFD_RELOC_C6000_FPHEAD -ENUMX - BFD_RELOC_C6000_NOCMP -ENUMDOC - TMS320C6000 relocations. - -ENUM - BFD_RELOC_FR30_48 -ENUMDOC - This is a 48 bit reloc for the FR30 that stores 32 bits. -ENUM - BFD_RELOC_FR30_20 -ENUMDOC - This is a 32 bit reloc for the FR30 that stores 20 bits split up into - two sections. -ENUM - BFD_RELOC_FR30_6_IN_4 -ENUMDOC - This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in - 4 bits. -ENUM - BFD_RELOC_FR30_8_IN_8 -ENUMDOC - This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset - into 8 bits. -ENUM - BFD_RELOC_FR30_9_IN_8 -ENUMDOC - This is a 16 bit reloc for the FR30 that stores a 9 bit short offset - into 8 bits. -ENUM - BFD_RELOC_FR30_10_IN_8 -ENUMDOC - This is a 16 bit reloc for the FR30 that stores a 10 bit word offset - into 8 bits. -ENUM - BFD_RELOC_FR30_9_PCREL -ENUMDOC - This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative - short offset into 8 bits. -ENUM - BFD_RELOC_FR30_12_PCREL -ENUMDOC - This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative - short offset into 11 bits. - -ENUM - BFD_RELOC_MCORE_PCREL_IMM8BY4 -ENUMX - BFD_RELOC_MCORE_PCREL_IMM11BY2 -ENUMX - BFD_RELOC_MCORE_PCREL_IMM4BY2 -ENUMX - BFD_RELOC_MCORE_PCREL_32 -ENUMX - BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2 -ENUMX - BFD_RELOC_MCORE_RVA -ENUMDOC - Motorola Mcore relocations. - -ENUM - BFD_RELOC_MEP_8 -ENUMX - BFD_RELOC_MEP_16 -ENUMX - BFD_RELOC_MEP_32 -ENUMX - BFD_RELOC_MEP_PCREL8A2 -ENUMX - BFD_RELOC_MEP_PCREL12A2 -ENUMX - BFD_RELOC_MEP_PCREL17A2 -ENUMX - BFD_RELOC_MEP_PCREL24A2 -ENUMX - BFD_RELOC_MEP_PCABS24A2 -ENUMX - BFD_RELOC_MEP_LOW16 -ENUMX - BFD_RELOC_MEP_HI16U -ENUMX - BFD_RELOC_MEP_HI16S -ENUMX - BFD_RELOC_MEP_GPREL -ENUMX - BFD_RELOC_MEP_TPREL -ENUMX - BFD_RELOC_MEP_TPREL7 -ENUMX - BFD_RELOC_MEP_TPREL7A2 -ENUMX - BFD_RELOC_MEP_TPREL7A4 -ENUMX - BFD_RELOC_MEP_UIMM24 -ENUMX - BFD_RELOC_MEP_ADDR24A4 -ENUMX - BFD_RELOC_MEP_GNU_VTINHERIT -ENUMX - BFD_RELOC_MEP_GNU_VTENTRY -ENUMDOC - Toshiba Media Processor Relocations. -COMMENT - -ENUM - BFD_RELOC_MMIX_GETA -ENUMX - BFD_RELOC_MMIX_GETA_1 -ENUMX - BFD_RELOC_MMIX_GETA_2 -ENUMX - BFD_RELOC_MMIX_GETA_3 -ENUMDOC - These are relocations for the GETA instruction. -ENUM - BFD_RELOC_MMIX_CBRANCH -ENUMX - BFD_RELOC_MMIX_CBRANCH_J -ENUMX - BFD_RELOC_MMIX_CBRANCH_1 -ENUMX - BFD_RELOC_MMIX_CBRANCH_2 -ENUMX - BFD_RELOC_MMIX_CBRANCH_3 -ENUMDOC - These are relocations for a conditional branch instruction. -ENUM - BFD_RELOC_MMIX_PUSHJ -ENUMX - BFD_RELOC_MMIX_PUSHJ_1 -ENUMX - BFD_RELOC_MMIX_PUSHJ_2 -ENUMX - BFD_RELOC_MMIX_PUSHJ_3 -ENUMX - BFD_RELOC_MMIX_PUSHJ_STUBBABLE -ENUMDOC - These are relocations for the PUSHJ instruction. -ENUM - BFD_RELOC_MMIX_JMP -ENUMX - BFD_RELOC_MMIX_JMP_1 -ENUMX - BFD_RELOC_MMIX_JMP_2 -ENUMX - BFD_RELOC_MMIX_JMP_3 -ENUMDOC - These are relocations for the JMP instruction. -ENUM - BFD_RELOC_MMIX_ADDR19 -ENUMDOC - This is a relocation for a relative address as in a GETA instruction or - a branch. -ENUM - BFD_RELOC_MMIX_ADDR27 -ENUMDOC - This is a relocation for a relative address as in a JMP instruction. -ENUM - BFD_RELOC_MMIX_REG_OR_BYTE -ENUMDOC - This is a relocation for an instruction field that may be a general - register or a value 0..255. -ENUM - BFD_RELOC_MMIX_REG -ENUMDOC - This is a relocation for an instruction field that may be a general - register. -ENUM - BFD_RELOC_MMIX_BASE_PLUS_OFFSET -ENUMDOC - This is a relocation for two instruction fields holding a register and - an offset, the equivalent of the relocation. -ENUM - BFD_RELOC_MMIX_LOCAL -ENUMDOC - This relocation is an assertion that the expression is not allocated as - a global register. It does not modify contents. - -ENUM - BFD_RELOC_AVR_7_PCREL -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit pc relative - short offset into 7 bits. -ENUM - BFD_RELOC_AVR_13_PCREL -ENUMDOC - This is a 16 bit reloc for the AVR that stores 13 bit pc relative - short offset into 12 bits. -ENUM - BFD_RELOC_AVR_16_PM -ENUMDOC - This is a 16 bit reloc for the AVR that stores 17 bit value (usually - program memory address) into 16 bits. -ENUM - BFD_RELOC_AVR_LO8_LDI -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (usually - data memory address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_HI8_LDI -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit - of data memory address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_HH8_LDI -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit - of program memory address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_MS8_LDI -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit - of 32 bit value) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_LO8_LDI_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (usually data memory address) into 8 bit immediate value of SUBI insn. -ENUM - BFD_RELOC_AVR_HI8_LDI_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (high 8 bit of data memory address) into 8 bit immediate value of - SUBI insn. -ENUM - BFD_RELOC_AVR_HH8_LDI_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (most high 8 bit of program memory address) into 8 bit immediate value - of LDI or SUBI insn. -ENUM - BFD_RELOC_AVR_MS8_LDI_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb - of 32 bit value) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_LO8_LDI_PM -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (usually - command address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_LO8_LDI_GS -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value - (command address) into 8 bit immediate value of LDI insn. If the address - is beyond the 128k boundary, the linker inserts a jump stub for this reloc - in the lower 128k. -ENUM - BFD_RELOC_AVR_HI8_LDI_PM -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit - of command address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_HI8_LDI_GS -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit - of command address) into 8 bit immediate value of LDI insn. If the address - is beyond the 128k boundary, the linker inserts a jump stub for this reloc - below 128k. -ENUM - BFD_RELOC_AVR_HH8_LDI_PM -ENUMDOC - This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit - of command address) into 8 bit immediate value of LDI insn. -ENUM - BFD_RELOC_AVR_LO8_LDI_PM_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (usually command address) into 8 bit immediate value of SUBI insn. -ENUM - BFD_RELOC_AVR_HI8_LDI_PM_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (high 8 bit of 16 bit command address) into 8 bit immediate value - of SUBI insn. -ENUM - BFD_RELOC_AVR_HH8_LDI_PM_NEG -ENUMDOC - This is a 16 bit reloc for the AVR that stores negated 8 bit value - (high 6 bit of 22 bit command address) into 8 bit immediate - value of SUBI insn. -ENUM - BFD_RELOC_AVR_CALL -ENUMDOC - This is a 32 bit reloc for the AVR that stores 23 bit value - into 22 bits. -ENUM - BFD_RELOC_AVR_LDI -ENUMDOC - This is a 16 bit reloc for the AVR that stores all needed bits - for absolute addressing with ldi with overflow check to linktime -ENUM - BFD_RELOC_AVR_6 -ENUMDOC - This is a 6 bit reloc for the AVR that stores offset for ldd/std - instructions -ENUM - BFD_RELOC_AVR_6_ADIW -ENUMDOC - This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw - instructions - -ENUM - BFD_RELOC_RX_NEG8 -ENUMX - BFD_RELOC_RX_NEG16 -ENUMX - BFD_RELOC_RX_NEG24 -ENUMX - BFD_RELOC_RX_NEG32 -ENUMX - BFD_RELOC_RX_16_OP -ENUMX - BFD_RELOC_RX_24_OP -ENUMX - BFD_RELOC_RX_32_OP -ENUMX - BFD_RELOC_RX_8U -ENUMX - BFD_RELOC_RX_16U -ENUMX - BFD_RELOC_RX_24U -ENUMX - BFD_RELOC_RX_DIR3U_PCREL -ENUMX - BFD_RELOC_RX_DIFF -ENUMX - BFD_RELOC_RX_GPRELB -ENUMX - BFD_RELOC_RX_GPRELW -ENUMX - BFD_RELOC_RX_GPRELL -ENUMX - BFD_RELOC_RX_SYM -ENUMX - BFD_RELOC_RX_OP_SUBTRACT -ENUMX - BFD_RELOC_RX_OP_NEG -ENUMX - BFD_RELOC_RX_ABS8 -ENUMX - BFD_RELOC_RX_ABS16 -ENUMX - BFD_RELOC_RX_ABS16_REV -ENUMX - BFD_RELOC_RX_ABS32 -ENUMX - BFD_RELOC_RX_ABS32_REV -ENUMX - BFD_RELOC_RX_ABS16U -ENUMX - BFD_RELOC_RX_ABS16UW -ENUMX - BFD_RELOC_RX_ABS16UL -ENUMX - BFD_RELOC_RX_RELAX -ENUMDOC - Renesas RX Relocations. - -ENUM - BFD_RELOC_390_12 -ENUMDOC - Direct 12 bit. -ENUM - BFD_RELOC_390_GOT12 -ENUMDOC - 12 bit GOT offset. -ENUM - BFD_RELOC_390_PLT32 -ENUMDOC - 32 bit PC relative PLT address. -ENUM - BFD_RELOC_390_COPY -ENUMDOC - Copy symbol at runtime. -ENUM - BFD_RELOC_390_GLOB_DAT -ENUMDOC - Create GOT entry. -ENUM - BFD_RELOC_390_JMP_SLOT -ENUMDOC - Create PLT entry. -ENUM - BFD_RELOC_390_RELATIVE -ENUMDOC - Adjust by program base. -ENUM - BFD_RELOC_390_GOTPC -ENUMDOC - 32 bit PC relative offset to GOT. -ENUM - BFD_RELOC_390_GOT16 -ENUMDOC - 16 bit GOT offset. -ENUM - BFD_RELOC_390_PC16DBL -ENUMDOC - PC relative 16 bit shifted by 1. -ENUM - BFD_RELOC_390_PLT16DBL -ENUMDOC - 16 bit PC rel. PLT shifted by 1. -ENUM - BFD_RELOC_390_PC32DBL -ENUMDOC - PC relative 32 bit shifted by 1. -ENUM - BFD_RELOC_390_PLT32DBL -ENUMDOC - 32 bit PC rel. PLT shifted by 1. -ENUM - BFD_RELOC_390_GOTPCDBL -ENUMDOC - 32 bit PC rel. GOT shifted by 1. -ENUM - BFD_RELOC_390_GOT64 -ENUMDOC - 64 bit GOT offset. -ENUM - BFD_RELOC_390_PLT64 -ENUMDOC - 64 bit PC relative PLT address. -ENUM - BFD_RELOC_390_GOTENT -ENUMDOC - 32 bit rel. offset to GOT entry. -ENUM - BFD_RELOC_390_GOTOFF64 -ENUMDOC - 64 bit offset to GOT. -ENUM - BFD_RELOC_390_GOTPLT12 -ENUMDOC - 12-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_390_GOTPLT16 -ENUMDOC - 16-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_390_GOTPLT32 -ENUMDOC - 32-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_390_GOTPLT64 -ENUMDOC - 64-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_390_GOTPLTENT -ENUMDOC - 32-bit rel. offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_390_PLTOFF16 -ENUMDOC - 16-bit rel. offset from the GOT to a PLT entry. -ENUM - BFD_RELOC_390_PLTOFF32 -ENUMDOC - 32-bit rel. offset from the GOT to a PLT entry. -ENUM - BFD_RELOC_390_PLTOFF64 -ENUMDOC - 64-bit rel. offset from the GOT to a PLT entry. - -ENUM - BFD_RELOC_390_TLS_LOAD -ENUMX - BFD_RELOC_390_TLS_GDCALL -ENUMX - BFD_RELOC_390_TLS_LDCALL -ENUMX - BFD_RELOC_390_TLS_GD32 -ENUMX - BFD_RELOC_390_TLS_GD64 -ENUMX - BFD_RELOC_390_TLS_GOTIE12 -ENUMX - BFD_RELOC_390_TLS_GOTIE32 -ENUMX - BFD_RELOC_390_TLS_GOTIE64 -ENUMX - BFD_RELOC_390_TLS_LDM32 -ENUMX - BFD_RELOC_390_TLS_LDM64 -ENUMX - BFD_RELOC_390_TLS_IE32 -ENUMX - BFD_RELOC_390_TLS_IE64 -ENUMX - BFD_RELOC_390_TLS_IEENT -ENUMX - BFD_RELOC_390_TLS_LE32 -ENUMX - BFD_RELOC_390_TLS_LE64 -ENUMX - BFD_RELOC_390_TLS_LDO32 -ENUMX - BFD_RELOC_390_TLS_LDO64 -ENUMX - BFD_RELOC_390_TLS_DTPMOD -ENUMX - BFD_RELOC_390_TLS_DTPOFF -ENUMX - BFD_RELOC_390_TLS_TPOFF -ENUMDOC - s390 tls relocations. - -ENUM - BFD_RELOC_390_20 -ENUMX - BFD_RELOC_390_GOT20 -ENUMX - BFD_RELOC_390_GOTPLT20 -ENUMX - BFD_RELOC_390_TLS_GOTIE20 -ENUMDOC - Long displacement extension. - -ENUM - BFD_RELOC_SCORE_GPREL15 -ENUMDOC - Score relocations - Low 16 bit for load/store -ENUM - BFD_RELOC_SCORE_DUMMY2 -ENUMX - BFD_RELOC_SCORE_JMP -ENUMDOC - This is a 24-bit reloc with the right 1 bit assumed to be 0 -ENUM - BFD_RELOC_SCORE_BRANCH -ENUMDOC - This is a 19-bit reloc with the right 1 bit assumed to be 0 -ENUM - BFD_RELOC_SCORE_IMM30 -ENUMDOC - This is a 32-bit reloc for 48-bit instructions. -ENUM - BFD_RELOC_SCORE_IMM32 -ENUMDOC - This is a 32-bit reloc for 48-bit instructions. -ENUM - BFD_RELOC_SCORE16_JMP -ENUMDOC - This is a 11-bit reloc with the right 1 bit assumed to be 0 -ENUM - BFD_RELOC_SCORE16_BRANCH -ENUMDOC - This is a 8-bit reloc with the right 1 bit assumed to be 0 -ENUM - BFD_RELOC_SCORE_BCMP -ENUMDOC - This is a 9-bit reloc with the right 1 bit assumed to be 0 -ENUM - BFD_RELOC_SCORE_GOT15 -ENUMX - BFD_RELOC_SCORE_GOT_LO16 -ENUMX - BFD_RELOC_SCORE_CALL15 -ENUMX - BFD_RELOC_SCORE_DUMMY_HI16 -ENUMDOC - Undocumented Score relocs - -ENUM - BFD_RELOC_IP2K_FR9 -ENUMDOC - Scenix IP2K - 9-bit register number / data address -ENUM - BFD_RELOC_IP2K_BANK -ENUMDOC - Scenix IP2K - 4-bit register/data bank number -ENUM - BFD_RELOC_IP2K_ADDR16CJP -ENUMDOC - Scenix IP2K - low 13 bits of instruction word address -ENUM - BFD_RELOC_IP2K_PAGE3 -ENUMDOC - Scenix IP2K - high 3 bits of instruction word address -ENUM - BFD_RELOC_IP2K_LO8DATA -ENUMX - BFD_RELOC_IP2K_HI8DATA -ENUMX - BFD_RELOC_IP2K_EX8DATA -ENUMDOC - Scenix IP2K - ext/low/high 8 bits of data address -ENUM - BFD_RELOC_IP2K_LO8INSN -ENUMX - BFD_RELOC_IP2K_HI8INSN -ENUMDOC - Scenix IP2K - low/high 8 bits of instruction word address -ENUM - BFD_RELOC_IP2K_PC_SKIP -ENUMDOC - Scenix IP2K - even/odd PC modifier to modify snb pcl.0 -ENUM - BFD_RELOC_IP2K_TEXT -ENUMDOC - Scenix IP2K - 16 bit word address in text section. -ENUM - BFD_RELOC_IP2K_FR_OFFSET -ENUMDOC - Scenix IP2K - 7-bit sp or dp offset -ENUM - BFD_RELOC_VPE4KMATH_DATA -ENUMX - BFD_RELOC_VPE4KMATH_INSN -ENUMDOC - Scenix VPE4K coprocessor - data/insn-space addressing - -ENUM - BFD_RELOC_VTABLE_INHERIT -ENUMX - BFD_RELOC_VTABLE_ENTRY -ENUMDOC - These two relocations are used by the linker to determine which of - the entries in a C++ virtual function table are actually used. When - the --gc-sections option is given, the linker will zero out the entries - that are not used, so that the code for those functions need not be - included in the output. - - VTABLE_INHERIT is a zero-space relocation used to describe to the - linker the inheritance tree of a C++ virtual function table. The - relocation's symbol should be the parent class' vtable, and the - relocation should be located at the child vtable. - - VTABLE_ENTRY is a zero-space relocation that describes the use of a - virtual function table entry. The reloc's symbol should refer to the - table of the class mentioned in the code. Off of that base, an offset - describes the entry that is being used. For Rela hosts, this offset - is stored in the reloc's addend. For Rel hosts, we are forced to put - this offset in the reloc's section offset. - -ENUM - BFD_RELOC_IA64_IMM14 -ENUMX - BFD_RELOC_IA64_IMM22 -ENUMX - BFD_RELOC_IA64_IMM64 -ENUMX - BFD_RELOC_IA64_DIR32MSB -ENUMX - BFD_RELOC_IA64_DIR32LSB -ENUMX - BFD_RELOC_IA64_DIR64MSB -ENUMX - BFD_RELOC_IA64_DIR64LSB -ENUMX - BFD_RELOC_IA64_GPREL22 -ENUMX - BFD_RELOC_IA64_GPREL64I -ENUMX - BFD_RELOC_IA64_GPREL32MSB -ENUMX - BFD_RELOC_IA64_GPREL32LSB -ENUMX - BFD_RELOC_IA64_GPREL64MSB -ENUMX - BFD_RELOC_IA64_GPREL64LSB -ENUMX - BFD_RELOC_IA64_LTOFF22 -ENUMX - BFD_RELOC_IA64_LTOFF64I -ENUMX - BFD_RELOC_IA64_PLTOFF22 -ENUMX - BFD_RELOC_IA64_PLTOFF64I -ENUMX - BFD_RELOC_IA64_PLTOFF64MSB -ENUMX - BFD_RELOC_IA64_PLTOFF64LSB -ENUMX - BFD_RELOC_IA64_FPTR64I -ENUMX - BFD_RELOC_IA64_FPTR32MSB -ENUMX - BFD_RELOC_IA64_FPTR32LSB -ENUMX - BFD_RELOC_IA64_FPTR64MSB -ENUMX - BFD_RELOC_IA64_FPTR64LSB -ENUMX - BFD_RELOC_IA64_PCREL21B -ENUMX - BFD_RELOC_IA64_PCREL21BI -ENUMX - BFD_RELOC_IA64_PCREL21M -ENUMX - BFD_RELOC_IA64_PCREL21F -ENUMX - BFD_RELOC_IA64_PCREL22 -ENUMX - BFD_RELOC_IA64_PCREL60B -ENUMX - BFD_RELOC_IA64_PCREL64I -ENUMX - BFD_RELOC_IA64_PCREL32MSB -ENUMX - BFD_RELOC_IA64_PCREL32LSB -ENUMX - BFD_RELOC_IA64_PCREL64MSB -ENUMX - BFD_RELOC_IA64_PCREL64LSB -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR22 -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR64I -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR32MSB -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR32LSB -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR64MSB -ENUMX - BFD_RELOC_IA64_LTOFF_FPTR64LSB -ENUMX - BFD_RELOC_IA64_SEGREL32MSB -ENUMX - BFD_RELOC_IA64_SEGREL32LSB -ENUMX - BFD_RELOC_IA64_SEGREL64MSB -ENUMX - BFD_RELOC_IA64_SEGREL64LSB -ENUMX - BFD_RELOC_IA64_SECREL32MSB -ENUMX - BFD_RELOC_IA64_SECREL32LSB -ENUMX - BFD_RELOC_IA64_SECREL64MSB -ENUMX - BFD_RELOC_IA64_SECREL64LSB -ENUMX - BFD_RELOC_IA64_REL32MSB -ENUMX - BFD_RELOC_IA64_REL32LSB -ENUMX - BFD_RELOC_IA64_REL64MSB -ENUMX - BFD_RELOC_IA64_REL64LSB -ENUMX - BFD_RELOC_IA64_LTV32MSB -ENUMX - BFD_RELOC_IA64_LTV32LSB -ENUMX - BFD_RELOC_IA64_LTV64MSB -ENUMX - BFD_RELOC_IA64_LTV64LSB -ENUMX - BFD_RELOC_IA64_IPLTMSB -ENUMX - BFD_RELOC_IA64_IPLTLSB -ENUMX - BFD_RELOC_IA64_COPY -ENUMX - BFD_RELOC_IA64_LTOFF22X -ENUMX - BFD_RELOC_IA64_LDXMOV -ENUMX - BFD_RELOC_IA64_TPREL14 -ENUMX - BFD_RELOC_IA64_TPREL22 -ENUMX - BFD_RELOC_IA64_TPREL64I -ENUMX - BFD_RELOC_IA64_TPREL64MSB -ENUMX - BFD_RELOC_IA64_TPREL64LSB -ENUMX - BFD_RELOC_IA64_LTOFF_TPREL22 -ENUMX - BFD_RELOC_IA64_DTPMOD64MSB -ENUMX - BFD_RELOC_IA64_DTPMOD64LSB -ENUMX - BFD_RELOC_IA64_LTOFF_DTPMOD22 -ENUMX - BFD_RELOC_IA64_DTPREL14 -ENUMX - BFD_RELOC_IA64_DTPREL22 -ENUMX - BFD_RELOC_IA64_DTPREL64I -ENUMX - BFD_RELOC_IA64_DTPREL32MSB -ENUMX - BFD_RELOC_IA64_DTPREL32LSB -ENUMX - BFD_RELOC_IA64_DTPREL64MSB -ENUMX - BFD_RELOC_IA64_DTPREL64LSB -ENUMX - BFD_RELOC_IA64_LTOFF_DTPREL22 -ENUMDOC - Intel IA64 Relocations. - -ENUM - BFD_RELOC_M68HC11_HI8 -ENUMDOC - Motorola 68HC11 reloc. - This is the 8 bit high part of an absolute address. -ENUM - BFD_RELOC_M68HC11_LO8 -ENUMDOC - Motorola 68HC11 reloc. - This is the 8 bit low part of an absolute address. -ENUM - BFD_RELOC_M68HC11_3B -ENUMDOC - Motorola 68HC11 reloc. - This is the 3 bit of a value. -ENUM - BFD_RELOC_M68HC11_RL_JUMP -ENUMDOC - Motorola 68HC11 reloc. - This reloc marks the beginning of a jump/call instruction. - It is used for linker relaxation to correctly identify beginning - of instruction and change some branches to use PC-relative - addressing mode. -ENUM - BFD_RELOC_M68HC11_RL_GROUP -ENUMDOC - Motorola 68HC11 reloc. - This reloc marks a group of several instructions that gcc generates - and for which the linker relaxation pass can modify and/or remove - some of them. -ENUM - BFD_RELOC_M68HC11_LO16 -ENUMDOC - Motorola 68HC11 reloc. - This is the 16-bit lower part of an address. It is used for 'call' - instruction to specify the symbol address without any special - transformation (due to memory bank window). -ENUM - BFD_RELOC_M68HC11_PAGE -ENUMDOC - Motorola 68HC11 reloc. - This is a 8-bit reloc that specifies the page number of an address. - It is used by 'call' instruction to specify the page number of - the symbol. -ENUM - BFD_RELOC_M68HC11_24 -ENUMDOC - Motorola 68HC11 reloc. - This is a 24-bit reloc that represents the address with a 16-bit - value and a 8-bit page number. The symbol address is transformed - to follow the 16K memory bank of 68HC12 (seen as mapped in the window). -ENUM - BFD_RELOC_M68HC12_5B -ENUMDOC - Motorola 68HC12 reloc. - This is the 5 bits of a value. - -ENUM - BFD_RELOC_16C_NUM08 -ENUMX - BFD_RELOC_16C_NUM08_C -ENUMX - BFD_RELOC_16C_NUM16 -ENUMX - BFD_RELOC_16C_NUM16_C -ENUMX - BFD_RELOC_16C_NUM32 -ENUMX - BFD_RELOC_16C_NUM32_C -ENUMX - BFD_RELOC_16C_DISP04 -ENUMX - BFD_RELOC_16C_DISP04_C -ENUMX - BFD_RELOC_16C_DISP08 -ENUMX - BFD_RELOC_16C_DISP08_C -ENUMX - BFD_RELOC_16C_DISP16 -ENUMX - BFD_RELOC_16C_DISP16_C -ENUMX - BFD_RELOC_16C_DISP24 -ENUMX - BFD_RELOC_16C_DISP24_C -ENUMX - BFD_RELOC_16C_DISP24a -ENUMX - BFD_RELOC_16C_DISP24a_C -ENUMX - BFD_RELOC_16C_REG04 -ENUMX - BFD_RELOC_16C_REG04_C -ENUMX - BFD_RELOC_16C_REG04a -ENUMX - BFD_RELOC_16C_REG04a_C -ENUMX - BFD_RELOC_16C_REG14 -ENUMX - BFD_RELOC_16C_REG14_C -ENUMX - BFD_RELOC_16C_REG16 -ENUMX - BFD_RELOC_16C_REG16_C -ENUMX - BFD_RELOC_16C_REG20 -ENUMX - BFD_RELOC_16C_REG20_C -ENUMX - BFD_RELOC_16C_ABS20 -ENUMX - BFD_RELOC_16C_ABS20_C -ENUMX - BFD_RELOC_16C_ABS24 -ENUMX - BFD_RELOC_16C_ABS24_C -ENUMX - BFD_RELOC_16C_IMM04 -ENUMX - BFD_RELOC_16C_IMM04_C -ENUMX - BFD_RELOC_16C_IMM16 -ENUMX - BFD_RELOC_16C_IMM16_C -ENUMX - BFD_RELOC_16C_IMM20 -ENUMX - BFD_RELOC_16C_IMM20_C -ENUMX - BFD_RELOC_16C_IMM24 -ENUMX - BFD_RELOC_16C_IMM24_C -ENUMX - BFD_RELOC_16C_IMM32 -ENUMX - BFD_RELOC_16C_IMM32_C -ENUMDOC - NS CR16C Relocations. - -ENUM - BFD_RELOC_CR16_NUM8 -ENUMX - BFD_RELOC_CR16_NUM16 -ENUMX - BFD_RELOC_CR16_NUM32 -ENUMX - BFD_RELOC_CR16_NUM32a -ENUMX - BFD_RELOC_CR16_REGREL0 -ENUMX - BFD_RELOC_CR16_REGREL4 -ENUMX - BFD_RELOC_CR16_REGREL4a -ENUMX - BFD_RELOC_CR16_REGREL14 -ENUMX - BFD_RELOC_CR16_REGREL14a -ENUMX - BFD_RELOC_CR16_REGREL16 -ENUMX - BFD_RELOC_CR16_REGREL20 -ENUMX - BFD_RELOC_CR16_REGREL20a -ENUMX - BFD_RELOC_CR16_ABS20 -ENUMX - BFD_RELOC_CR16_ABS24 -ENUMX - BFD_RELOC_CR16_IMM4 -ENUMX - BFD_RELOC_CR16_IMM8 -ENUMX - BFD_RELOC_CR16_IMM16 -ENUMX - BFD_RELOC_CR16_IMM20 -ENUMX - BFD_RELOC_CR16_IMM24 -ENUMX - BFD_RELOC_CR16_IMM32 -ENUMX - BFD_RELOC_CR16_IMM32a -ENUMX - BFD_RELOC_CR16_DISP4 -ENUMX - BFD_RELOC_CR16_DISP8 -ENUMX - BFD_RELOC_CR16_DISP16 -ENUMX - BFD_RELOC_CR16_DISP20 -ENUMX - BFD_RELOC_CR16_DISP24 -ENUMX - BFD_RELOC_CR16_DISP24a -ENUMX - BFD_RELOC_CR16_SWITCH8 -ENUMX - BFD_RELOC_CR16_SWITCH16 -ENUMX - BFD_RELOC_CR16_SWITCH32 -ENUMX - BFD_RELOC_CR16_GOT_REGREL20 -ENUMX - BFD_RELOC_CR16_GOTC_REGREL20 -ENUMX - BFD_RELOC_CR16_GLOB_DAT -ENUMDOC - NS CR16 Relocations. - -ENUM - BFD_RELOC_CRX_REL4 -ENUMX - BFD_RELOC_CRX_REL8 -ENUMX - BFD_RELOC_CRX_REL8_CMP -ENUMX - BFD_RELOC_CRX_REL16 -ENUMX - BFD_RELOC_CRX_REL24 -ENUMX - BFD_RELOC_CRX_REL32 -ENUMX - BFD_RELOC_CRX_REGREL12 -ENUMX - BFD_RELOC_CRX_REGREL22 -ENUMX - BFD_RELOC_CRX_REGREL28 -ENUMX - BFD_RELOC_CRX_REGREL32 -ENUMX - BFD_RELOC_CRX_ABS16 -ENUMX - BFD_RELOC_CRX_ABS32 -ENUMX - BFD_RELOC_CRX_NUM8 -ENUMX - BFD_RELOC_CRX_NUM16 -ENUMX - BFD_RELOC_CRX_NUM32 -ENUMX - BFD_RELOC_CRX_IMM16 -ENUMX - BFD_RELOC_CRX_IMM32 -ENUMX - BFD_RELOC_CRX_SWITCH8 -ENUMX - BFD_RELOC_CRX_SWITCH16 -ENUMX - BFD_RELOC_CRX_SWITCH32 -ENUMDOC - NS CRX Relocations. - -ENUM - BFD_RELOC_CRIS_BDISP8 -ENUMX - BFD_RELOC_CRIS_UNSIGNED_5 -ENUMX - BFD_RELOC_CRIS_SIGNED_6 -ENUMX - BFD_RELOC_CRIS_UNSIGNED_6 -ENUMX - BFD_RELOC_CRIS_SIGNED_8 -ENUMX - BFD_RELOC_CRIS_UNSIGNED_8 -ENUMX - BFD_RELOC_CRIS_SIGNED_16 -ENUMX - BFD_RELOC_CRIS_UNSIGNED_16 -ENUMX - BFD_RELOC_CRIS_LAPCQ_OFFSET -ENUMX - BFD_RELOC_CRIS_UNSIGNED_4 -ENUMDOC - These relocs are only used within the CRIS assembler. They are not - (at present) written to any object files. -ENUM - BFD_RELOC_CRIS_COPY -ENUMX - BFD_RELOC_CRIS_GLOB_DAT -ENUMX - BFD_RELOC_CRIS_JUMP_SLOT -ENUMX - BFD_RELOC_CRIS_RELATIVE -ENUMDOC - Relocs used in ELF shared libraries for CRIS. -ENUM - BFD_RELOC_CRIS_32_GOT -ENUMDOC - 32-bit offset to symbol-entry within GOT. -ENUM - BFD_RELOC_CRIS_16_GOT -ENUMDOC - 16-bit offset to symbol-entry within GOT. -ENUM - BFD_RELOC_CRIS_32_GOTPLT -ENUMDOC - 32-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_CRIS_16_GOTPLT -ENUMDOC - 16-bit offset to symbol-entry within GOT, with PLT handling. -ENUM - BFD_RELOC_CRIS_32_GOTREL -ENUMDOC - 32-bit offset to symbol, relative to GOT. -ENUM - BFD_RELOC_CRIS_32_PLT_GOTREL -ENUMDOC - 32-bit offset to symbol with PLT entry, relative to GOT. -ENUM - BFD_RELOC_CRIS_32_PLT_PCREL -ENUMDOC - 32-bit offset to symbol with PLT entry, relative to this relocation. - -ENUM - BFD_RELOC_CRIS_32_GOT_GD -ENUMX - BFD_RELOC_CRIS_16_GOT_GD -ENUMX - BFD_RELOC_CRIS_32_GD -ENUMX - BFD_RELOC_CRIS_DTP -ENUMX - BFD_RELOC_CRIS_32_DTPREL -ENUMX - BFD_RELOC_CRIS_16_DTPREL -ENUMX - BFD_RELOC_CRIS_32_GOT_TPREL -ENUMX - BFD_RELOC_CRIS_16_GOT_TPREL -ENUMX - BFD_RELOC_CRIS_32_TPREL -ENUMX - BFD_RELOC_CRIS_16_TPREL -ENUMX - BFD_RELOC_CRIS_DTPMOD -ENUMX - BFD_RELOC_CRIS_32_IE -ENUMDOC - Relocs used in TLS code for CRIS. - -ENUM - BFD_RELOC_860_COPY -ENUMX - BFD_RELOC_860_GLOB_DAT -ENUMX - BFD_RELOC_860_JUMP_SLOT -ENUMX - BFD_RELOC_860_RELATIVE -ENUMX - BFD_RELOC_860_PC26 -ENUMX - BFD_RELOC_860_PLT26 -ENUMX - BFD_RELOC_860_PC16 -ENUMX - BFD_RELOC_860_LOW0 -ENUMX - BFD_RELOC_860_SPLIT0 -ENUMX - BFD_RELOC_860_LOW1 -ENUMX - BFD_RELOC_860_SPLIT1 -ENUMX - BFD_RELOC_860_LOW2 -ENUMX - BFD_RELOC_860_SPLIT2 -ENUMX - BFD_RELOC_860_LOW3 -ENUMX - BFD_RELOC_860_LOGOT0 -ENUMX - BFD_RELOC_860_SPGOT0 -ENUMX - BFD_RELOC_860_LOGOT1 -ENUMX - BFD_RELOC_860_SPGOT1 -ENUMX - BFD_RELOC_860_LOGOTOFF0 -ENUMX - BFD_RELOC_860_SPGOTOFF0 -ENUMX - BFD_RELOC_860_LOGOTOFF1 -ENUMX - BFD_RELOC_860_SPGOTOFF1 -ENUMX - BFD_RELOC_860_LOGOTOFF2 -ENUMX - BFD_RELOC_860_LOGOTOFF3 -ENUMX - BFD_RELOC_860_LOPC -ENUMX - BFD_RELOC_860_HIGHADJ -ENUMX - BFD_RELOC_860_HAGOT -ENUMX - BFD_RELOC_860_HAGOTOFF -ENUMX - BFD_RELOC_860_HAPC -ENUMX - BFD_RELOC_860_HIGH -ENUMX - BFD_RELOC_860_HIGOT -ENUMX - BFD_RELOC_860_HIGOTOFF -ENUMDOC - Intel i860 Relocations. - -ENUM - BFD_RELOC_OPENRISC_ABS_26 -ENUMX - BFD_RELOC_OPENRISC_REL_26 -ENUMDOC - OpenRISC Relocations. - -ENUM - BFD_RELOC_H8_DIR16A8 -ENUMX - BFD_RELOC_H8_DIR16R8 -ENUMX - BFD_RELOC_H8_DIR24A8 -ENUMX - BFD_RELOC_H8_DIR24R8 -ENUMX - BFD_RELOC_H8_DIR32A16 -ENUMDOC - H8 elf Relocations. - -ENUM - BFD_RELOC_XSTORMY16_REL_12 -ENUMX - BFD_RELOC_XSTORMY16_12 -ENUMX - BFD_RELOC_XSTORMY16_24 -ENUMX - BFD_RELOC_XSTORMY16_FPTR16 -ENUMDOC - Sony Xstormy16 Relocations. - -ENUM - BFD_RELOC_RELC -ENUMDOC - Self-describing complex relocations. -COMMENT - -ENUM - BFD_RELOC_XC16X_PAG -ENUMX - BFD_RELOC_XC16X_POF -ENUMX - BFD_RELOC_XC16X_SEG -ENUMX - BFD_RELOC_XC16X_SOF -ENUMDOC - Infineon Relocations. - -ENUM - BFD_RELOC_VAX_GLOB_DAT -ENUMX - BFD_RELOC_VAX_JMP_SLOT -ENUMX - BFD_RELOC_VAX_RELATIVE -ENUMDOC - Relocations used by VAX ELF. - -ENUM - BFD_RELOC_MT_PC16 -ENUMDOC - Morpho MT - 16 bit immediate relocation. -ENUM - BFD_RELOC_MT_HI16 -ENUMDOC - Morpho MT - Hi 16 bits of an address. -ENUM - BFD_RELOC_MT_LO16 -ENUMDOC - Morpho MT - Low 16 bits of an address. -ENUM - BFD_RELOC_MT_GNU_VTINHERIT -ENUMDOC - Morpho MT - Used to tell the linker which vtable entries are used. -ENUM - BFD_RELOC_MT_GNU_VTENTRY -ENUMDOC - Morpho MT - Used to tell the linker which vtable entries are used. -ENUM - BFD_RELOC_MT_PCINSN8 -ENUMDOC - Morpho MT - 8 bit immediate relocation. - -ENUM - BFD_RELOC_MSP430_10_PCREL -ENUMX - BFD_RELOC_MSP430_16_PCREL -ENUMX - BFD_RELOC_MSP430_16 -ENUMX - BFD_RELOC_MSP430_16_PCREL_BYTE -ENUMX - BFD_RELOC_MSP430_16_BYTE -ENUMX - BFD_RELOC_MSP430_2X_PCREL -ENUMX - BFD_RELOC_MSP430_RL_PCREL -ENUMDOC - msp430 specific relocation codes - -ENUM - BFD_RELOC_IQ2000_OFFSET_16 -ENUMX - BFD_RELOC_IQ2000_OFFSET_21 -ENUMX - BFD_RELOC_IQ2000_UHI16 -ENUMDOC - IQ2000 Relocations. - -ENUM - BFD_RELOC_XTENSA_RTLD -ENUMDOC - Special Xtensa relocation used only by PLT entries in ELF shared - objects to indicate that the runtime linker should set the value - to one of its own internal functions or data structures. -ENUM - BFD_RELOC_XTENSA_GLOB_DAT -ENUMX - BFD_RELOC_XTENSA_JMP_SLOT -ENUMX - BFD_RELOC_XTENSA_RELATIVE -ENUMDOC - Xtensa relocations for ELF shared objects. -ENUM - BFD_RELOC_XTENSA_PLT -ENUMDOC - Xtensa relocation used in ELF object files for symbols that may require - PLT entries. Otherwise, this is just a generic 32-bit relocation. -ENUM - BFD_RELOC_XTENSA_DIFF8 -ENUMX - BFD_RELOC_XTENSA_DIFF16 -ENUMX - BFD_RELOC_XTENSA_DIFF32 -ENUMDOC - Xtensa relocations to mark the difference of two local symbols. - These are only needed to support linker relaxation and can be ignored - when not relaxing. The field is set to the value of the difference - assuming no relaxation. The relocation encodes the position of the - first symbol so the linker can determine whether to adjust the field - value. -ENUM - BFD_RELOC_XTENSA_SLOT0_OP -ENUMX - BFD_RELOC_XTENSA_SLOT1_OP -ENUMX - BFD_RELOC_XTENSA_SLOT2_OP -ENUMX - BFD_RELOC_XTENSA_SLOT3_OP -ENUMX - BFD_RELOC_XTENSA_SLOT4_OP -ENUMX - BFD_RELOC_XTENSA_SLOT5_OP -ENUMX - BFD_RELOC_XTENSA_SLOT6_OP -ENUMX - BFD_RELOC_XTENSA_SLOT7_OP -ENUMX - BFD_RELOC_XTENSA_SLOT8_OP -ENUMX - BFD_RELOC_XTENSA_SLOT9_OP -ENUMX - BFD_RELOC_XTENSA_SLOT10_OP -ENUMX - BFD_RELOC_XTENSA_SLOT11_OP -ENUMX - BFD_RELOC_XTENSA_SLOT12_OP -ENUMX - BFD_RELOC_XTENSA_SLOT13_OP -ENUMX - BFD_RELOC_XTENSA_SLOT14_OP -ENUMDOC - Generic Xtensa relocations for instruction operands. Only the slot - number is encoded in the relocation. The relocation applies to the - last PC-relative immediate operand, or if there are no PC-relative - immediates, to the last immediate operand. -ENUM - BFD_RELOC_XTENSA_SLOT0_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT1_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT2_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT3_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT4_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT5_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT6_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT7_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT8_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT9_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT10_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT11_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT12_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT13_ALT -ENUMX - BFD_RELOC_XTENSA_SLOT14_ALT -ENUMDOC - Alternate Xtensa relocations. Only the slot is encoded in the - relocation. The meaning of these relocations is opcode-specific. -ENUM - BFD_RELOC_XTENSA_OP0 -ENUMX - BFD_RELOC_XTENSA_OP1 -ENUMX - BFD_RELOC_XTENSA_OP2 -ENUMDOC - Xtensa relocations for backward compatibility. These have all been - replaced by BFD_RELOC_XTENSA_SLOT0_OP. -ENUM - BFD_RELOC_XTENSA_ASM_EXPAND -ENUMDOC - Xtensa relocation to mark that the assembler expanded the - instructions from an original target. The expansion size is - encoded in the reloc size. -ENUM - BFD_RELOC_XTENSA_ASM_SIMPLIFY -ENUMDOC - Xtensa relocation to mark that the linker should simplify - assembler-expanded instructions. This is commonly used - internally by the linker after analysis of a - BFD_RELOC_XTENSA_ASM_EXPAND. -ENUM - BFD_RELOC_XTENSA_TLSDESC_FN -ENUMX - BFD_RELOC_XTENSA_TLSDESC_ARG -ENUMX - BFD_RELOC_XTENSA_TLS_DTPOFF -ENUMX - BFD_RELOC_XTENSA_TLS_TPOFF -ENUMX - BFD_RELOC_XTENSA_TLS_FUNC -ENUMX - BFD_RELOC_XTENSA_TLS_ARG -ENUMX - BFD_RELOC_XTENSA_TLS_CALL -ENUMDOC - Xtensa TLS relocations. - -ENUM - BFD_RELOC_Z80_DISP8 -ENUMDOC - 8 bit signed offset in (ix+d) or (iy+d). - -ENUM - BFD_RELOC_Z8K_DISP7 -ENUMDOC - DJNZ offset. -ENUM - BFD_RELOC_Z8K_CALLR -ENUMDOC - CALR offset. -ENUM - BFD_RELOC_Z8K_IMM4L -ENUMDOC - 4 bit value. - -ENUM - BFD_RELOC_LM32_CALL -ENUMX - BFD_RELOC_LM32_BRANCH -ENUMX - BFD_RELOC_LM32_16_GOT -ENUMX - BFD_RELOC_LM32_GOTOFF_HI16 -ENUMX - BFD_RELOC_LM32_GOTOFF_LO16 -ENUMX - BFD_RELOC_LM32_COPY -ENUMX - BFD_RELOC_LM32_GLOB_DAT -ENUMX - BFD_RELOC_LM32_JMP_SLOT -ENUMX - BFD_RELOC_LM32_RELATIVE -ENUMDOC - Lattice Mico32 relocations. - -ENUM - BFD_RELOC_MACH_O_SECTDIFF -ENUMDOC - Difference between two section addreses. Must be followed by a - BFD_RELOC_MACH_O_PAIR. -ENUM - BFD_RELOC_MACH_O_PAIR -ENUMDOC - Pair of relocation. Contains the first symbol. - -ENUM - BFD_RELOC_MACH_O_X86_64_BRANCH32 -ENUMX - BFD_RELOC_MACH_O_X86_64_BRANCH8 -ENUMDOC - PCREL relocations. They are marked as branch to create PLT entry if - required. -ENUM - BFD_RELOC_MACH_O_X86_64_GOT -ENUMDOC - Used when referencing a GOT entry. -ENUM - BFD_RELOC_MACH_O_X86_64_GOT_LOAD -ENUMDOC - Used when loading a GOT entry with movq. It is specially marked so that - the linker could optimize the movq to a leaq if possible. -ENUM - BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32 -ENUMDOC - Symbol will be substracted. Must be followed by a BFD_RELOC_64. -ENUM - BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64 -ENUMDOC - Symbol will be substracted. Must be followed by a BFD_RELOC_64. -ENUM - BFD_RELOC_MACH_O_X86_64_PCREL32_1 -ENUMDOC - Same as BFD_RELOC_32_PCREL but with an implicit -1 addend. -ENUM - BFD_RELOC_MACH_O_X86_64_PCREL32_2 -ENUMDOC - Same as BFD_RELOC_32_PCREL but with an implicit -2 addend. -ENUM - BFD_RELOC_MACH_O_X86_64_PCREL32_4 -ENUMDOC - Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. - -ENUM - BFD_RELOC_MICROBLAZE_32_LO -ENUMDOC - This is a 32 bit reloc for the microblaze that stores the - low 16 bits of a value -ENUM - BFD_RELOC_MICROBLAZE_32_LO_PCREL -ENUMDOC - This is a 32 bit pc-relative reloc for the microblaze that - stores the low 16 bits of a value -ENUM - BFD_RELOC_MICROBLAZE_32_ROSDA -ENUMDOC - This is a 32 bit reloc for the microblaze that stores a - value relative to the read-only small data area anchor -ENUM - BFD_RELOC_MICROBLAZE_32_RWSDA -ENUMDOC - This is a 32 bit reloc for the microblaze that stores a - value relative to the read-write small data area anchor -ENUM - BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM -ENUMDOC - This is a 32 bit reloc for the microblaze to handle - expressions of the form "Symbol Op Symbol" -ENUM - BFD_RELOC_MICROBLAZE_64_NONE -ENUMDOC - This is a 64 bit reloc that stores the 32 bit pc relative - value in two words (with an imm instruction). No relocation is - done here - only used for relaxing -ENUM - BFD_RELOC_MICROBLAZE_64_GOTPC -ENUMDOC - This is a 64 bit reloc that stores the 32 bit pc relative - value in two words (with an imm instruction). The relocation is - PC-relative GOT offset -ENUM - BFD_RELOC_MICROBLAZE_64_GOT -ENUMDOC - This is a 64 bit reloc that stores the 32 bit pc relative - value in two words (with an imm instruction). The relocation is - GOT offset -ENUM - BFD_RELOC_MICROBLAZE_64_PLT -ENUMDOC - This is a 64 bit reloc that stores the 32 bit pc relative - value in two words (with an imm instruction). The relocation is - PC-relative offset into PLT -ENUM - BFD_RELOC_MICROBLAZE_64_GOTOFF -ENUMDOC - This is a 64 bit reloc that stores the 32 bit GOT relative - value in two words (with an imm instruction). The relocation is - relative offset from _GLOBAL_OFFSET_TABLE_ -ENUM - BFD_RELOC_MICROBLAZE_32_GOTOFF -ENUMDOC - This is a 32 bit reloc that stores the 32 bit GOT relative - value in a word. The relocation is relative offset from - _GLOBAL_OFFSET_TABLE_ -ENUM - BFD_RELOC_MICROBLAZE_COPY -ENUMDOC - This is used to tell the dynamic linker to copy the value out of - the dynamic object into the runtime process image. - -ENUM - BFD_RELOC_TILEPRO_COPY -ENUMX - BFD_RELOC_TILEPRO_GLOB_DAT -ENUMX - BFD_RELOC_TILEPRO_JMP_SLOT -ENUMX - BFD_RELOC_TILEPRO_RELATIVE -ENUMX - BFD_RELOC_TILEPRO_BROFF_X1 -ENUMX - BFD_RELOC_TILEPRO_JOFFLONG_X1 -ENUMX - BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT -ENUMX - BFD_RELOC_TILEPRO_IMM8_X0 -ENUMX - BFD_RELOC_TILEPRO_IMM8_Y0 -ENUMX - BFD_RELOC_TILEPRO_IMM8_X1 -ENUMX - BFD_RELOC_TILEPRO_IMM8_Y1 -ENUMX - BFD_RELOC_TILEPRO_DEST_IMM8_X1 -ENUMX - BFD_RELOC_TILEPRO_MT_IMM15_X1 -ENUMX - BFD_RELOC_TILEPRO_MF_IMM15_X1 -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0 -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1 -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_GOT -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_GOT -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA -ENUMX - BFD_RELOC_TILEPRO_MMSTART_X0 -ENUMX - BFD_RELOC_TILEPRO_MMEND_X0 -ENUMX - BFD_RELOC_TILEPRO_MMSTART_X1 -ENUMX - BFD_RELOC_TILEPRO_MMEND_X1 -ENUMX - BFD_RELOC_TILEPRO_SHAMT_X0 -ENUMX - BFD_RELOC_TILEPRO_SHAMT_X1 -ENUMX - BFD_RELOC_TILEPRO_SHAMT_Y0 -ENUMX - BFD_RELOC_TILEPRO_SHAMT_Y1 -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI -ENUMX - BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA -ENUMX - BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA -ENUMX - BFD_RELOC_TILEPRO_TLS_DTPMOD32 -ENUMX - BFD_RELOC_TILEPRO_TLS_DTPOFF32 -ENUMX - BFD_RELOC_TILEPRO_TLS_TPOFF32 -ENUMDOC - Tilera TILEPro Relocations. - -ENUM - BFD_RELOC_TILEGX_HW0 -ENUMX - BFD_RELOC_TILEGX_HW1 -ENUMX - BFD_RELOC_TILEGX_HW2 -ENUMX - BFD_RELOC_TILEGX_HW3 -ENUMX - BFD_RELOC_TILEGX_HW0_LAST -ENUMX - BFD_RELOC_TILEGX_HW1_LAST -ENUMX - BFD_RELOC_TILEGX_HW2_LAST -ENUMX - BFD_RELOC_TILEGX_COPY -ENUMX - BFD_RELOC_TILEGX_GLOB_DAT -ENUMX - BFD_RELOC_TILEGX_JMP_SLOT -ENUMX - BFD_RELOC_TILEGX_RELATIVE -ENUMX - BFD_RELOC_TILEGX_BROFF_X1 -ENUMX - BFD_RELOC_TILEGX_JUMPOFF_X1 -ENUMX - BFD_RELOC_TILEGX_JUMPOFF_X1_PLT -ENUMX - BFD_RELOC_TILEGX_IMM8_X0 -ENUMX - BFD_RELOC_TILEGX_IMM8_Y0 -ENUMX - BFD_RELOC_TILEGX_IMM8_X1 -ENUMX - BFD_RELOC_TILEGX_IMM8_Y1 -ENUMX - BFD_RELOC_TILEGX_DEST_IMM8_X1 -ENUMX - BFD_RELOC_TILEGX_MT_IMM14_X1 -ENUMX - BFD_RELOC_TILEGX_MF_IMM14_X1 -ENUMX - BFD_RELOC_TILEGX_MMSTART_X0 -ENUMX - BFD_RELOC_TILEGX_MMEND_X0 -ENUMX - BFD_RELOC_TILEGX_SHAMT_X0 -ENUMX - BFD_RELOC_TILEGX_SHAMT_X1 -ENUMX - BFD_RELOC_TILEGX_SHAMT_Y0 -ENUMX - BFD_RELOC_TILEGX_SHAMT_Y1 -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0 -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0 -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1 -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1 -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2 -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2 -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3 -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3 -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE -ENUMX - BFD_RELOC_TILEGX_TLS_DTPMOD64 -ENUMX - BFD_RELOC_TILEGX_TLS_DTPOFF64 -ENUMX - BFD_RELOC_TILEGX_TLS_TPOFF64 -ENUMX - BFD_RELOC_TILEGX_TLS_DTPMOD32 -ENUMX - BFD_RELOC_TILEGX_TLS_DTPOFF32 -ENUMX - BFD_RELOC_TILEGX_TLS_TPOFF32 -ENUMDOC - Tilera TILE-Gx Relocations. - - -ENDSENUM - BFD_RELOC_UNUSED -CODE_FRAGMENT -. -.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; -*/ - -/* -FUNCTION - bfd_reloc_type_lookup - bfd_reloc_name_lookup - -SYNOPSIS - reloc_howto_type *bfd_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); - reloc_howto_type *bfd_reloc_name_lookup - (bfd *abfd, const char *reloc_name); - -DESCRIPTION - Return a pointer to a howto structure which, when - invoked, will perform the relocation @var{code} on data from the - architecture noted. - -*/ - -reloc_howto_type * -bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) -{ - return BFD_SEND (abfd, reloc_type_lookup, (abfd, code)); -} - -reloc_howto_type * -bfd_reloc_name_lookup (bfd *abfd, const char *reloc_name) -{ - return BFD_SEND (abfd, reloc_name_lookup, (abfd, reloc_name)); -} - -static reloc_howto_type bfd_howto_32 = -HOWTO (0, 00, 2, 32, FALSE, 0, complain_overflow_dont, 0, "VRT32", FALSE, 0xffffffff, 0xffffffff, TRUE); - -/* -INTERNAL_FUNCTION - bfd_default_reloc_type_lookup - -SYNOPSIS - reloc_howto_type *bfd_default_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); - -DESCRIPTION - Provides a default relocation lookup routine for any architecture. - -*/ - -reloc_howto_type * -bfd_default_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) -{ - switch (code) - { - case BFD_RELOC_CTOR: - /* The type of reloc used in a ctor, which will be as wide as the - address - so either a 64, 32, or 16 bitter. */ - switch (bfd_arch_bits_per_address (abfd)) - { - case 64: - BFD_FAIL (); - case 32: - return &bfd_howto_32; - case 16: - BFD_FAIL (); - default: - BFD_FAIL (); - } - default: - BFD_FAIL (); - } - return NULL; -} - -/* -FUNCTION - bfd_get_reloc_code_name - -SYNOPSIS - const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); - -DESCRIPTION - Provides a printable name for the supplied relocation code. - Useful mainly for printing error messages. -*/ - -const char * -bfd_get_reloc_code_name (bfd_reloc_code_real_type code) -{ - if (code > BFD_RELOC_UNUSED) - return 0; - return bfd_reloc_code_real_names[code]; -} - -/* -INTERNAL_FUNCTION - bfd_generic_relax_section - -SYNOPSIS - bfd_boolean bfd_generic_relax_section - (bfd *abfd, - asection *section, - struct bfd_link_info *, - bfd_boolean *); - -DESCRIPTION - Provides default handling for relaxing for back ends which - don't do relaxing. -*/ - -bfd_boolean -bfd_generic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - bfd_boolean *again) -{ - if (link_info->relocatable) - (*link_info->callbacks->einfo) - (_("%P%F: --relax and -r may not be used together\n")); - - *again = FALSE; - return TRUE; -} - -/* -INTERNAL_FUNCTION - bfd_generic_gc_sections - -SYNOPSIS - bfd_boolean bfd_generic_gc_sections - (bfd *, struct bfd_link_info *); - -DESCRIPTION - Provides default handling for relaxing for back ends which - don't do section gc -- i.e., does nothing. -*/ - -bfd_boolean -bfd_generic_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* -INTERNAL_FUNCTION - bfd_generic_lookup_section_flags - -SYNOPSIS - void bfd_generic_lookup_section_flags - (struct bfd_link_info *, struct flag_info *); - -DESCRIPTION - Provides default handling for section flags lookup - -- i.e., does nothing. -*/ - -void -bfd_generic_lookup_section_flags (struct bfd_link_info *info ATTRIBUTE_UNUSED, - struct flag_info *finfo) -{ - if (finfo != NULL) - { - (*_bfd_error_handler) (_("INPUT_SECTION_FLAGS are not supported.\n")); - return; - } -} - -/* -INTERNAL_FUNCTION - bfd_generic_merge_sections - -SYNOPSIS - bfd_boolean bfd_generic_merge_sections - (bfd *, struct bfd_link_info *); - -DESCRIPTION - Provides default handling for SEC_MERGE section merging for back ends - which don't have SEC_MERGE support -- i.e., does nothing. -*/ - -bfd_boolean -bfd_generic_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *link_info ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* -INTERNAL_FUNCTION - bfd_generic_get_relocated_section_contents - -SYNOPSIS - bfd_byte *bfd_generic_get_relocated_section_contents - (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - bfd_boolean relocatable, - asymbol **symbols); - -DESCRIPTION - Provides default handling of relocation effort for back ends - which can't be bothered to do it efficiently. - -*/ - -bfd_byte * -bfd_generic_get_relocated_section_contents (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - bfd_boolean relocatable, - asymbol **symbols) -{ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size; - arelent **reloc_vector; - long reloc_count; - - reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - if (reloc_size < 0) - return NULL; - - /* Read in the section. */ - if (!bfd_get_full_section_contents (input_bfd, input_section, &data)) - return NULL; - - if (reloc_size == 0) - return data; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL) - return NULL; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent != NULL; parent++) - { - char *error_message = NULL; - asymbol *symbol; - bfd_reloc_status_type r; - - symbol = *(*parent)->sym_ptr_ptr; - if (symbol->section && elf_discarded_section (symbol->section)) - { - bfd_byte *p; - static reloc_howto_type none_howto - = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, - "unused", FALSE, 0, 0, FALSE); - - p = data + (*parent)->address * bfd_octets_per_byte (input_bfd); - _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, - p); - (*parent)->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; - (*parent)->addend = 0; - (*parent)->howto = &none_howto; - r = bfd_reloc_ok; - } - else - r = bfd_perform_relocation (input_bfd, - *parent, - data, - input_section, - relocatable ? abfd : NULL, - &error_message); - - if (relocatable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs. */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (!((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address, - TRUE))) - goto error_return; - break; - case bfd_reloc_dangerous: - BFD_ASSERT (error_message != NULL); - if (!((*link_info->callbacks->reloc_dangerous) - (link_info, error_message, input_bfd, input_section, - (*parent)->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (!((*link_info->callbacks->reloc_overflow) - (link_info, NULL, - bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - (*parent)->howto->name, (*parent)->addend, - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - - } - } - } - - free (reloc_vector); - return data; - -error_return: - free (reloc_vector); - return NULL; -} diff --git a/contrib/binutils-2.22/bfd/section.c b/contrib/binutils-2.22/bfd/section.c deleted file mode 100644 index 7c1f750483..0000000000 --- a/contrib/binutils-2.22/bfd/section.c +++ /dev/null @@ -1,1588 +0,0 @@ -/* Object file "section" support for the BFD library. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - Sections - - The raw data contained within a BFD is maintained through the - section abstraction. A single BFD may have any number of - sections. It keeps hold of them by pointing to the first; - each one points to the next in the list. - - Sections are supported in BFD in <>. - -@menu -@* Section Input:: -@* Section Output:: -@* typedef asection:: -@* section prototypes:: -@end menu - -INODE -Section Input, Section Output, Sections, Sections -SUBSECTION - Section input - - When a BFD is opened for reading, the section structures are - created and attached to the BFD. - - Each section has a name which describes the section in the - outside world---for example, <> would contain at least - three sections, called <<.text>>, <<.data>> and <<.bss>>. - - Names need not be unique; for example a COFF file may have several - sections named <<.data>>. - - Sometimes a BFD will contain more than the ``natural'' number of - sections. A back end may attach other sections containing - constructor data, or an application may add a section (using - <>) to the sections attached to an already open - BFD. For example, the linker creates an extra section - <> for each input file's BFD to hold information about - common storage. - - The raw data is not necessarily read in when - the section descriptor is created. Some targets may leave the - data in place until a <> call is - made. Other back ends may read in all the data at once. For - example, an S-record file has to be read once to determine the - size of the data. An IEEE-695 file doesn't contain raw data in - sections, but data and relocation expressions intermixed, so - the data area has to be parsed to get out the data and - relocations. - -INODE -Section Output, typedef asection, Section Input, Sections - -SUBSECTION - Section output - - To write a new object style BFD, the various sections to be - written have to be created. They are attached to the BFD in - the same way as input sections; data is written to the - sections using <>. - - Any program that creates or combines sections (e.g., the assembler - and linker) must use the <> fields <> and - <> to indicate the file sections to which each - section must be written. (If the section is being created from - scratch, <> should probably point to the section - itself and <> should probably be zero.) - - The data to be written comes from input sections attached - (via <> pointers) to - the output sections. The output section structure can be - considered a filter for the input section: the output section - determines the vma of the output data and the name, but the - input section determines the offset into the output section of - the data to be written. - - E.g., to create a section "O", starting at 0x100, 0x123 long, - containing two subsections, "A" at offset 0x0 (i.e., at vma - 0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the <> - structures would look like: - -| section name "A" -| output_offset 0x00 -| size 0x20 -| output_section -----------> section name "O" -| | vma 0x100 -| section name "B" | size 0x123 -| output_offset 0x20 | -| size 0x103 | -| output_section --------| - -SUBSECTION - Link orders - - The data within a section is stored in a @dfn{link_order}. - These are much like the fixups in <>. The link_order - abstraction allows a section to grow and shrink within itself. - - A link_order knows how big it is, and which is the next - link_order and where the raw data for it is; it also points to - a list of relocations which apply to it. - - The link_order is used by the linker to perform relaxing on - final code. The compiler creates code which is as big as - necessary to make it work without relaxing, and the user can - select whether to relax. Sometimes relaxing takes a lot of - time. The linker runs around the relocations to see if any - are attached to data which can be shrunk, if so it does it on - a link_order by link_order basis. - -*/ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "bfdlink.h" - -/* -DOCDD -INODE -typedef asection, section prototypes, Section Output, Sections -SUBSECTION - typedef asection - - Here is the section structure: - -CODE_FRAGMENT -. -.typedef struct bfd_section -.{ -. {* The name of the section; the name isn't a copy, the pointer is -. the same as that passed to bfd_make_section. *} -. const char *name; -. -. {* A unique sequence number. *} -. int id; -. -. {* Which section in the bfd; 0..n-1 as sections are created in a bfd. *} -. int index; -. -. {* The next section in the list belonging to the BFD, or NULL. *} -. struct bfd_section *next; -. -. {* The previous section in the list belonging to the BFD, or NULL. *} -. struct bfd_section *prev; -. -. {* The field flags contains attributes of the section. Some -. flags are read in from the object file, and some are -. synthesized from other information. *} -. flagword flags; -. -.#define SEC_NO_FLAGS 0x000 -. -. {* Tells the OS to allocate space for this section when loading. -. This is clear for a section containing debug information only. *} -.#define SEC_ALLOC 0x001 -. -. {* Tells the OS to load the section from the file when loading. -. This is clear for a .bss section. *} -.#define SEC_LOAD 0x002 -. -. {* The section contains data still to be relocated, so there is -. some relocation information too. *} -.#define SEC_RELOC 0x004 -. -. {* A signal to the OS that the section contains read only data. *} -.#define SEC_READONLY 0x008 -. -. {* The section contains code only. *} -.#define SEC_CODE 0x010 -. -. {* The section contains data only. *} -.#define SEC_DATA 0x020 -. -. {* The section will reside in ROM. *} -.#define SEC_ROM 0x040 -. -. {* The section contains constructor information. This section -. type is used by the linker to create lists of constructors and -. destructors used by <>. When a back end sees a symbol -. which should be used in a constructor list, it creates a new -. section for the type of name (e.g., <<__CTOR_LIST__>>), attaches -. the symbol to it, and builds a relocation. To build the lists -. of constructors, all the linker has to do is catenate all the -. sections called <<__CTOR_LIST__>> and relocate the data -. contained within - exactly the operations it would peform on -. standard data. *} -.#define SEC_CONSTRUCTOR 0x080 -. -. {* The section has contents - a data section could be -. <> | <>; a debug section could be -. <> *} -.#define SEC_HAS_CONTENTS 0x100 -. -. {* An instruction to the linker to not output the section -. even if it has information which would normally be written. *} -.#define SEC_NEVER_LOAD 0x200 -. -. {* The section contains thread local data. *} -.#define SEC_THREAD_LOCAL 0x400 -. -. {* The section has GOT references. This flag is only for the -. linker, and is currently only used by the elf32-hppa back end. -. It will be set if global offset table references were detected -. in this section, which indicate to the linker that the section -. contains PIC code, and must be handled specially when doing a -. static link. *} -.#define SEC_HAS_GOT_REF 0x800 -. -. {* The section contains common symbols (symbols may be defined -. multiple times, the value of a symbol is the amount of -. space it requires, and the largest symbol value is the one -. used). Most targets have exactly one of these (which we -. translate to bfd_com_section_ptr), but ECOFF has two. *} -.#define SEC_IS_COMMON 0x1000 -. -. {* The section contains only debugging information. For -. example, this is set for ELF .debug and .stab sections. -. strip tests this flag to see if a section can be -. discarded. *} -.#define SEC_DEBUGGING 0x2000 -. -. {* The contents of this section are held in memory pointed to -. by the contents field. This is checked by bfd_get_section_contents, -. and the data is retrieved from memory if appropriate. *} -.#define SEC_IN_MEMORY 0x4000 -. -. {* The contents of this section are to be excluded by the -. linker for executable and shared objects unless those -. objects are to be further relocated. *} -.#define SEC_EXCLUDE 0x8000 -. -. {* The contents of this section are to be sorted based on the sum of -. the symbol and addend values specified by the associated relocation -. entries. Entries without associated relocation entries will be -. appended to the end of the section in an unspecified order. *} -.#define SEC_SORT_ENTRIES 0x10000 -. -. {* When linking, duplicate sections of the same name should be -. discarded, rather than being combined into a single section as -. is usually done. This is similar to how common symbols are -. handled. See SEC_LINK_DUPLICATES below. *} -.#define SEC_LINK_ONCE 0x20000 -. -. {* If SEC_LINK_ONCE is set, this bitfield describes how the linker -. should handle duplicate sections. *} -.#define SEC_LINK_DUPLICATES 0xc0000 -. -. {* This value for SEC_LINK_DUPLICATES means that duplicate -. sections with the same name should simply be discarded. *} -.#define SEC_LINK_DUPLICATES_DISCARD 0x0 -. -. {* This value for SEC_LINK_DUPLICATES means that the linker -. should warn if there are any duplicate sections, although -. it should still only link one copy. *} -.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x40000 -. -. {* This value for SEC_LINK_DUPLICATES means that the linker -. should warn if any duplicate sections are a different size. *} -.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x80000 -. -. {* This value for SEC_LINK_DUPLICATES means that the linker -. should warn if any duplicate sections contain different -. contents. *} -.#define SEC_LINK_DUPLICATES_SAME_CONTENTS \ -. (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) -. -. {* This section was created by the linker as part of dynamic -. relocation or other arcane processing. It is skipped when -. going through the first-pass output, trusting that someone -. else up the line will take care of it later. *} -.#define SEC_LINKER_CREATED 0x100000 -. -. {* This section should not be subject to garbage collection. -. Also set to inform the linker that this section should not be -. listed in the link map as discarded. *} -.#define SEC_KEEP 0x200000 -. -. {* This section contains "short" data, and should be placed -. "near" the GP. *} -.#define SEC_SMALL_DATA 0x400000 -. -. {* Attempt to merge identical entities in the section. -. Entity size is given in the entsize field. *} -.#define SEC_MERGE 0x800000 -. -. {* If given with SEC_MERGE, entities to merge are zero terminated -. strings where entsize specifies character size instead of fixed -. size entries. *} -.#define SEC_STRINGS 0x1000000 -. -. {* This section contains data about section groups. *} -.#define SEC_GROUP 0x2000000 -. -. {* The section is a COFF shared library section. This flag is -. only for the linker. If this type of section appears in -. the input file, the linker must copy it to the output file -. without changing the vma or size. FIXME: Although this -. was originally intended to be general, it really is COFF -. specific (and the flag was renamed to indicate this). It -. might be cleaner to have some more general mechanism to -. allow the back end to control what the linker does with -. sections. *} -.#define SEC_COFF_SHARED_LIBRARY 0x4000000 -. -. {* This input section should be copied to output in reverse order -. as an array of pointers. This is for ELF linker internal use -. only. *} -.#define SEC_ELF_REVERSE_COPY 0x4000000 -. -. {* This section contains data which may be shared with other -. executables or shared objects. This is for COFF only. *} -.#define SEC_COFF_SHARED 0x8000000 -. -. {* When a section with this flag is being linked, then if the size of -. the input section is less than a page, it should not cross a page -. boundary. If the size of the input section is one page or more, -. it should be aligned on a page boundary. This is for TI -. TMS320C54X only. *} -.#define SEC_TIC54X_BLOCK 0x10000000 -. -. {* Conditionally link this section; do not link if there are no -. references found to any symbol in the section. This is for TI -. TMS320C54X only. *} -.#define SEC_TIC54X_CLINK 0x20000000 -. -. {* Indicate that section has the no read flag set. This happens -. when memory read flag isn't set. *} -.#define SEC_COFF_NOREAD 0x40000000 -. -. {* End of section flags. *} -. -. {* Some internal packed boolean fields. *} -. -. {* See the vma field. *} -. unsigned int user_set_vma : 1; -. -. {* A mark flag used by some of the linker backends. *} -. unsigned int linker_mark : 1; -. -. {* Another mark flag used by some of the linker backends. Set for -. output sections that have an input section. *} -. unsigned int linker_has_input : 1; -. -. {* Mark flag used by some linker backends for garbage collection. *} -. unsigned int gc_mark : 1; -. -. {* Section compression status. *} -. unsigned int compress_status : 2; -.#define COMPRESS_SECTION_NONE 0 -.#define COMPRESS_SECTION_DONE 1 -.#define DECOMPRESS_SECTION_SIZED 2 -. -. {* The following flags are used by the ELF linker. *} -. -. {* Mark sections which have been allocated to segments. *} -. unsigned int segment_mark : 1; -. -. {* Type of sec_info information. *} -. unsigned int sec_info_type:3; -.#define ELF_INFO_TYPE_NONE 0 -.#define ELF_INFO_TYPE_STABS 1 -.#define ELF_INFO_TYPE_MERGE 2 -.#define ELF_INFO_TYPE_EH_FRAME 3 -.#define ELF_INFO_TYPE_JUST_SYMS 4 -. -. {* Nonzero if this section uses RELA relocations, rather than REL. *} -. unsigned int use_rela_p:1; -. -. {* Bits used by various backends. The generic code doesn't touch -. these fields. *} -. -. unsigned int sec_flg0:1; -. unsigned int sec_flg1:1; -. unsigned int sec_flg2:1; -. unsigned int sec_flg3:1; -. unsigned int sec_flg4:1; -. unsigned int sec_flg5:1; -. -. {* End of internal packed boolean fields. *} -. -. {* The virtual memory address of the section - where it will be -. at run time. The symbols are relocated against this. The -. user_set_vma flag is maintained by bfd; if it's not set, the -. backend can assign addresses (for example, in <>, where -. the default address for <<.data>> is dependent on the specific -. target and various flags). *} -. bfd_vma vma; -. -. {* The load address of the section - where it would be in a -. rom image; really only used for writing section header -. information. *} -. bfd_vma lma; -. -. {* The size of the section in octets, as it will be output. -. Contains a value even if the section has no contents (e.g., the -. size of <<.bss>>). *} -. bfd_size_type size; -. -. {* For input sections, the original size on disk of the section, in -. octets. This field should be set for any section whose size is -. changed by linker relaxation. It is required for sections where -. the linker relaxation scheme doesn't cache altered section and -. reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing -. targets), and thus the original size needs to be kept to read the -. section multiple times. For output sections, rawsize holds the -. section size calculated on a previous linker relaxation pass. *} -. bfd_size_type rawsize; -. -. {* The compressed size of the section in octets. *} -. bfd_size_type compressed_size; -. -. {* Relaxation table. *} -. struct relax_table *relax; -. -. {* Count of used relaxation table entries. *} -. int relax_count; -. -. -. {* If this section is going to be output, then this value is the -. offset in *bytes* into the output section of the first byte in the -. input section (byte ==> smallest addressable unit on the -. target). In most cases, if this was going to start at the -. 100th octet (8-bit quantity) in the output section, this value -. would be 100. However, if the target byte size is 16 bits -. (bfd_octets_per_byte is "2"), this value would be 50. *} -. bfd_vma output_offset; -. -. {* The output section through which to map on output. *} -. struct bfd_section *output_section; -. -. {* The alignment requirement of the section, as an exponent of 2 - -. e.g., 3 aligns to 2^3 (or 8). *} -. unsigned int alignment_power; -. -. {* If an input section, a pointer to a vector of relocation -. records for the data in this section. *} -. struct reloc_cache_entry *relocation; -. -. {* If an output section, a pointer to a vector of pointers to -. relocation records for the data in this section. *} -. struct reloc_cache_entry **orelocation; -. -. {* The number of relocation records in one of the above. *} -. unsigned reloc_count; -. -. {* Information below is back end specific - and not always used -. or updated. *} -. -. {* File position of section data. *} -. file_ptr filepos; -. -. {* File position of relocation info. *} -. file_ptr rel_filepos; -. -. {* File position of line data. *} -. file_ptr line_filepos; -. -. {* Pointer to data for applications. *} -. void *userdata; -. -. {* If the SEC_IN_MEMORY flag is set, this points to the actual -. contents. *} -. unsigned char *contents; -. -. {* Attached line number information. *} -. alent *lineno; -. -. {* Number of line number records. *} -. unsigned int lineno_count; -. -. {* Entity size for merging purposes. *} -. unsigned int entsize; -. -. {* Points to the kept section if this section is a link-once section, -. and is discarded. *} -. struct bfd_section *kept_section; -. -. {* When a section is being output, this value changes as more -. linenumbers are written out. *} -. file_ptr moving_line_filepos; -. -. {* What the section number is in the target world. *} -. int target_index; -. -. void *used_by_bfd; -. -. {* If this is a constructor section then here is a list of the -. relocations created to relocate items within it. *} -. struct relent_chain *constructor_chain; -. -. {* The BFD which owns the section. *} -. bfd *owner; -. -. {* INPUT_SECTION_FLAGS if specified in the linker script. *} -. struct flag_info *section_flag_info; -. -. {* A symbol which points at this section only. *} -. struct bfd_symbol *symbol; -. struct bfd_symbol **symbol_ptr_ptr; -. -. {* Early in the link process, map_head and map_tail are used to build -. a list of input sections attached to an output section. Later, -. output sections use these fields for a list of bfd_link_order -. structs. *} -. union { -. struct bfd_link_order *link_order; -. struct bfd_section *s; -. } map_head, map_tail; -.} asection; -. -.{* Relax table contains information about instructions which can -. be removed by relaxation -- replacing a long address with a -. short address. *} -.struct relax_table { -. {* Address where bytes may be deleted. *} -. bfd_vma addr; -. -. {* Number of bytes to be deleted. *} -. int size; -.}; -. -.{* These sections are global, and are managed by BFD. The application -. and target back end are not permitted to change the values in -. these sections. New code should use the section_ptr macros rather -. than referring directly to the const sections. The const sections -. may eventually vanish. *} -.#define BFD_ABS_SECTION_NAME "*ABS*" -.#define BFD_UND_SECTION_NAME "*UND*" -.#define BFD_COM_SECTION_NAME "*COM*" -.#define BFD_IND_SECTION_NAME "*IND*" -. -.{* The absolute section. *} -.extern asection bfd_abs_section; -.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) -.{* Pointer to the undefined section. *} -.extern asection bfd_und_section; -.#define bfd_und_section_ptr ((asection *) &bfd_und_section) -.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) -.{* Pointer to the common section. *} -.extern asection bfd_com_section; -.#define bfd_com_section_ptr ((asection *) &bfd_com_section) -.{* Pointer to the indirect section. *} -.extern asection bfd_ind_section; -.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -.#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) -. -.#define bfd_is_const_section(SEC) \ -. ( ((SEC) == bfd_abs_section_ptr) \ -. || ((SEC) == bfd_und_section_ptr) \ -. || ((SEC) == bfd_com_section_ptr) \ -. || ((SEC) == bfd_ind_section_ptr)) -. -.{* Macros to handle insertion and deletion of a bfd's sections. These -. only handle the list pointers, ie. do not adjust section_count, -. target_index etc. *} -.#define bfd_section_list_remove(ABFD, S) \ -. do \ -. { \ -. asection *_s = S; \ -. asection *_next = _s->next; \ -. asection *_prev = _s->prev; \ -. if (_prev) \ -. _prev->next = _next; \ -. else \ -. (ABFD)->sections = _next; \ -. if (_next) \ -. _next->prev = _prev; \ -. else \ -. (ABFD)->section_last = _prev; \ -. } \ -. while (0) -.#define bfd_section_list_append(ABFD, S) \ -. do \ -. { \ -. asection *_s = S; \ -. bfd *_abfd = ABFD; \ -. _s->next = NULL; \ -. if (_abfd->section_last) \ -. { \ -. _s->prev = _abfd->section_last; \ -. _abfd->section_last->next = _s; \ -. } \ -. else \ -. { \ -. _s->prev = NULL; \ -. _abfd->sections = _s; \ -. } \ -. _abfd->section_last = _s; \ -. } \ -. while (0) -.#define bfd_section_list_prepend(ABFD, S) \ -. do \ -. { \ -. asection *_s = S; \ -. bfd *_abfd = ABFD; \ -. _s->prev = NULL; \ -. if (_abfd->sections) \ -. { \ -. _s->next = _abfd->sections; \ -. _abfd->sections->prev = _s; \ -. } \ -. else \ -. { \ -. _s->next = NULL; \ -. _abfd->section_last = _s; \ -. } \ -. _abfd->sections = _s; \ -. } \ -. while (0) -.#define bfd_section_list_insert_after(ABFD, A, S) \ -. do \ -. { \ -. asection *_a = A; \ -. asection *_s = S; \ -. asection *_next = _a->next; \ -. _s->next = _next; \ -. _s->prev = _a; \ -. _a->next = _s; \ -. if (_next) \ -. _next->prev = _s; \ -. else \ -. (ABFD)->section_last = _s; \ -. } \ -. while (0) -.#define bfd_section_list_insert_before(ABFD, B, S) \ -. do \ -. { \ -. asection *_b = B; \ -. asection *_s = S; \ -. asection *_prev = _b->prev; \ -. _s->prev = _prev; \ -. _s->next = _b; \ -. _b->prev = _s; \ -. if (_prev) \ -. _prev->next = _s; \ -. else \ -. (ABFD)->sections = _s; \ -. } \ -. while (0) -.#define bfd_section_removed_from_list(ABFD, S) \ -. ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) -. -.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ -. {* name, id, index, next, prev, flags, user_set_vma, *} \ -. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ -. \ -. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \ -. 0, 0, 1, 0, \ -. \ -. {* segment_mark, sec_info_type, use_rela_p, *} \ -. 0, 0, 0, \ -. \ -. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \ -. 0, 0, 0, 0, 0, 0, \ -. \ -. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \ -. 0, 0, 0, 0, 0, 0, 0, \ -. \ -. {* output_offset, output_section, alignment_power, *} \ -. 0, (struct bfd_section *) &SEC, 0, \ -. \ -. {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \ -. NULL, NULL, 0, 0, 0, \ -. \ -. {* line_filepos, userdata, contents, lineno, lineno_count, *} \ -. 0, NULL, NULL, NULL, 0, \ -. \ -. {* entsize, kept_section, moving_line_filepos, *} \ -. 0, NULL, 0, \ -. \ -. {* target_index, used_by_bfd, constructor_chain, owner, *} \ -. 0, NULL, NULL, NULL, \ -. \ -. {* flag_info, *} \ -. NULL, \ -. \ -. {* symbol, symbol_ptr_ptr, *} \ -. (struct bfd_symbol *) SYM, &SEC.symbol, \ -. \ -. {* map_head, map_tail *} \ -. { NULL }, { NULL } \ -. } -. -*/ - -/* We use a macro to initialize the static asymbol structures because - traditional C does not permit us to initialize a union member while - gcc warns if we don't initialize it. */ - /* the_bfd, name, value, attr, section [, udata] */ -#ifdef __STDC__ -#define GLOBAL_SYM_INIT(NAME, SECTION) \ - { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION, { 0 }} -#else -#define GLOBAL_SYM_INIT(NAME, SECTION) \ - { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION } -#endif - -/* These symbols are global, not specific to any BFD. Therefore, anything - that tries to change them is broken, and should be repaired. */ - -static const asymbol global_syms[] = -{ - GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, &bfd_com_section), - GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, &bfd_und_section), - GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, &bfd_abs_section), - GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section) -}; - -#define STD_SECTION(SEC, FLAGS, NAME, IDX) \ - asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], \ - NAME, IDX) - -STD_SECTION (bfd_com_section, SEC_IS_COMMON, BFD_COM_SECTION_NAME, 0); -STD_SECTION (bfd_und_section, 0, BFD_UND_SECTION_NAME, 1); -STD_SECTION (bfd_abs_section, 0, BFD_ABS_SECTION_NAME, 2); -STD_SECTION (bfd_ind_section, 0, BFD_IND_SECTION_NAME, 3); -#undef STD_SECTION - -/* Initialize an entry in the section hash table. */ - -struct bfd_hash_entry * -bfd_section_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (entry == NULL) - { - entry = (struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct section_hash_entry)); - if (entry == NULL) - return entry; - } - - /* Call the allocation method of the superclass. */ - entry = bfd_hash_newfunc (entry, table, string); - if (entry != NULL) - memset (&((struct section_hash_entry *) entry)->section, 0, - sizeof (asection)); - - return entry; -} - -#define section_hash_lookup(table, string, create, copy) \ - ((struct section_hash_entry *) \ - bfd_hash_lookup ((table), (string), (create), (copy))) - -/* Create a symbol whose only job is to point to this section. This - is useful for things like relocs which are relative to the base - of a section. */ - -bfd_boolean -_bfd_generic_new_section_hook (bfd *abfd, asection *newsect) -{ - newsect->symbol = bfd_make_empty_symbol (abfd); - if (newsect->symbol == NULL) - return FALSE; - - newsect->symbol->name = newsect->name; - newsect->symbol->value = 0; - newsect->symbol->section = newsect; - newsect->symbol->flags = BSF_SECTION_SYM; - - newsect->symbol_ptr_ptr = &newsect->symbol; - return TRUE; -} - -/* Initializes a new section. NEWSECT->NAME is already set. */ - -static asection * -bfd_section_init (bfd *abfd, asection *newsect) -{ - static int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */ - - newsect->id = section_id; - newsect->index = abfd->section_count; - newsect->owner = abfd; - - if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect))) - return NULL; - - section_id++; - abfd->section_count++; - bfd_section_list_append (abfd, newsect); - return newsect; -} - -/* -DOCDD -INODE -section prototypes, , typedef asection, Sections -SUBSECTION - Section prototypes - -These are the functions exported by the section handling part of BFD. -*/ - -/* -FUNCTION - bfd_section_list_clear - -SYNOPSIS - void bfd_section_list_clear (bfd *); - -DESCRIPTION - Clears the section list, and also resets the section count and - hash table entries. -*/ - -void -bfd_section_list_clear (bfd *abfd) -{ - abfd->sections = NULL; - abfd->section_last = NULL; - abfd->section_count = 0; - memset (abfd->section_htab.table, 0, - abfd->section_htab.size * sizeof (struct bfd_hash_entry *)); -} - -/* -FUNCTION - bfd_get_section_by_name - -SYNOPSIS - asection *bfd_get_section_by_name (bfd *abfd, const char *name); - -DESCRIPTION - Run through @var{abfd} and return the one of the - <>s whose name matches @var{name}, otherwise <>. - @xref{Sections}, for more information. - - This should only be used in special cases; the normal way to process - all sections of a given name is to use <> and - <> on the name (or better yet, base it on the section flags - or something else) for each section. -*/ - -asection * -bfd_get_section_by_name (bfd *abfd, const char *name) -{ - struct section_hash_entry *sh; - - sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE); - if (sh != NULL) - return &sh->section; - - return NULL; -} - -/* -FUNCTION - bfd_get_section_by_name_if - -SYNOPSIS - asection *bfd_get_section_by_name_if - (bfd *abfd, - const char *name, - bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), - void *obj); - -DESCRIPTION - Call the provided function @var{func} for each section - attached to the BFD @var{abfd} whose name matches @var{name}, - passing @var{obj} as an argument. The function will be called - as if by - -| func (abfd, the_section, obj); - - It returns the first section for which @var{func} returns true, - otherwise <>. - -*/ - -asection * -bfd_get_section_by_name_if (bfd *abfd, const char *name, - bfd_boolean (*operation) (bfd *, - asection *, - void *), - void *user_storage) -{ - struct section_hash_entry *sh; - unsigned long hash; - - sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE); - if (sh == NULL) - return NULL; - - hash = sh->root.hash; - do - { - if ((*operation) (abfd, &sh->section, user_storage)) - return &sh->section; - sh = (struct section_hash_entry *) sh->root.next; - } - while (sh != NULL && sh->root.hash == hash - && strcmp (sh->root.string, name) == 0); - - return NULL; -} - -/* -FUNCTION - bfd_get_unique_section_name - -SYNOPSIS - char *bfd_get_unique_section_name - (bfd *abfd, const char *templat, int *count); - -DESCRIPTION - Invent a section name that is unique in @var{abfd} by tacking - a dot and a digit suffix onto the original @var{templat}. If - @var{count} is non-NULL, then it specifies the first number - tried as a suffix to generate a unique name. The value - pointed to by @var{count} will be incremented in this case. -*/ - -char * -bfd_get_unique_section_name (bfd *abfd, const char *templat, int *count) -{ - int num; - unsigned int len; - char *sname; - - len = strlen (templat); - sname = (char *) bfd_malloc (len + 8); - if (sname == NULL) - return NULL; - memcpy (sname, templat, len); - num = 1; - if (count != NULL) - num = *count; - - do - { - /* If we have a million sections, something is badly wrong. */ - if (num > 999999) - abort (); - sprintf (sname + len, ".%d", num++); - } - while (section_hash_lookup (&abfd->section_htab, sname, FALSE, FALSE)); - - if (count != NULL) - *count = num; - return sname; -} - -/* -FUNCTION - bfd_make_section_old_way - -SYNOPSIS - asection *bfd_make_section_old_way (bfd *abfd, const char *name); - -DESCRIPTION - Create a new empty section called @var{name} - and attach it to the end of the chain of sections for the - BFD @var{abfd}. An attempt to create a section with a name which - is already in use returns its pointer without changing the - section chain. - - It has the funny name since this is the way it used to be - before it was rewritten.... - - Possible errors are: - o <> - - If output has already started for this BFD. - o <> - - If memory allocation fails. - -*/ - -asection * -bfd_make_section_old_way (bfd *abfd, const char *name) -{ - asection *newsect; - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - if (strcmp (name, BFD_ABS_SECTION_NAME) == 0) - newsect = bfd_abs_section_ptr; - else if (strcmp (name, BFD_COM_SECTION_NAME) == 0) - newsect = bfd_com_section_ptr; - else if (strcmp (name, BFD_UND_SECTION_NAME) == 0) - newsect = bfd_und_section_ptr; - else if (strcmp (name, BFD_IND_SECTION_NAME) == 0) - newsect = bfd_ind_section_ptr; - else - { - struct section_hash_entry *sh; - - sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE); - if (sh == NULL) - return NULL; - - newsect = &sh->section; - if (newsect->name != NULL) - { - /* Section already exists. */ - return newsect; - } - - newsect->name = name; - return bfd_section_init (abfd, newsect); - } - - /* Call new_section_hook when "creating" the standard abs, com, und - and ind sections to tack on format specific section data. - Also, create a proper section symbol. */ - if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect))) - return NULL; - return newsect; -} - -/* -FUNCTION - bfd_make_section_anyway_with_flags - -SYNOPSIS - asection *bfd_make_section_anyway_with_flags - (bfd *abfd, const char *name, flagword flags); - -DESCRIPTION - Create a new empty section called @var{name} and attach it to the end of - the chain of sections for @var{abfd}. Create a new section even if there - is already a section with that name. Also set the attributes of the - new section to the value @var{flags}. - - Return <> and set <> on error; possible errors are: - o <> - If output has already started for @var{abfd}. - o <> - If memory allocation fails. -*/ - -sec_ptr -bfd_make_section_anyway_with_flags (bfd *abfd, const char *name, - flagword flags) -{ - struct section_hash_entry *sh; - asection *newsect; - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE); - if (sh == NULL) - return NULL; - - newsect = &sh->section; - if (newsect->name != NULL) - { - /* We are making a section of the same name. Put it in the - section hash table. Even though we can't find it directly by a - hash lookup, we'll be able to find the section by traversing - sh->root.next quicker than looking at all the bfd sections. */ - struct section_hash_entry *new_sh; - new_sh = (struct section_hash_entry *) - bfd_section_hash_newfunc (NULL, &abfd->section_htab, name); - if (new_sh == NULL) - return NULL; - - new_sh->root = sh->root; - sh->root.next = &new_sh->root; - newsect = &new_sh->section; - } - - newsect->flags = flags; - newsect->name = name; - return bfd_section_init (abfd, newsect); -} - -/* -FUNCTION - bfd_make_section_anyway - -SYNOPSIS - asection *bfd_make_section_anyway (bfd *abfd, const char *name); - -DESCRIPTION - Create a new empty section called @var{name} and attach it to the end of - the chain of sections for @var{abfd}. Create a new section even if there - is already a section with that name. - - Return <> and set <> on error; possible errors are: - o <> - If output has already started for @var{abfd}. - o <> - If memory allocation fails. -*/ - -sec_ptr -bfd_make_section_anyway (bfd *abfd, const char *name) -{ - return bfd_make_section_anyway_with_flags (abfd, name, 0); -} - -/* -FUNCTION - bfd_make_section_with_flags - -SYNOPSIS - asection *bfd_make_section_with_flags - (bfd *, const char *name, flagword flags); - -DESCRIPTION - Like <>, but return <> (without calling - bfd_set_error ()) without changing the section chain if there is already a - section named @var{name}. Also set the attributes of the new section to - the value @var{flags}. If there is an error, return <> and set - <>. -*/ - -asection * -bfd_make_section_with_flags (bfd *abfd, const char *name, - flagword flags) -{ - struct section_hash_entry *sh; - asection *newsect; - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - if (strcmp (name, BFD_ABS_SECTION_NAME) == 0 - || strcmp (name, BFD_COM_SECTION_NAME) == 0 - || strcmp (name, BFD_UND_SECTION_NAME) == 0 - || strcmp (name, BFD_IND_SECTION_NAME) == 0) - return NULL; - - sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE); - if (sh == NULL) - return NULL; - - newsect = &sh->section; - if (newsect->name != NULL) - { - /* Section already exists. */ - return NULL; - } - - newsect->name = name; - newsect->flags = flags; - return bfd_section_init (abfd, newsect); -} - -/* -FUNCTION - bfd_make_section - -SYNOPSIS - asection *bfd_make_section (bfd *, const char *name); - -DESCRIPTION - Like <>, but return <> (without calling - bfd_set_error ()) without changing the section chain if there is already a - section named @var{name}. If there is an error, return <> and set - <>. -*/ - -asection * -bfd_make_section (bfd *abfd, const char *name) -{ - return bfd_make_section_with_flags (abfd, name, 0); -} - -/* -FUNCTION - bfd_set_section_flags - -SYNOPSIS - bfd_boolean bfd_set_section_flags - (bfd *abfd, asection *sec, flagword flags); - -DESCRIPTION - Set the attributes of the section @var{sec} in the BFD - @var{abfd} to the value @var{flags}. Return <> on success, - <> on error. Possible error returns are: - - o <> - - The section cannot have one or more of the attributes - requested. For example, a .bss section in <> may not - have the <> field set. - -*/ - -bfd_boolean -bfd_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED, - sec_ptr section, - flagword flags) -{ - section->flags = flags; - return TRUE; -} - -/* -FUNCTION - bfd_rename_section - -SYNOPSIS - void bfd_rename_section - (bfd *abfd, asection *sec, const char *newname); - -DESCRIPTION - Rename section @var{sec} in @var{abfd} to @var{newname}. -*/ - -void -bfd_rename_section (bfd *abfd, sec_ptr sec, const char *newname) -{ - struct section_hash_entry *sh; - - sh = (struct section_hash_entry *) - ((char *) sec - offsetof (struct section_hash_entry, section)); - sh->section.name = newname; - bfd_hash_rename (&abfd->section_htab, newname, &sh->root); -} - -/* -FUNCTION - bfd_map_over_sections - -SYNOPSIS - void bfd_map_over_sections - (bfd *abfd, - void (*func) (bfd *abfd, asection *sect, void *obj), - void *obj); - -DESCRIPTION - Call the provided function @var{func} for each section - attached to the BFD @var{abfd}, passing @var{obj} as an - argument. The function will be called as if by - -| func (abfd, the_section, obj); - - This is the preferred method for iterating over sections; an - alternative would be to use a loop: - -| section *p; -| for (p = abfd->sections; p != NULL; p = p->next) -| func (abfd, p, ...) - -*/ - -void -bfd_map_over_sections (bfd *abfd, - void (*operation) (bfd *, asection *, void *), - void *user_storage) -{ - asection *sect; - unsigned int i = 0; - - for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) - (*operation) (abfd, sect, user_storage); - - if (i != abfd->section_count) /* Debugging */ - abort (); -} - -/* -FUNCTION - bfd_sections_find_if - -SYNOPSIS - asection *bfd_sections_find_if - (bfd *abfd, - bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), - void *obj); - -DESCRIPTION - Call the provided function @var{operation} for each section - attached to the BFD @var{abfd}, passing @var{obj} as an - argument. The function will be called as if by - -| operation (abfd, the_section, obj); - - It returns the first section for which @var{operation} returns true. - -*/ - -asection * -bfd_sections_find_if (bfd *abfd, - bfd_boolean (*operation) (bfd *, asection *, void *), - void *user_storage) -{ - asection *sect; - - for (sect = abfd->sections; sect != NULL; sect = sect->next) - if ((*operation) (abfd, sect, user_storage)) - break; - - return sect; -} - -/* -FUNCTION - bfd_set_section_size - -SYNOPSIS - bfd_boolean bfd_set_section_size - (bfd *abfd, asection *sec, bfd_size_type val); - -DESCRIPTION - Set @var{sec} to the size @var{val}. If the operation is - ok, then <> is returned, else <>. - - Possible error returns: - o <> - - Writing has started to the BFD, so setting the size is invalid. - -*/ - -bfd_boolean -bfd_set_section_size (bfd *abfd, sec_ptr ptr, bfd_size_type val) -{ - /* Once you've started writing to any section you cannot create or change - the size of any others. */ - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - ptr->size = val; - return TRUE; -} - -/* -FUNCTION - bfd_set_section_contents - -SYNOPSIS - bfd_boolean bfd_set_section_contents - (bfd *abfd, asection *section, const void *data, - file_ptr offset, bfd_size_type count); - -DESCRIPTION - Sets the contents of the section @var{section} in BFD - @var{abfd} to the data starting in memory at @var{data}. The - data is written to the output section starting at offset - @var{offset} for @var{count} octets. - - Normally <> is returned, else <>. Possible error - returns are: - o <> - - The output section does not have the <> - attribute, so nothing can be written to it. - o and some more too - - This routine is front end to the back end function - <<_bfd_set_section_contents>>. - -*/ - -bfd_boolean -bfd_set_section_contents (bfd *abfd, - sec_ptr section, - const void *location, - file_ptr offset, - bfd_size_type count) -{ - bfd_size_type sz; - - if (!(bfd_get_section_flags (abfd, section) & SEC_HAS_CONTENTS)) - { - bfd_set_error (bfd_error_no_contents); - return FALSE; - } - - sz = section->size; - if ((bfd_size_type) offset > sz - || count > sz - || offset + count > sz - || count != (size_t) count) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - if (!bfd_write_p (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* Record a copy of the data in memory if desired. */ - if (section->contents - && location != section->contents + offset) - memcpy (section->contents + offset, location, (size_t) count); - - if (BFD_SEND (abfd, _bfd_set_section_contents, - (abfd, section, location, offset, count))) - { - abfd->output_has_begun = TRUE; - return TRUE; - } - - return FALSE; -} - -/* -FUNCTION - bfd_get_section_contents - -SYNOPSIS - bfd_boolean bfd_get_section_contents - (bfd *abfd, asection *section, void *location, file_ptr offset, - bfd_size_type count); - -DESCRIPTION - Read data from @var{section} in BFD @var{abfd} - into memory starting at @var{location}. The data is read at an - offset of @var{offset} from the start of the input section, - and is read for @var{count} bytes. - - If the contents of a constructor with the <> - flag set are requested or if the section does not have the - <> flag set, then the @var{location} is filled - with zeroes. If no errors occur, <> is returned, else - <>. - -*/ -bfd_boolean -bfd_get_section_contents (bfd *abfd, - sec_ptr section, - void *location, - file_ptr offset, - bfd_size_type count) -{ - bfd_size_type sz; - - if (section->flags & SEC_CONSTRUCTOR) - { - memset (location, 0, (size_t) count); - return TRUE; - } - - if (abfd->direction != write_direction && section->rawsize != 0) - sz = section->rawsize; - else - sz = section->size; - if ((bfd_size_type) offset > sz - || count > sz - || offset + count > sz - || count != (size_t) count) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - if (count == 0) - /* Don't bother. */ - return TRUE; - - if ((section->flags & SEC_HAS_CONTENTS) == 0) - { - memset (location, 0, (size_t) count); - return TRUE; - } - - if ((section->flags & SEC_IN_MEMORY) != 0) - { - if (section->contents == NULL) - { - /* This can happen because of errors earlier on in the linking process. - We do not want to seg-fault here, so clear the flag and return an - error code. */ - section->flags &= ~ SEC_IN_MEMORY; - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - memcpy (location, section->contents + offset, (size_t) count); - return TRUE; - } - - return BFD_SEND (abfd, _bfd_get_section_contents, - (abfd, section, location, offset, count)); -} - -/* -FUNCTION - bfd_malloc_and_get_section - -SYNOPSIS - bfd_boolean bfd_malloc_and_get_section - (bfd *abfd, asection *section, bfd_byte **buf); - -DESCRIPTION - Read all data from @var{section} in BFD @var{abfd} - into a buffer, *@var{buf}, malloc'd by this function. -*/ - -bfd_boolean -bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf) -{ - *buf = NULL; - return bfd_get_full_section_contents (abfd, sec, buf); -} -/* -FUNCTION - bfd_copy_private_section_data - -SYNOPSIS - bfd_boolean bfd_copy_private_section_data - (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); - -DESCRIPTION - Copy private section information from @var{isec} in the BFD - @var{ibfd} to the section @var{osec} in the BFD @var{obfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{osec}. - -.#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ -. BFD_SEND (obfd, _bfd_copy_private_section_data, \ -. (ibfd, isection, obfd, osection)) -*/ - -/* -FUNCTION - bfd_generic_is_group_section - -SYNOPSIS - bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); - -DESCRIPTION - Returns TRUE if @var{sec} is a member of a group. -*/ - -bfd_boolean -bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, - const asection *sec ATTRIBUTE_UNUSED) -{ - return FALSE; -} - -/* -FUNCTION - bfd_generic_discard_group - -SYNOPSIS - bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); - -DESCRIPTION - Remove all members of @var{group} from the output. -*/ - -bfd_boolean -bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED, - asection *group ATTRIBUTE_UNUSED) -{ - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/simple.c b/contrib/binutils-2.22/bfd/simple.c deleted file mode 100644 index e5a5b58f92..0000000000 --- a/contrib/binutils-2.22/bfd/simple.c +++ /dev/null @@ -1,253 +0,0 @@ -/* simple.c -- BFD simple client routines - Copyright 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Contributed by MontaVista Software, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "bfdlink.h" - -static bfd_boolean -simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - const char *warning ATTRIBUTE_UNUSED, - const char *symbol ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - bfd_vma address ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static bfd_boolean -simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - bfd_vma address ATTRIBUTE_UNUSED, - bfd_boolean fatal ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static bfd_boolean -simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - const char *reloc_name ATTRIBUTE_UNUSED, - bfd_vma addend ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - bfd_vma address ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static bfd_boolean -simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - const char *message ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - bfd_vma address ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static bfd_boolean -simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - bfd *abfd ATTRIBUTE_UNUSED, - asection *section ATTRIBUTE_UNUSED, - bfd_vma address ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static bfd_boolean -simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED, - struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED, - bfd *nbfd ATTRIBUTE_UNUSED, - asection *nsec ATTRIBUTE_UNUSED, - bfd_vma nval ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -static void -simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...) -{ -} - -struct saved_output_info -{ - bfd_vma offset; - asection *section; -}; - -static void -simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED, - asection *section, - void *ptr) -{ - struct saved_output_info *output_info = (struct saved_output_info *) ptr; - output_info[section->index].offset = section->output_offset; - output_info[section->index].section = section->output_section; - if ((section->flags & SEC_DEBUGGING) != 0 - || section->output_section == NULL) - { - section->output_offset = 0; - section->output_section = section; - } -} - -static void -simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED, - asection *section, - void *ptr) -{ - struct saved_output_info *output_info = (struct saved_output_info *) ptr; - section->output_offset = output_info[section->index].offset; - section->output_section = output_info[section->index].section; -} - -/* -FUNCTION - bfd_simple_relocate_secton - -SYNOPSIS - bfd_byte *bfd_simple_get_relocated_section_contents - (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); - -DESCRIPTION - Returns the relocated contents of section @var{sec}. The symbols in - @var{symbol_table} will be used, or the symbols from @var{abfd} if - @var{symbol_table} is NULL. The output offsets for debug sections will - be temporarily reset to 0. The result will be stored at @var{outbuf} - or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}. - - Returns @code{NULL} on a fatal error; ignores errors applying - particular relocations. -*/ - -bfd_byte * -bfd_simple_get_relocated_section_contents (bfd *abfd, - asection *sec, - bfd_byte *outbuf, - asymbol **symbol_table) -{ - struct bfd_link_info link_info; - struct bfd_link_order link_order; - struct bfd_link_callbacks callbacks; - bfd_byte *contents, *data; - int storage_needed; - void *saved_offsets; - - /* Don't apply relocation on executable and shared library. See - PR 4756. */ - if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC - || ! (sec->flags & SEC_RELOC)) - { - contents = outbuf; - if (!bfd_get_full_section_contents (abfd, sec, &contents)) - return NULL; - return contents; - } - - /* In order to use bfd_get_relocated_section_contents, we need - to forge some data structures that it expects. */ - - /* Fill in the bare minimum number of fields for our purposes. */ - memset (&link_info, 0, sizeof (link_info)); - link_info.output_bfd = abfd; - link_info.input_bfds = abfd; - link_info.input_bfds_tail = &abfd->link_next; - - link_info.hash = _bfd_generic_link_hash_table_create (abfd); - link_info.callbacks = &callbacks; - callbacks.warning = simple_dummy_warning; - callbacks.undefined_symbol = simple_dummy_undefined_symbol; - callbacks.reloc_overflow = simple_dummy_reloc_overflow; - callbacks.reloc_dangerous = simple_dummy_reloc_dangerous; - callbacks.unattached_reloc = simple_dummy_unattached_reloc; - callbacks.multiple_definition = simple_dummy_multiple_definition; - callbacks.einfo = simple_dummy_einfo; - - memset (&link_order, 0, sizeof (link_order)); - link_order.next = NULL; - link_order.type = bfd_indirect_link_order; - link_order.offset = 0; - link_order.size = sec->size; - link_order.u.indirect.section = sec; - - data = NULL; - if (outbuf == NULL) - { - bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size; - data = (bfd_byte *) bfd_malloc (amt); - if (data == NULL) - return NULL; - outbuf = data; - } - - /* The sections in ABFD may already have output sections and offsets set. - Because this function is primarily for debug sections, and GCC uses the - knowledge that debug sections will generally have VMA 0 when emitting - relocations between DWARF-2 sections (which are supposed to be - section-relative offsets anyway), we need to reset the output offsets - to zero. We also need to arrange for section->output_section->vma plus - section->output_offset to equal section->vma, which we do by setting - section->output_section to point back to section. Save the original - output offset and output section to restore later. */ - saved_offsets = malloc (sizeof (struct saved_output_info) - * abfd->section_count); - if (saved_offsets == NULL) - { - if (data) - free (data); - return NULL; - } - bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets); - - if (symbol_table == NULL) - { - _bfd_generic_link_add_symbols (abfd, &link_info); - - storage_needed = bfd_get_symtab_upper_bound (abfd); - symbol_table = (asymbol **) bfd_malloc (storage_needed); - bfd_canonicalize_symtab (abfd, symbol_table); - } - else - storage_needed = 0; - - contents = bfd_get_relocated_section_contents (abfd, - &link_info, - &link_order, - outbuf, - 0, - symbol_table); - if (contents == NULL && data != NULL) - free (data); - - bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets); - free (saved_offsets); - - _bfd_generic_link_hash_table_free (link_info.hash); - return contents; -} diff --git a/contrib/binutils-2.22/bfd/srec.c b/contrib/binutils-2.22/bfd/srec.c deleted file mode 100644 index 6226773387..0000000000 --- a/contrib/binutils-2.22/bfd/srec.c +++ /dev/null @@ -1,1380 +0,0 @@ -/* BFD back-end for s-record objects. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 - Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* SUBSECTION - S-Record handling - - DESCRIPTION - - Ordinary S-Records cannot hold anything but addresses and - data, so that's all that we implement. - - The only interesting thing is that S-Records may come out of - order and there is no header, so an initial scan is required - to discover the minimum and maximum addresses used to create - the vma and size of the only section we create. We - arbitrarily call this section ".text". - - When bfd_get_section_contents is called the file is read - again, and this time the data is placed into a bfd_alloc'd - area. - - Any number of sections may be created for output, we save them - up and output them when it's time to close the bfd. - - An s record looks like: - - EXAMPLE - S
- - DESCRIPTION - Where - o length - is the number of bytes following upto the checksum. Note that - this is not the number of chars following, since it takes two - chars to represent a byte. - o type - is one of: - 0) header record - 1) two byte address data record - 2) three byte address data record - 3) four byte address data record - 7) four byte address termination record - 8) three byte address termination record - 9) two byte address termination record - - o address - is the start address of the data following, or in the case of - a termination record, the start address of the image - o data - is the data. - o checksum - is the sum of all the raw byte data in the record, from the length - upwards, modulo 256 and subtracted from 255. - - SUBSECTION - Symbol S-Record handling - - DESCRIPTION - Some ICE equipment understands an addition to the standard - S-Record format; symbols and their addresses can be sent - before the data. - - The format of this is: - ($$ - (
)*) - $$ - - so a short symbol table could look like: - - EXAMPLE - $$ flash.x - $$ flash.c - _port6 $0 - _delay $4 - _start $14 - _etext $8036 - _edata $8036 - _end $8036 - $$ - - DESCRIPTION - We allow symbols to be anywhere in the data stream - the module names - are always ignored. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "libiberty.h" -#include "safe-ctype.h" - - -/* Macros for converting between hex and binary. */ - -static const char digs[] = "0123456789ABCDEF"; - -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1])) -#define TOHEX(d, x, ch) \ - d[1] = digs[(x) & 0xf]; \ - d[0] = digs[((x)>>4)&0xf]; \ - ch += ((x) & 0xff); -#define ISHEX(x) hex_p(x) - -/* The maximum number of address+data+crc bytes on a line is FF. */ -#define MAXCHUNK 0xff - -/* Default size for a CHUNK. */ -#define DEFAULT_CHUNK 16 - -/* The number of data bytes we actually fit onto a line on output. - This variable can be modified by objcopy's --srec-len parameter. - For a 0x75 byte record you should set --srec-len=0x70. */ -unsigned int Chunk = DEFAULT_CHUNK; - -/* The type of srec output (free or forced to S3). - This variable can be modified by objcopy's --srec-forceS3 - parameter. */ -bfd_boolean S3Forced = FALSE; - -/* When writing an S-record file, the S-records can not be output as - they are seen. This structure is used to hold them in memory. */ - -struct srec_data_list_struct -{ - struct srec_data_list_struct *next; - bfd_byte *data; - bfd_vma where; - bfd_size_type size; -}; - -typedef struct srec_data_list_struct srec_data_list_type; - -/* When scanning the S-record file, a linked list of srec_symbol - structures is built to represent the symbol table (if there is - one). */ - -struct srec_symbol -{ - struct srec_symbol *next; - const char *name; - bfd_vma val; -}; - -/* The S-record tdata information. */ - -typedef struct srec_data_struct - { - srec_data_list_type *head; - srec_data_list_type *tail; - unsigned int type; - struct srec_symbol *symbols; - struct srec_symbol *symtail; - asymbol *csymbols; - } -tdata_type; - -/* Initialize by filling in the hex conversion array. */ - -static void -srec_init (void) -{ - static bfd_boolean inited = FALSE; - - if (! inited) - { - inited = TRUE; - hex_init (); - } -} - -/* Set up the S-record tdata information. */ - -static bfd_boolean -srec_mkobject (bfd *abfd) -{ - tdata_type *tdata; - - srec_init (); - - tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (tdata == NULL) - return FALSE; - - abfd->tdata.srec_data = tdata; - tdata->type = 1; - tdata->head = NULL; - tdata->tail = NULL; - tdata->symbols = NULL; - tdata->symtail = NULL; - tdata->csymbols = NULL; - - return TRUE; -} - -/* Read a byte from an S record file. Set *ERRORPTR if an error - occurred. Return EOF on error or end of file. */ - -static int -srec_get_byte (bfd *abfd, bfd_boolean *errorptr) -{ - bfd_byte c; - - if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1) - { - if (bfd_get_error () != bfd_error_file_truncated) - *errorptr = TRUE; - return EOF; - } - - return (int) (c & 0xff); -} - -/* Report a problem in an S record file. FIXME: This probably should - not call fprintf, but we really do need some mechanism for printing - error messages. */ - -static void -srec_bad_byte (bfd *abfd, - unsigned int lineno, - int c, - bfd_boolean error) -{ - if (c == EOF) - { - if (! error) - bfd_set_error (bfd_error_file_truncated); - } - else - { - char buf[10]; - - if (! ISPRINT (c)) - sprintf (buf, "\\%03o", (unsigned int) c); - else - { - buf[0] = c; - buf[1] = '\0'; - } - (*_bfd_error_handler) - (_("%B:%d: Unexpected character `%s' in S-record file\n"), - abfd, lineno, buf); - bfd_set_error (bfd_error_bad_value); - } -} - -/* Add a new symbol found in an S-record file. */ - -static bfd_boolean -srec_new_symbol (bfd *abfd, const char *name, bfd_vma val) -{ - struct srec_symbol *n; - - n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (* n)); - if (n == NULL) - return FALSE; - - n->name = name; - n->val = val; - - if (abfd->tdata.srec_data->symbols == NULL) - abfd->tdata.srec_data->symbols = n; - else - abfd->tdata.srec_data->symtail->next = n; - abfd->tdata.srec_data->symtail = n; - n->next = NULL; - - ++abfd->symcount; - - return TRUE; -} - -/* Read the S record file and turn it into sections. We create a new - section for each contiguous set of bytes. */ - -static bfd_boolean -srec_scan (bfd *abfd) -{ - int c; - unsigned int lineno = 1; - bfd_boolean error = FALSE; - bfd_byte *buf = NULL; - size_t bufsize = 0; - asection *sec = NULL; - char *symbuf = NULL; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - while ((c = srec_get_byte (abfd, &error)) != EOF) - { - /* We only build sections from contiguous S-records, so if this - is not an S-record, then stop building a section. */ - if (c != 'S' && c != '\r' && c != '\n') - sec = NULL; - - switch (c) - { - default: - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - - case '\n': - ++lineno; - break; - - case '\r': - break; - - case '$': - /* Starting a module name, which we ignore. */ - while ((c = srec_get_byte (abfd, &error)) != '\n' - && c != EOF) - ; - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - ++lineno; - break; - - case ' ': - do - { - bfd_size_type alc; - char *p, *symname; - bfd_vma symval; - - /* Starting a symbol definition. */ - while ((c = srec_get_byte (abfd, &error)) != EOF - && (c == ' ' || c == '\t')) - ; - - if (c == '\n' || c == '\r') - break; - - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - alc = 10; - symbuf = (char *) bfd_malloc (alc + 1); - if (symbuf == NULL) - goto error_return; - - p = symbuf; - - *p++ = c; - while ((c = srec_get_byte (abfd, &error)) != EOF - && ! ISSPACE (c)) - { - if ((bfd_size_type) (p - symbuf) >= alc) - { - char *n; - - alc *= 2; - n = (char *) bfd_realloc (symbuf, alc + 1); - if (n == NULL) - goto error_return; - p = n + (p - symbuf); - symbuf = n; - } - - *p++ = c; - } - - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - *p++ = '\0'; - symname = (char *) bfd_alloc (abfd, (bfd_size_type) (p - symbuf)); - if (symname == NULL) - goto error_return; - strcpy (symname, symbuf); - free (symbuf); - symbuf = NULL; - - while ((c = srec_get_byte (abfd, &error)) != EOF - && (c == ' ' || c == '\t')) - ; - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - /* Skip a dollar sign before the hex value. */ - if (c == '$') - { - c = srec_get_byte (abfd, &error); - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - } - - symval = 0; - while (ISHEX (c)) - { - symval <<= 4; - symval += NIBBLE (c); - c = srec_get_byte (abfd, &error); - if (c == EOF) - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - } - - if (! srec_new_symbol (abfd, symname, symval)) - goto error_return; - } - while (c == ' ' || c == '\t') - ; - - if (c == '\n') - ++lineno; - else if (c != '\r') - { - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - break; - - case 'S': - { - file_ptr pos; - char hdr[3]; - unsigned int bytes; - bfd_vma address; - bfd_byte *data; - unsigned char check_sum; - - /* Starting an S-record. */ - - pos = bfd_tell (abfd) - 1; - - if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3) - goto error_return; - - if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2])) - { - if (! ISHEX (hdr[1])) - c = hdr[1]; - else - c = hdr[2]; - srec_bad_byte (abfd, lineno, c, error); - goto error_return; - } - - check_sum = bytes = HEX (hdr + 1); - if (bytes * 2 > bufsize) - { - if (buf != NULL) - free (buf); - buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); - if (buf == NULL) - goto error_return; - bufsize = bytes * 2; - } - - if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2) - goto error_return; - - /* Ignore the checksum byte. */ - --bytes; - - address = 0; - data = buf; - switch (hdr[0]) - { - case '0': - case '5': - /* Prologue--ignore the file name, but stop building a - section at this point. */ - sec = NULL; - break; - - case '3': - check_sum += HEX (data); - address = HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '2': - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '1': - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - bytes -= 2; - - if (sec != NULL - && sec->vma + sec->size == address) - { - /* This data goes at the end of the section we are - currently building. */ - sec->size += bytes; - } - else - { - char secbuf[20]; - char *secname; - bfd_size_type amt; - flagword flags; - - sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1); - amt = strlen (secbuf) + 1; - secname = (char *) bfd_alloc (abfd, amt); - strcpy (secname, secbuf); - flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - sec = bfd_make_section_with_flags (abfd, secname, flags); - if (sec == NULL) - goto error_return; - sec->vma = address; - sec->lma = address; - sec->size = bytes; - sec->filepos = pos; - } - - while (bytes > 0) - { - check_sum += HEX (data); - data += 2; - bytes--; - } - check_sum = 255 - (check_sum & 0xff); - if (check_sum != HEX (data)) - { - (*_bfd_error_handler) - (_("%B:%d: Bad checksum in S-record file\n"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - break; - - case '7': - check_sum += HEX (data); - address = HEX (data); - data += 2; - /* Fall through. */ - case '8': - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - /* Fall through. */ - case '9': - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - check_sum += HEX (data); - address = (address << 8) | HEX (data); - data += 2; - - /* This is a termination record. */ - abfd->start_address = address; - - check_sum = 255 - (check_sum & 0xff); - if (check_sum != HEX (data)) - { - (*_bfd_error_handler) - (_("%B:%d: Bad checksum in S-record file\n"), - abfd, lineno); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (buf != NULL) - free (buf); - - return TRUE; - } - } - break; - } - } - - if (error) - goto error_return; - - if (buf != NULL) - free (buf); - - return TRUE; - - error_return: - if (symbuf != NULL) - free (symbuf); - if (buf != NULL) - free (buf); - return FALSE; -} - -/* Check whether an existing file is an S-record file. */ - -static const bfd_target * -srec_object_p (bfd *abfd) -{ - void * tdata_save; - bfd_byte b[4]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_bread (b, (bfd_size_type) 4, abfd) != 4) - return NULL; - - if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - tdata_save = abfd->tdata.any; - if (! srec_mkobject (abfd) || ! srec_scan (abfd)) - { - if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) - bfd_release (abfd, abfd->tdata.any); - abfd->tdata.any = tdata_save; - return NULL; - } - - if (abfd->symcount > 0) - abfd->flags |= HAS_SYMS; - - return abfd->xvec; -} - -/* Check whether an existing file is an S-record file with symbols. */ - -static const bfd_target * -symbolsrec_object_p (bfd *abfd) -{ - void * tdata_save; - char b[2]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_bread (b, (bfd_size_type) 2, abfd) != 2) - return NULL; - - if (b[0] != '$' || b[1] != '$') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - tdata_save = abfd->tdata.any; - if (! srec_mkobject (abfd) || ! srec_scan (abfd)) - { - if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL) - bfd_release (abfd, abfd->tdata.any); - abfd->tdata.any = tdata_save; - return NULL; - } - - if (abfd->symcount > 0) - abfd->flags |= HAS_SYMS; - - return abfd->xvec; -} - -/* Read in the contents of a section in an S-record file. */ - -static bfd_boolean -srec_read_section (bfd *abfd, asection *section, bfd_byte *contents) -{ - int c; - bfd_size_type sofar = 0; - bfd_boolean error = FALSE; - bfd_byte *buf = NULL; - size_t bufsize = 0; - - if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0) - goto error_return; - - while ((c = srec_get_byte (abfd, &error)) != EOF) - { - bfd_byte hdr[3]; - unsigned int bytes; - bfd_vma address; - bfd_byte *data; - - if (c == '\r' || c == '\n') - continue; - - /* This is called after srec_scan has already been called, so we - ought to know the exact format. */ - BFD_ASSERT (c == 'S'); - - if (bfd_bread (hdr, (bfd_size_type) 3, abfd) != 3) - goto error_return; - - BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2])); - - bytes = HEX (hdr + 1); - - if (bytes * 2 > bufsize) - { - if (buf != NULL) - free (buf); - buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2); - if (buf == NULL) - goto error_return; - bufsize = bytes * 2; - } - - if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2) - goto error_return; - - address = 0; - data = buf; - switch (hdr[0]) - { - default: - BFD_ASSERT (sofar == section->size); - if (buf != NULL) - free (buf); - return TRUE; - - case '3': - address = HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '2': - address = (address << 8) | HEX (data); - data += 2; - --bytes; - /* Fall through. */ - case '1': - address = (address << 8) | HEX (data); - data += 2; - address = (address << 8) | HEX (data); - data += 2; - bytes -= 2; - - if (address != section->vma + sofar) - { - /* We've come to the end of this section. */ - BFD_ASSERT (sofar == section->size); - if (buf != NULL) - free (buf); - return TRUE; - } - - /* Don't consider checksum. */ - --bytes; - - while (bytes-- != 0) - { - contents[sofar] = HEX (data); - data += 2; - ++sofar; - } - - break; - } - } - - if (error) - goto error_return; - - BFD_ASSERT (sofar == section->size); - - if (buf != NULL) - free (buf); - - return TRUE; - - error_return: - if (buf != NULL) - free (buf); - return FALSE; -} - -/* Get the contents of a section in an S-record file. */ - -static bfd_boolean -srec_get_section_contents (bfd *abfd, - asection *section, - void * location, - file_ptr offset, - bfd_size_type count) -{ - if (count == 0) - return TRUE; - - if (offset + count < count - || offset + count > section->size) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - if (section->used_by_bfd == NULL) - { - section->used_by_bfd = bfd_alloc (abfd, section->size); - if (section->used_by_bfd == NULL) - return FALSE; - - if (! srec_read_section (abfd, section, - (bfd_byte *) section->used_by_bfd)) - return FALSE; - } - - memcpy (location, (bfd_byte *) section->used_by_bfd + offset, - (size_t) count); - - return TRUE; -} - -/* Set the architecture. We accept an unknown architecture here. */ - -static bfd_boolean -srec_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach) -{ - if (arch != bfd_arch_unknown) - return bfd_default_set_arch_mach (abfd, arch, mach); - - abfd->arch_info = & bfd_default_arch_struct; - return TRUE; -} - -/* We have to save up all the Srecords for a splurge before output. */ - -static bfd_boolean -srec_set_section_contents (bfd *abfd, - sec_ptr section, - const void * location, - file_ptr offset, - bfd_size_type bytes_to_do) -{ - tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *entry; - - entry = (srec_data_list_type *) bfd_alloc (abfd, sizeof (* entry)); - if (entry == NULL) - return FALSE; - - if (bytes_to_do - && (section->flags & SEC_ALLOC) - && (section->flags & SEC_LOAD)) - { - bfd_byte *data; - - data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); - if (data == NULL) - return FALSE; - memcpy ((void *) data, location, (size_t) bytes_to_do); - - /* Ff S3Forced is TRUE then always select S3 records, - regardless of the siez of the addresses. */ - if (S3Forced) - tdata->type = 3; - else if ((section->lma + offset + bytes_to_do - 1) <= 0xffff) - ; /* The default, S1, is OK. */ - else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff - && tdata->type <= 2) - tdata->type = 2; - else - tdata->type = 3; - - entry->data = data; - entry->where = section->lma + offset; - entry->size = bytes_to_do; - - /* Sort the records by address. Optimize for the common case of - adding a record to the end of the list. */ - if (tdata->tail != NULL - && entry->where >= tdata->tail->where) - { - tdata->tail->next = entry; - entry->next = NULL; - tdata->tail = entry; - } - else - { - srec_data_list_type **look; - - for (look = &tdata->head; - *look != NULL && (*look)->where < entry->where; - look = &(*look)->next) - ; - entry->next = *look; - *look = entry; - if (entry->next == NULL) - tdata->tail = entry; - } - } - return TRUE; -} - -/* Write a record of type, of the supplied number of bytes. The - supplied bytes and length don't have a checksum. That's worked out - here. */ - -static bfd_boolean -srec_write_record (bfd *abfd, - unsigned int type, - bfd_vma address, - const bfd_byte *data, - const bfd_byte *end) -{ - char buffer[2 * MAXCHUNK + 6]; - unsigned int check_sum = 0; - const bfd_byte *src = data; - char *dst = buffer; - char *length; - bfd_size_type wrlen; - - *dst++ = 'S'; - *dst++ = '0' + type; - - length = dst; - dst += 2; /* Leave room for dst. */ - - switch (type) - { - case 3: - case 7: - TOHEX (dst, (address >> 24), check_sum); - dst += 2; - case 8: - case 2: - TOHEX (dst, (address >> 16), check_sum); - dst += 2; - case 9: - case 1: - case 0: - TOHEX (dst, (address >> 8), check_sum); - dst += 2; - TOHEX (dst, (address), check_sum); - dst += 2; - break; - - } - for (src = data; src < end; src++) - { - TOHEX (dst, *src, check_sum); - dst += 2; - } - - /* Fill in the length. */ - TOHEX (length, (dst - length) / 2, check_sum); - check_sum &= 0xff; - check_sum = 255 - check_sum; - TOHEX (dst, check_sum, check_sum); - dst += 2; - - *dst++ = '\r'; - *dst++ = '\n'; - wrlen = dst - buffer; - - return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen; -} - -static bfd_boolean -srec_write_header (bfd *abfd) -{ - unsigned int len = strlen (abfd->filename); - - /* I'll put an arbitrary 40 char limit on header size. */ - if (len > 40) - len = 40; - - return srec_write_record (abfd, 0, (bfd_vma) 0, - (bfd_byte *) abfd->filename, - (bfd_byte *) abfd->filename + len); -} - -static bfd_boolean -srec_write_section (bfd *abfd, - tdata_type *tdata, - srec_data_list_type *list) -{ - unsigned int octets_written = 0; - bfd_byte *location = list->data; - - /* Validate number of data bytes to write. The srec length byte - counts the address, data and crc bytes. S1 (tdata->type == 1) - records have two address bytes, S2 (tdata->type == 2) records - have three, and S3 (tdata->type == 3) records have four. - The total length can't exceed 255, and a zero data length will - spin for a long time. */ - if (Chunk == 0) - Chunk = 1; - else if (Chunk > MAXCHUNK - tdata->type - 2) - Chunk = MAXCHUNK - tdata->type - 2; - - while (octets_written < list->size) - { - bfd_vma address; - unsigned int octets_this_chunk = list->size - octets_written; - - if (octets_this_chunk > Chunk) - octets_this_chunk = Chunk; - - address = list->where + octets_written / bfd_octets_per_byte (abfd); - - if (! srec_write_record (abfd, - tdata->type, - address, - location, - location + octets_this_chunk)) - return FALSE; - - octets_written += octets_this_chunk; - location += octets_this_chunk; - } - - return TRUE; -} - -static bfd_boolean -srec_write_terminator (bfd *abfd, tdata_type *tdata) -{ - return srec_write_record (abfd, 10 - tdata->type, - abfd->start_address, NULL, NULL); -} - -static bfd_boolean -srec_write_symbols (bfd *abfd) -{ - /* Dump out the symbols of a bfd. */ - int i; - int count = bfd_get_symcount (abfd); - - if (count) - { - bfd_size_type len; - asymbol **table = bfd_get_outsymbols (abfd); - - len = strlen (abfd->filename); - if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3 - || bfd_bwrite (abfd->filename, len, abfd) != len - || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2) - return FALSE; - - for (i = 0; i < count; i++) - { - asymbol *s = table[i]; - if (! bfd_is_local_label (abfd, s) - && (s->flags & BSF_DEBUGGING) == 0) - { - /* Just dump out non debug symbols. */ - char buf[43], *p; - - len = strlen (s->name); - if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2 - || bfd_bwrite (s->name, len, abfd) != len) - return FALSE; - - sprintf_vma (buf + 2, (s->value - + s->section->output_section->lma - + s->section->output_offset)); - p = buf + 2; - while (p[0] == '0' && p[1] != 0) - p++; - len = strlen (p); - p[len] = '\r'; - p[len + 1] = '\n'; - *--p = '$'; - *--p = ' '; - len += 4; - if (bfd_bwrite (p, len, abfd) != len) - return FALSE; - } - } - if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5) - return FALSE; - } - - return TRUE; -} - -static bfd_boolean -internal_srec_write_object_contents (bfd *abfd, int symbols) -{ - tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *list; - - if (symbols) - { - if (! srec_write_symbols (abfd)) - return FALSE; - } - - if (! srec_write_header (abfd)) - return FALSE; - - /* Now wander though all the sections provided and output them. */ - list = tdata->head; - - while (list != (srec_data_list_type *) NULL) - { - if (! srec_write_section (abfd, tdata, list)) - return FALSE; - list = list->next; - } - return srec_write_terminator (abfd, tdata); -} - -static bfd_boolean -srec_write_object_contents (bfd *abfd) -{ - return internal_srec_write_object_contents (abfd, 0); -} - -static bfd_boolean -symbolsrec_write_object_contents (bfd *abfd) -{ - return internal_srec_write_object_contents (abfd, 1); -} - -static int -srec_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - return 0; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -srec_get_symtab_upper_bound (bfd *abfd) -{ - return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); -} - -/* Return the symbol table. */ - -static long -srec_canonicalize_symtab (bfd *abfd, asymbol **alocation) -{ - bfd_size_type symcount = bfd_get_symcount (abfd); - asymbol *csymbols; - unsigned int i; - - csymbols = abfd->tdata.srec_data->csymbols; - if (csymbols == NULL && symcount != 0) - { - asymbol *c; - struct srec_symbol *s; - - csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol)); - if (csymbols == NULL) - return -1; - abfd->tdata.srec_data->csymbols = csymbols; - - for (s = abfd->tdata.srec_data->symbols, c = csymbols; - s != NULL; - s = s->next, ++c) - { - c->the_bfd = abfd; - c->name = s->name; - c->value = s->val; - c->flags = BSF_GLOBAL; - c->section = bfd_abs_section_ptr; - c->udata.p = NULL; - } - } - - for (i = 0; i < symcount; i++) - *alocation++ = csymbols++; - *alocation = NULL; - - return symcount; -} - -static void -srec_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED, - asymbol *symbol, - symbol_info *ret) -{ - bfd_symbol_info (symbol, ret); -} - -static void -srec_print_symbol (bfd *abfd, - void * afile, - asymbol *symbol, - bfd_print_symbol_type how) -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - default: - bfd_print_symbol_vandf (abfd, (void *) file, symbol); - fprintf (file, " %-5s %s", - symbol->section->name, - symbol->name); - } -} - -#define srec_close_and_cleanup _bfd_generic_close_and_cleanup -#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define srec_new_section_hook _bfd_generic_new_section_hook -#define srec_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name -#define srec_get_lineno _bfd_nosymbols_get_lineno -#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line -#define srec_find_inliner_info _bfd_nosymbols_find_inliner_info -#define srec_make_empty_symbol _bfd_generic_make_empty_symbol -#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define srec_read_minisymbols _bfd_generic_read_minisymbols -#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define srec_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define srec_bfd_relax_section bfd_generic_relax_section -#define srec_bfd_gc_sections bfd_generic_gc_sections -#define srec_bfd_lookup_section_flags bfd_generic_lookup_section_flags -#define srec_bfd_merge_sections bfd_generic_merge_sections -#define srec_bfd_is_group_section bfd_generic_is_group_section -#define srec_bfd_discard_group bfd_generic_discard_group -#define srec_section_already_linked _bfd_generic_section_already_linked -#define srec_bfd_define_common_symbol bfd_generic_define_common_symbol -#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define srec_bfd_link_just_syms _bfd_generic_link_just_syms -#define srec_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -#define srec_bfd_final_link _bfd_generic_final_link -#define srec_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target srec_vec = -{ - "srec", /* Name. */ - bfd_target_srec_flavour, - BFD_ENDIAN_UNKNOWN, /* Target byte order. */ - BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ - (HAS_RELOC | EXEC_P | /* Object flags. */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ - 0, /* Leading underscore. */ - ' ', /* AR_pad_char. */ - 16, /* AR_max_namelen. */ - 0, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */ - - { - _bfd_dummy_target, - srec_object_p, /* bfd_check_format. */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents. */ - bfd_false, - srec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; - -const bfd_target symbolsrec_vec = -{ - "symbolsrec", /* Name. */ - bfd_target_srec_flavour, - BFD_ENDIAN_UNKNOWN, /* Target byte order. */ - BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ - (HAS_RELOC | EXEC_P | /* Object flags. */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ - 0, /* Leading underscore. */ - ' ', /* AR_pad_char. */ - 16, /* AR_max_namelen. */ - 0, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ - - { - _bfd_dummy_target, - symbolsrec_object_p, /* bfd_check_format. */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents. */ - bfd_false, - symbolsrec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; diff --git a/contrib/binutils-2.22/bfd/stab-syms.c b/contrib/binutils-2.22/bfd/stab-syms.c deleted file mode 100644 index 9e9274f987..0000000000 --- a/contrib/binutils-2.22/bfd/stab-syms.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Table of stab names for the BFD library. - Copyright 1990, 1991, 1992, 1994, 1995, 1996, 2000, 2005, 2007 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "bfd.h" - -#define ARCH_SIZE 32 /* Value doesn't matter. */ -#include "libaout.h" -#include "aout/aout64.h" - -/* Ignore duplicate stab codes; just return the string for the first - one. */ -#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING) -#define __define_stab_duplicate(NAME, CODE, STRING) - -/* These are not really stab symbols, but it is - convenient to have them here for the sake of nm. - For completeness, we could also add N_TEXT etc, but those - are never needed, since nm treats those specially. */ -#define EXTRA_SYMBOLS \ - __define_name (N_SETA, "SETA")/* Absolute set element symbol */ \ - __define_name (N_SETT, "SETT")/* Text set element symbol */ \ - __define_name (N_SETD, "SETD")/* Data set element symbol */ \ - __define_name (N_SETB, "SETB")/* Bss set element symbol */ \ - __define_name (N_SETV, "SETV")/* Pointer to set vector in data area. */ \ - __define_name (N_INDR, "INDR") \ - __define_name (N_WARNING, "WARNING") - -const char * -bfd_get_stab_name (code) - int code; -{ - switch (code) - { -#define __define_name(val, str) case val: return str; -#include "aout/stab.def" - EXTRA_SYMBOLS - } - - return (const char *) 0; -} diff --git a/contrib/binutils-2.22/bfd/stabs.c b/contrib/binutils-2.22/bfd/stabs.c deleted file mode 100644 index 8a1cd87e06..0000000000 --- a/contrib/binutils-2.22/bfd/stabs.c +++ /dev/null @@ -1,789 +0,0 @@ -/* Stabs in sections linking support. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* This file contains support for linking stabs in sections, as used - on COFF and ELF. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "aout/stab_gnu.h" -#include "safe-ctype.h" - -/* Stabs entries use a 12 byte format: - 4 byte string table index - 1 byte stab type - 1 byte stab other field - 2 byte stab desc field - 4 byte stab value - FIXME: This will have to change for a 64 bit object format. - - The stabs symbols are divided into compilation units. For the - first entry in each unit, the type of 0, the value is the length of - the string table for this unit, and the desc field is the number of - stabs symbols for this unit. */ - -#define STRDXOFF 0 -#define TYPEOFF 4 -#define OTHEROFF 5 -#define DESCOFF 6 -#define VALOFF 8 -#define STABSIZE 12 - -/* A linked list of totals that we have found for a particular header - file. A total is a unique identifier for a particular BINCL...EINCL - sequence of STABs that can be used to identify duplicate sequences. - It consists of three fields, 'sum_chars' which is the sum of all the - STABS characters; 'num_chars' which is the number of these charactes - and 'symb' which is a buffer of all the symbols in the sequence. This - buffer is only checked as a last resort. */ - -struct stab_link_includes_totals -{ - struct stab_link_includes_totals *next; - bfd_vma sum_chars; /* Accumulated sum of STABS characters. */ - bfd_vma num_chars; /* Number of STABS characters. */ - const char* symb; /* The STABS characters themselves. */ -}; - -/* An entry in the header file hash table. */ - -struct stab_link_includes_entry -{ - struct bfd_hash_entry root; - /* List of totals we have found for this file. */ - struct stab_link_includes_totals *totals; -}; - -/* This structure is used to hold a list of N_BINCL symbols, some of - which might be converted into N_EXCL symbols. */ - -struct stab_excl_list -{ - /* The next symbol to convert. */ - struct stab_excl_list *next; - /* The offset to this symbol in the section contents. */ - bfd_size_type offset; - /* The value to use for the symbol. */ - bfd_vma val; - /* The type of this symbol (N_BINCL or N_EXCL). */ - int type; -}; - -/* This structure is stored with each .stab section. */ - -struct stab_section_info -{ - /* This is a linked list of N_BINCL symbols which should be - converted into N_EXCL symbols. */ - struct stab_excl_list *excls; - - /* This is used to map input stab offsets within their sections - to output stab offsets, to take into account stabs that have - been deleted. If it is NULL, the output offsets are the same - as the input offsets, because no stabs have been deleted from - this section. Otherwise the i'th entry is the number of - bytes of stabs that have been deleted prior to the i'th - stab. */ - bfd_size_type *cumulative_skips; - - /* This is an array of string indices. For each stab symbol, we - store the string index here. If a stab symbol should not be - included in the final output, the string index is -1. */ - bfd_size_type stridxs[1]; -}; - - -/* The function to create a new entry in the header file hash table. */ - -static struct bfd_hash_entry * -stab_link_includes_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - struct stab_link_includes_entry *ret = - (struct stab_link_includes_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = (struct stab_link_includes_entry *) - bfd_hash_allocate (table, sizeof (struct stab_link_includes_entry)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct stab_link_includes_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret) - /* Set local fields. */ - ret->totals = NULL; - - return (struct bfd_hash_entry *) ret; -} - -/* This function is called for each input file from the add_symbols - pass of the linker. */ - -bfd_boolean -_bfd_link_section_stabs (bfd *abfd, - struct stab_info *sinfo, - asection *stabsec, - asection *stabstrsec, - void * *psecinfo, - bfd_size_type *pstring_offset) -{ - bfd_boolean first; - bfd_size_type count, amt; - struct stab_section_info *secinfo; - bfd_byte *stabbuf = NULL; - bfd_byte *stabstrbuf = NULL; - bfd_byte *sym, *symend; - bfd_size_type stroff, next_stroff, skip; - bfd_size_type *pstridx; - - if (stabsec->size == 0 - || stabstrsec->size == 0) - /* This file does not contain stabs debugging information. */ - return TRUE; - - if (stabsec->size % STABSIZE != 0) - /* Something is wrong with the format of these stab symbols. - Don't try to optimize them. */ - return TRUE; - - if ((stabstrsec->flags & SEC_RELOC) != 0) - /* We shouldn't see relocations in the strings, and we aren't - prepared to handle them. */ - return TRUE; - - if (bfd_is_abs_section (stabsec->output_section) - || bfd_is_abs_section (stabstrsec->output_section)) - /* At least one of the sections is being discarded from the - link, so we should just ignore them. */ - return TRUE; - - first = FALSE; - - if (sinfo->stabstr == NULL) - { - flagword flags; - - /* Initialize the stabs information we need to keep track of. */ - first = TRUE; - sinfo->strings = _bfd_stringtab_init (); - if (sinfo->strings == NULL) - goto error_return; - /* Make sure the first byte is zero. */ - (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE); - if (! bfd_hash_table_init (&sinfo->includes, - stab_link_includes_newfunc, - sizeof (struct stab_link_includes_entry))) - goto error_return; - flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING - | SEC_LINKER_CREATED); - sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr", - flags); - if (sinfo->stabstr == NULL) - goto error_return; - } - - /* Initialize the information we are going to store for this .stab - section. */ - count = stabsec->size / STABSIZE; - - amt = sizeof (struct stab_section_info); - amt += (count - 1) * sizeof (bfd_size_type); - *psecinfo = bfd_alloc (abfd, amt); - if (*psecinfo == NULL) - goto error_return; - - secinfo = (struct stab_section_info *) *psecinfo; - secinfo->excls = NULL; - stabsec->rawsize = stabsec->size; - secinfo->cumulative_skips = NULL; - memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type)); - - /* Read the stabs information from abfd. */ - if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf) - || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf)) - goto error_return; - - /* Look through the stabs symbols, work out the new string indices, - and identify N_BINCL symbols which can be eliminated. */ - stroff = 0; - /* The stabs sections can be split when - -split-by-reloc/-split-by-file is used. We must keep track of - each stab section's place in the single concatenated string - table. */ - next_stroff = pstring_offset ? *pstring_offset : 0; - skip = 0; - - symend = stabbuf + stabsec->size; - for (sym = stabbuf, pstridx = secinfo->stridxs; - sym < symend; - sym += STABSIZE, ++pstridx) - { - bfd_size_type symstroff; - int type; - const char *string; - - if (*pstridx != 0) - /* This symbol has already been handled by an N_BINCL pass. */ - continue; - - type = sym[TYPEOFF]; - - if (type == 0) - { - /* Special type 0 stabs indicate the offset to the next - string table. We only copy the very first one. */ - stroff = next_stroff; - next_stroff += bfd_get_32 (abfd, sym + 8); - if (pstring_offset) - *pstring_offset = next_stroff; - if (! first) - { - *pstridx = (bfd_size_type) -1; - ++skip; - continue; - } - first = FALSE; - } - - /* Store the string in the hash table, and record the index. */ - symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF); - if (symstroff >= stabstrsec->size) - { - (*_bfd_error_handler) - (_("%B(%A+0x%lx): Stabs entry has invalid string index."), - abfd, stabsec, (long) (sym - stabbuf)); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - string = (char *) stabstrbuf + symstroff; - *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE); - - /* An N_BINCL symbol indicates the start of the stabs entries - for a header file. We need to scan ahead to the next N_EINCL - symbol, ignoring nesting, adding up all the characters in the - symbol names, not including the file numbers in types (the - first number after an open parenthesis). */ - if (type == (int) N_BINCL) - { - bfd_vma sum_chars; - bfd_vma num_chars; - bfd_vma buf_len = 0; - char * symb; - char * symb_rover; - int nest; - bfd_byte * incl_sym; - struct stab_link_includes_entry * incl_entry; - struct stab_link_includes_totals * t; - struct stab_excl_list * ne; - - symb = symb_rover = NULL; - sum_chars = num_chars = 0; - nest = 0; - - for (incl_sym = sym + STABSIZE; - incl_sym < symend; - incl_sym += STABSIZE) - { - int incl_type; - - incl_type = incl_sym[TYPEOFF]; - if (incl_type == 0) - break; - else if (incl_type == (int) N_EXCL) - continue; - else if (incl_type == (int) N_EINCL) - { - if (nest == 0) - break; - --nest; - } - else if (incl_type == (int) N_BINCL) - ++nest; - else if (nest == 0) - { - const char *str; - - str = ((char *) stabstrbuf - + stroff - + bfd_get_32 (abfd, incl_sym + STRDXOFF)); - for (; *str != '\0'; str++) - { - if (num_chars >= buf_len) - { - buf_len += 32 * 1024; - symb = (char *) bfd_realloc_or_free (symb, buf_len); - if (symb == NULL) - goto error_return; - symb_rover = symb + num_chars; - } - * symb_rover ++ = * str; - sum_chars += *str; - num_chars ++; - if (*str == '(') - { - /* Skip the file number. */ - ++str; - while (ISDIGIT (*str)) - ++str; - --str; - } - } - } - } - - BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb)); - - /* If we have already included a header file with the same - value, then replaced this one with an N_EXCL symbol. */ - incl_entry = (struct stab_link_includes_entry * ) - bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE); - if (incl_entry == NULL) - goto error_return; - - for (t = incl_entry->totals; t != NULL; t = t->next) - if (t->sum_chars == sum_chars - && t->num_chars == num_chars - && memcmp (t->symb, symb, num_chars) == 0) - break; - - /* Record this symbol, so that we can set the value - correctly. */ - amt = sizeof *ne; - ne = (struct stab_excl_list *) bfd_alloc (abfd, amt); - if (ne == NULL) - goto error_return; - ne->offset = sym - stabbuf; - ne->val = sum_chars; - ne->type = (int) N_BINCL; - ne->next = secinfo->excls; - secinfo->excls = ne; - - if (t == NULL) - { - /* This is the first time we have seen this header file - with this set of stabs strings. */ - t = (struct stab_link_includes_totals *) - bfd_hash_allocate (&sinfo->includes, sizeof *t); - if (t == NULL) - goto error_return; - t->sum_chars = sum_chars; - t->num_chars = num_chars; - /* Trim data down. */ - t->symb = symb = (char *) bfd_realloc_or_free (symb, num_chars); - t->next = incl_entry->totals; - incl_entry->totals = t; - } - else - { - bfd_size_type *incl_pstridx; - - /* We have seen this header file before. Tell the final - pass to change the type to N_EXCL. */ - ne->type = (int) N_EXCL; - - /* Free off superfluous symbols. */ - free (symb); - - /* Mark the skipped symbols. */ - - nest = 0; - for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1; - incl_sym < symend; - incl_sym += STABSIZE, ++incl_pstridx) - { - int incl_type; - - incl_type = incl_sym[TYPEOFF]; - - if (incl_type == (int) N_EINCL) - { - if (nest == 0) - { - *incl_pstridx = (bfd_size_type) -1; - ++skip; - break; - } - --nest; - } - else if (incl_type == (int) N_BINCL) - ++nest; - else if (incl_type == (int) N_EXCL) - /* Keep existing exclusion marks. */ - continue; - else if (nest == 0) - { - *incl_pstridx = (bfd_size_type) -1; - ++skip; - } - } - } - } - } - - free (stabbuf); - stabbuf = NULL; - free (stabstrbuf); - stabstrbuf = NULL; - - /* We need to set the section sizes such that the linker will - compute the output section sizes correctly. We set the .stab - size to not include the entries we don't want. We set - SEC_EXCLUDE for the .stabstr section, so that it will be dropped - from the link. We record the size of the strtab in the first - .stabstr section we saw, and make sure we don't set SEC_EXCLUDE - for that section. */ - stabsec->size = (count - skip) * STABSIZE; - if (stabsec->size == 0) - stabsec->flags |= SEC_EXCLUDE | SEC_KEEP; - stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP; - sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings); - - /* Calculate the `cumulative_skips' array now that stabs have been - deleted for this section. */ - - if (skip != 0) - { - bfd_size_type i, offset; - bfd_size_type *pskips; - - amt = count * sizeof (bfd_size_type); - secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); - if (secinfo->cumulative_skips == NULL) - goto error_return; - - pskips = secinfo->cumulative_skips; - pstridx = secinfo->stridxs; - offset = 0; - - for (i = 0; i < count; i++, pskips++, pstridx++) - { - *pskips = offset; - if (*pstridx == (bfd_size_type) -1) - offset += STABSIZE; - } - - BFD_ASSERT (offset != 0); - } - - return TRUE; - - error_return: - if (stabbuf != NULL) - free (stabbuf); - if (stabstrbuf != NULL) - free (stabstrbuf); - return FALSE; -} - -/* This function is called for each input file before the stab - section is relocated. It discards stab entries for discarded - functions and variables. The function returns TRUE iff - any entries have been deleted. -*/ - -bfd_boolean -_bfd_discard_section_stabs (bfd *abfd, - asection *stabsec, - void * psecinfo, - bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *), - void * cookie) -{ - bfd_size_type count, amt; - struct stab_section_info *secinfo; - bfd_byte *stabbuf = NULL; - bfd_byte *sym, *symend; - bfd_size_type skip; - bfd_size_type *pstridx; - int deleting; - - if (stabsec->size == 0) - /* This file does not contain stabs debugging information. */ - return FALSE; - - if (stabsec->size % STABSIZE != 0) - /* Something is wrong with the format of these stab symbols. - Don't try to optimize them. */ - return FALSE; - - if ((stabsec->output_section != NULL - && bfd_is_abs_section (stabsec->output_section))) - /* At least one of the sections is being discarded from the - link, so we should just ignore them. */ - return FALSE; - - /* We should have initialized our data in _bfd_link_stab_sections. - If there was some bizarre error reading the string sections, though, - we might not have. Bail rather than asserting. */ - if (psecinfo == NULL) - return FALSE; - - count = stabsec->rawsize / STABSIZE; - secinfo = (struct stab_section_info *) psecinfo; - - /* Read the stabs information from abfd. */ - if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)) - goto error_return; - - /* Look through the stabs symbols and discard any information for - discarded functions. */ - skip = 0; - deleting = -1; - - symend = stabbuf + stabsec->rawsize; - for (sym = stabbuf, pstridx = secinfo->stridxs; - sym < symend; - sym += STABSIZE, ++pstridx) - { - int type; - - if (*pstridx == (bfd_size_type) -1) - /* This stab was deleted in a previous pass. */ - continue; - - type = sym[TYPEOFF]; - - if (type == (int) N_FUN) - { - int strx = bfd_get_32 (abfd, sym + STRDXOFF); - - if (strx == 0) - { - if (deleting) - { - skip++; - *pstridx = -1; - } - deleting = -1; - continue; - } - deleting = 0; - if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) - deleting = 1; - } - - if (deleting == 1) - { - *pstridx = -1; - skip++; - } - else if (deleting == -1) - { - /* Outside of a function. Check for deleted variables. */ - if (type == (int) N_STSYM || type == (int) N_LCSYM) - if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) - { - *pstridx = -1; - skip ++; - } - /* We should also check for N_GSYM entries which reference a - deleted global, but those are less harmful to debuggers - and would require parsing the stab strings. */ - } - } - - free (stabbuf); - stabbuf = NULL; - - /* Shrink the stabsec as needed. */ - stabsec->size -= skip * STABSIZE; - if (stabsec->size == 0) - stabsec->flags |= SEC_EXCLUDE | SEC_KEEP; - - /* Recalculate the `cumulative_skips' array now that stabs have been - deleted for this section. */ - - if (skip != 0) - { - bfd_size_type i, offset; - bfd_size_type *pskips; - - if (secinfo->cumulative_skips == NULL) - { - amt = count * sizeof (bfd_size_type); - secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); - if (secinfo->cumulative_skips == NULL) - goto error_return; - } - - pskips = secinfo->cumulative_skips; - pstridx = secinfo->stridxs; - offset = 0; - - for (i = 0; i < count; i++, pskips++, pstridx++) - { - *pskips = offset; - if (*pstridx == (bfd_size_type) -1) - offset += STABSIZE; - } - - BFD_ASSERT (offset != 0); - } - - return skip > 0; - - error_return: - if (stabbuf != NULL) - free (stabbuf); - return FALSE; -} - -/* Write out the stab section. This is called with the relocated - contents. */ - -bfd_boolean -_bfd_write_section_stabs (bfd *output_bfd, - struct stab_info *sinfo, - asection *stabsec, - void * *psecinfo, - bfd_byte *contents) -{ - struct stab_section_info *secinfo; - struct stab_excl_list *e; - bfd_byte *sym, *tosym, *symend; - bfd_size_type *pstridx; - - secinfo = (struct stab_section_info *) *psecinfo; - - if (secinfo == NULL) - return bfd_set_section_contents (output_bfd, stabsec->output_section, - contents, stabsec->output_offset, - stabsec->size); - - /* Handle each N_BINCL entry. */ - for (e = secinfo->excls; e != NULL; e = e->next) - { - bfd_byte *excl_sym; - - BFD_ASSERT (e->offset < stabsec->rawsize); - excl_sym = contents + e->offset; - bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF); - excl_sym[TYPEOFF] = e->type; - } - - /* Copy over all the stabs symbols, omitting the ones we don't want, - and correcting the string indices for those we do want. */ - tosym = contents; - symend = contents + stabsec->rawsize; - for (sym = contents, pstridx = secinfo->stridxs; - sym < symend; - sym += STABSIZE, ++pstridx) - { - if (*pstridx != (bfd_size_type) -1) - { - if (tosym != sym) - memcpy (tosym, sym, STABSIZE); - bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF); - - if (sym[TYPEOFF] == 0) - { - /* This is the header symbol for the stabs section. We - don't really need one, since we have merged all the - input stabs sections into one, but we generate one - for the benefit of readers which expect to see one. */ - BFD_ASSERT (sym == contents); - bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings), - tosym + VALOFF); - bfd_put_16 (output_bfd, - stabsec->output_section->size / STABSIZE - 1, - tosym + DESCOFF); - } - - tosym += STABSIZE; - } - } - - BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size); - - return bfd_set_section_contents (output_bfd, stabsec->output_section, - contents, (file_ptr) stabsec->output_offset, - stabsec->size); -} - -/* Write out the .stabstr section. */ - -bfd_boolean -_bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo) -{ - if (bfd_is_abs_section (sinfo->stabstr->output_section)) - /* The section was discarded from the link. */ - return TRUE; - - BFD_ASSERT ((sinfo->stabstr->output_offset - + _bfd_stringtab_size (sinfo->strings)) - <= sinfo->stabstr->output_section->size); - - if (bfd_seek (output_bfd, - (file_ptr) (sinfo->stabstr->output_section->filepos - + sinfo->stabstr->output_offset), - SEEK_SET) != 0) - return FALSE; - - if (! _bfd_stringtab_emit (output_bfd, sinfo->strings)) - return FALSE; - - /* We no longer need the stabs information. */ - _bfd_stringtab_free (sinfo->strings); - bfd_hash_table_free (&sinfo->includes); - - return TRUE; -} - -/* Adjust an address in the .stab section. Given OFFSET within - STABSEC, this returns the new offset in the adjusted stab section, - or -1 if the address refers to a stab which has been removed. */ - -bfd_vma -_bfd_stab_section_offset (asection *stabsec, - void * psecinfo, - bfd_vma offset) -{ - struct stab_section_info *secinfo; - - secinfo = (struct stab_section_info *) psecinfo; - - if (secinfo == NULL) - return offset; - - if (offset >= stabsec->rawsize) - return offset - stabsec->rawsize + stabsec->size; - - if (secinfo->cumulative_skips) - { - bfd_vma i; - - i = offset / STABSIZE; - - if (secinfo->stridxs [i] == (bfd_size_type) -1) - return (bfd_vma) -1; - - return offset - secinfo->cumulative_skips [i]; - } - - return offset; -} diff --git a/contrib/binutils-2.22/bfd/syms.c b/contrib/binutils-2.22/bfd/syms.c deleted file mode 100644 index e819eae16d..0000000000 --- a/contrib/binutils-2.22/bfd/syms.c +++ /dev/null @@ -1,1423 +0,0 @@ -/* Generic symbol-table support for the BFD library. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* -SECTION - Symbols - - BFD tries to maintain as much symbol information as it can when - it moves information from file to file. BFD passes information - to applications though the <> structure. When the - application requests the symbol table, BFD reads the table in - the native form and translates parts of it into the internal - format. To maintain more than the information passed to - applications, some targets keep some information ``behind the - scenes'' in a structure only the particular back end knows - about. For example, the coff back end keeps the original - symbol table structure as well as the canonical structure when - a BFD is read in. On output, the coff back end can reconstruct - the output symbol table so that no information is lost, even - information unique to coff which BFD doesn't know or - understand. If a coff symbol table were read, but were written - through an a.out back end, all the coff specific information - would be lost. The symbol table of a BFD - is not necessarily read in until a canonicalize request is - made. Then the BFD back end fills in a table provided by the - application with pointers to the canonical information. To - output symbols, the application provides BFD with a table of - pointers to pointers to <>s. This allows applications - like the linker to output a symbol as it was read, since the ``behind - the scenes'' information will be still available. -@menu -@* Reading Symbols:: -@* Writing Symbols:: -@* Mini Symbols:: -@* typedef asymbol:: -@* symbol handling functions:: -@end menu - -INODE -Reading Symbols, Writing Symbols, Symbols, Symbols -SUBSECTION - Reading symbols - - There are two stages to reading a symbol table from a BFD: - allocating storage, and the actual reading process. This is an - excerpt from an application which reads the symbol table: - -| long storage_needed; -| asymbol **symbol_table; -| long number_of_symbols; -| long i; -| -| storage_needed = bfd_get_symtab_upper_bound (abfd); -| -| if (storage_needed < 0) -| FAIL -| -| if (storage_needed == 0) -| return; -| -| symbol_table = xmalloc (storage_needed); -| ... -| number_of_symbols = -| bfd_canonicalize_symtab (abfd, symbol_table); -| -| if (number_of_symbols < 0) -| FAIL -| -| for (i = 0; i < number_of_symbols; i++) -| process_symbol (symbol_table[i]); - - All storage for the symbols themselves is in an objalloc - connected to the BFD; it is freed when the BFD is closed. - -INODE -Writing Symbols, Mini Symbols, Reading Symbols, Symbols -SUBSECTION - Writing symbols - - Writing of a symbol table is automatic when a BFD open for - writing is closed. The application attaches a vector of - pointers to pointers to symbols to the BFD being written, and - fills in the symbol count. The close and cleanup code reads - through the table provided and performs all the necessary - operations. The BFD output code must always be provided with an - ``owned'' symbol: one which has come from another BFD, or one - which has been created using <>. Here is an - example showing the creation of a symbol table with only one element: - -| #include "bfd.h" -| int main (void) -| { -| bfd *abfd; -| asymbol *ptrs[2]; -| asymbol *new; -| -| abfd = bfd_openw ("foo","a.out-sunos-big"); -| bfd_set_format (abfd, bfd_object); -| new = bfd_make_empty_symbol (abfd); -| new->name = "dummy_symbol"; -| new->section = bfd_make_section_old_way (abfd, ".text"); -| new->flags = BSF_GLOBAL; -| new->value = 0x12345; -| -| ptrs[0] = new; -| ptrs[1] = 0; -| -| bfd_set_symtab (abfd, ptrs, 1); -| bfd_close (abfd); -| return 0; -| } -| -| ./makesym -| nm foo -| 00012345 A dummy_symbol - - Many formats cannot represent arbitrary symbol information; for - instance, the <> object format does not allow an - arbitrary number of sections. A symbol pointing to a section - which is not one of <<.text>>, <<.data>> or <<.bss>> cannot - be described. - -INODE -Mini Symbols, typedef asymbol, Writing Symbols, Symbols -SUBSECTION - Mini Symbols - - Mini symbols provide read-only access to the symbol table. - They use less memory space, but require more time to access. - They can be useful for tools like nm or objdump, which may - have to handle symbol tables of extremely large executables. - - The <> function will read the symbols - into memory in an internal form. It will return a <> - pointer to a block of memory, a symbol count, and the size of - each symbol. The pointer is allocated using <>, and - should be freed by the caller when it is no longer needed. - - The function <> will take a pointer - to a minisymbol, and a pointer to a structure returned by - <>, and return a <> structure. - The return value may or may not be the same as the value from - <> which was passed in. - -*/ - -/* -DOCDD -INODE -typedef asymbol, symbol handling functions, Mini Symbols, Symbols - -*/ -/* -SUBSECTION - typedef asymbol - - An <> has the form: - -*/ - -/* -CODE_FRAGMENT - -. -.typedef struct bfd_symbol -.{ -. {* A pointer to the BFD which owns the symbol. This information -. is necessary so that a back end can work out what additional -. information (invisible to the application writer) is carried -. with the symbol. -. -. This field is *almost* redundant, since you can use section->owner -. instead, except that some symbols point to the global sections -. bfd_{abs,com,und}_section. This could be fixed by making -. these globals be per-bfd (or per-target-flavor). FIXME. *} -. struct bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *} -. -. {* The text of the symbol. The name is left alone, and not copied; the -. application may not alter it. *} -. const char *name; -. -. {* The value of the symbol. This really should be a union of a -. numeric value with a pointer, since some flags indicate that -. a pointer to another symbol is stored here. *} -. symvalue value; -. -. {* Attributes of a symbol. *} -.#define BSF_NO_FLAGS 0x00 -. -. {* The symbol has local scope; <> in <>. The value -. is the offset into the section of the data. *} -.#define BSF_LOCAL (1 << 0) -. -. {* The symbol has global scope; initialized data in <>. The -. value is the offset into the section of the data. *} -.#define BSF_GLOBAL (1 << 1) -. -. {* The symbol has global scope and is exported. The value is -. the offset into the section of the data. *} -.#define BSF_EXPORT BSF_GLOBAL {* No real difference. *} -. -. {* A normal C symbol would be one of: -. <>, <>, <> or -. <>. *} -. -. {* The symbol is a debugging record. The value has an arbitrary -. meaning, unless BSF_DEBUGGING_RELOC is also set. *} -.#define BSF_DEBUGGING (1 << 2) -. -. {* The symbol denotes a function entry point. Used in ELF, -. perhaps others someday. *} -.#define BSF_FUNCTION (1 << 3) -. -. {* Used by the linker. *} -.#define BSF_KEEP (1 << 5) -.#define BSF_KEEP_G (1 << 6) -. -. {* A weak global symbol, overridable without warnings by -. a regular global symbol of the same name. *} -.#define BSF_WEAK (1 << 7) -. -. {* This symbol was created to point to a section, e.g. ELF's -. STT_SECTION symbols. *} -.#define BSF_SECTION_SYM (1 << 8) -. -. {* The symbol used to be a common symbol, but now it is -. allocated. *} -.#define BSF_OLD_COMMON (1 << 9) -. -. {* In some files the type of a symbol sometimes alters its -. location in an output file - ie in coff a <> symbol -. which is also <> symbol appears where it was -. declared and not at the end of a section. This bit is set -. by the target BFD part to convey this information. *} -.#define BSF_NOT_AT_END (1 << 10) -. -. {* Signal that the symbol is the label of constructor section. *} -.#define BSF_CONSTRUCTOR (1 << 11) -. -. {* Signal that the symbol is a warning symbol. The name is a -. warning. The name of the next symbol is the one to warn about; -. if a reference is made to a symbol with the same name as the next -. symbol, a warning is issued by the linker. *} -.#define BSF_WARNING (1 << 12) -. -. {* Signal that the symbol is indirect. This symbol is an indirect -. pointer to the symbol with the same name as the next symbol. *} -.#define BSF_INDIRECT (1 << 13) -. -. {* BSF_FILE marks symbols that contain a file name. This is used -. for ELF STT_FILE symbols. *} -.#define BSF_FILE (1 << 14) -. -. {* Symbol is from dynamic linking information. *} -.#define BSF_DYNAMIC (1 << 15) -. -. {* The symbol denotes a data object. Used in ELF, and perhaps -. others someday. *} -.#define BSF_OBJECT (1 << 16) -. -. {* This symbol is a debugging symbol. The value is the offset -. into the section of the data. BSF_DEBUGGING should be set -. as well. *} -.#define BSF_DEBUGGING_RELOC (1 << 17) -. -. {* This symbol is thread local. Used in ELF. *} -.#define BSF_THREAD_LOCAL (1 << 18) -. -. {* This symbol represents a complex relocation expression, -. with the expression tree serialized in the symbol name. *} -.#define BSF_RELC (1 << 19) -. -. {* This symbol represents a signed complex relocation expression, -. with the expression tree serialized in the symbol name. *} -.#define BSF_SRELC (1 << 20) -. -. {* This symbol was created by bfd_get_synthetic_symtab. *} -.#define BSF_SYNTHETIC (1 << 21) -. -. {* This symbol is an indirect code object. Unrelated to BSF_INDIRECT. -. The dynamic linker will compute the value of this symbol by -. calling the function that it points to. BSF_FUNCTION must -. also be also set. *} -.#define BSF_GNU_INDIRECT_FUNCTION (1 << 22) -. {* This symbol is a globally unique data object. The dynamic linker -. will make sure that in the entire process there is just one symbol -. with this name and type in use. BSF_OBJECT must also be set. *} -.#define BSF_GNU_UNIQUE (1 << 23) -. -. flagword flags; -. -. {* A pointer to the section to which this symbol is -. relative. This will always be non NULL, there are special -. sections for undefined and absolute symbols. *} -. struct bfd_section *section; -. -. {* Back end special data. *} -. union -. { -. void *p; -. bfd_vma i; -. } -. udata; -.} -.asymbol; -. -*/ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "safe-ctype.h" -#include "bfdlink.h" -#include "aout/stab_gnu.h" - -/* -DOCDD -INODE -symbol handling functions, , typedef asymbol, Symbols -SUBSECTION - Symbol handling functions -*/ - -/* -FUNCTION - bfd_get_symtab_upper_bound - -DESCRIPTION - Return the number of bytes required to store a vector of pointers - to <> for all the symbols in the BFD @var{abfd}, - including a terminal NULL pointer. If there are no symbols in - the BFD, then return 0. If an error occurs, return -1. - -.#define bfd_get_symtab_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) -. -*/ - -/* -FUNCTION - bfd_is_local_label - -SYNOPSIS - bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); - -DESCRIPTION - Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is - a compiler generated local label, else return FALSE. -*/ - -bfd_boolean -bfd_is_local_label (bfd *abfd, asymbol *sym) -{ - /* The BSF_SECTION_SYM check is needed for IA-64, where every label that - starts with '.' is local. This would accidentally catch section names - if we didn't reject them here. */ - if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 0) - return FALSE; - if (sym->name == NULL) - return FALSE; - return bfd_is_local_label_name (abfd, sym->name); -} - -/* -FUNCTION - bfd_is_local_label_name - -SYNOPSIS - bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); - -DESCRIPTION - Return TRUE if a symbol with the name @var{name} in the BFD - @var{abfd} is a compiler generated local label, else return - FALSE. This just checks whether the name has the form of a - local label. - -.#define bfd_is_local_label_name(abfd, name) \ -. BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) -. -*/ - -/* -FUNCTION - bfd_is_target_special_symbol - -SYNOPSIS - bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); - -DESCRIPTION - Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something - special to the particular target represented by the BFD. Such symbols - should normally not be mentioned to the user. - -.#define bfd_is_target_special_symbol(abfd, sym) \ -. BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) -. -*/ - -/* -FUNCTION - bfd_canonicalize_symtab - -DESCRIPTION - Read the symbols from the BFD @var{abfd}, and fills in - the vector @var{location} with pointers to the symbols and - a trailing NULL. - Return the actual number of symbol pointers, not - including the NULL. - -.#define bfd_canonicalize_symtab(abfd, location) \ -. BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) -. -*/ - -/* -FUNCTION - bfd_set_symtab - -SYNOPSIS - bfd_boolean bfd_set_symtab - (bfd *abfd, asymbol **location, unsigned int count); - -DESCRIPTION - Arrange that when the output BFD @var{abfd} is closed, - the table @var{location} of @var{count} pointers to symbols - will be written. -*/ - -bfd_boolean -bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int symcount) -{ - if (abfd->format != bfd_object || bfd_read_p (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - bfd_get_outsymbols (abfd) = location; - bfd_get_symcount (abfd) = symcount; - return TRUE; -} - -/* -FUNCTION - bfd_print_symbol_vandf - -SYNOPSIS - void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); - -DESCRIPTION - Print the value and flags of the @var{symbol} supplied to the - stream @var{file}. -*/ -void -bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol) -{ - FILE *file = (FILE *) arg; - - flagword type = symbol->flags; - - if (symbol->section != NULL) - bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma); - else - bfd_fprintf_vma (abfd, file, symbol->value); - - /* This presumes that a symbol can not be both BSF_DEBUGGING and - BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and - BSF_OBJECT. */ - fprintf (file, " %c%c%c%c%c%c%c", - ((type & BSF_LOCAL) - ? (type & BSF_GLOBAL) ? '!' : 'l' - : (type & BSF_GLOBAL) ? 'g' - : (type & BSF_GNU_UNIQUE) ? 'u' : ' '), - (type & BSF_WEAK) ? 'w' : ' ', - (type & BSF_CONSTRUCTOR) ? 'C' : ' ', - (type & BSF_WARNING) ? 'W' : ' ', - (type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? 'i' : ' ', - (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ', - ((type & BSF_FUNCTION) - ? 'F' - : ((type & BSF_FILE) - ? 'f' - : ((type & BSF_OBJECT) ? 'O' : ' ')))); -} - -/* -FUNCTION - bfd_make_empty_symbol - -DESCRIPTION - Create a new <> structure for the BFD @var{abfd} - and return a pointer to it. - - This routine is necessary because each back end has private - information surrounding the <>. Building your own - <> and pointing to it will not create the private - information, and will cause problems later on. - -.#define bfd_make_empty_symbol(abfd) \ -. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) -. -*/ - -/* -FUNCTION - _bfd_generic_make_empty_symbol - -SYNOPSIS - asymbol *_bfd_generic_make_empty_symbol (bfd *); - -DESCRIPTION - Create a new <> structure for the BFD @var{abfd} - and return a pointer to it. Used by core file routines, - binary back-end and anywhere else where no private info - is needed. -*/ - -asymbol * -_bfd_generic_make_empty_symbol (bfd *abfd) -{ - bfd_size_type amt = sizeof (asymbol); - asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt); - if (new_symbol) - new_symbol->the_bfd = abfd; - return new_symbol; -} - -/* -FUNCTION - bfd_make_debug_symbol - -DESCRIPTION - Create a new <> structure for the BFD @var{abfd}, - to be used as a debugging symbol. Further details of its use have - yet to be worked out. - -.#define bfd_make_debug_symbol(abfd,ptr,size) \ -. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -. -*/ - -struct section_to_type -{ - const char *section; - char type; -}; - -/* Map section names to POSIX/BSD single-character symbol types. - This table is probably incomplete. It is sorted for convenience of - adding entries. Since it is so short, a linear search is used. */ -static const struct section_to_type stt[] = -{ - {".bss", 'b'}, - {"code", 't'}, /* MRI .text */ - {".data", 'd'}, - {"*DEBUG*", 'N'}, - {".debug", 'N'}, /* MSVC's .debug (non-standard debug syms) */ - {".drectve", 'i'}, /* MSVC's .drective section */ - {".edata", 'e'}, /* MSVC's .edata (export) section */ - {".fini", 't'}, /* ELF fini section */ - {".idata", 'i'}, /* MSVC's .idata (import) section */ - {".init", 't'}, /* ELF init section */ - {".pdata", 'p'}, /* MSVC's .pdata (stack unwind) section */ - {".rdata", 'r'}, /* Read only data. */ - {".rodata", 'r'}, /* Read only data. */ - {".sbss", 's'}, /* Small BSS (uninitialized data). */ - {".scommon", 'c'}, /* Small common. */ - {".sdata", 'g'}, /* Small initialized data. */ - {".text", 't'}, - {"vars", 'd'}, /* MRI .data */ - {"zerovars", 'b'}, /* MRI .bss */ - {0, 0} -}; - -/* Return the single-character symbol type corresponding to - section S, or '?' for an unknown COFF section. - - Check for any leading string which matches, so .text5 returns - 't' as well as .text */ - -static char -coff_section_type (const char *s) -{ - const struct section_to_type *t; - - for (t = &stt[0]; t->section; t++) - if (!strncmp (s, t->section, strlen (t->section))) - return t->type; - - return '?'; -} - -/* Return the single-character symbol type corresponding to section - SECTION, or '?' for an unknown section. This uses section flags to - identify sections. - - FIXME These types are unhandled: c, i, e, p. If we handled these also, - we could perhaps obsolete coff_section_type. */ - -static char -decode_section_type (const struct bfd_section *section) -{ - if (section->flags & SEC_CODE) - return 't'; - if (section->flags & SEC_DATA) - { - if (section->flags & SEC_READONLY) - return 'r'; - else if (section->flags & SEC_SMALL_DATA) - return 'g'; - else - return 'd'; - } - if ((section->flags & SEC_HAS_CONTENTS) == 0) - { - if (section->flags & SEC_SMALL_DATA) - return 's'; - else - return 'b'; - } - if (section->flags & SEC_DEBUGGING) - return 'N'; - if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY)) - return 'n'; - - return '?'; -} - -/* -FUNCTION - bfd_decode_symclass - -DESCRIPTION - Return a character corresponding to the symbol - class of @var{symbol}, or '?' for an unknown class. - -SYNOPSIS - int bfd_decode_symclass (asymbol *symbol); -*/ -int -bfd_decode_symclass (asymbol *symbol) -{ - char c; - - if (symbol->section && bfd_is_com_section (symbol->section)) - return 'C'; - if (bfd_is_und_section (symbol->section)) - { - if (symbol->flags & BSF_WEAK) - { - /* If weak, determine if it's specifically an object - or non-object weak. */ - if (symbol->flags & BSF_OBJECT) - return 'v'; - else - return 'w'; - } - else - return 'U'; - } - if (bfd_is_ind_section (symbol->section)) - return 'I'; - if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION) - return 'i'; - if (symbol->flags & BSF_WEAK) - { - /* If weak, determine if it's specifically an object - or non-object weak. */ - if (symbol->flags & BSF_OBJECT) - return 'V'; - else - return 'W'; - } - if (symbol->flags & BSF_GNU_UNIQUE) - return 'u'; - if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) - return '?'; - - if (bfd_is_abs_section (symbol->section)) - c = 'a'; - else if (symbol->section) - { - c = coff_section_type (symbol->section->name); - if (c == '?') - c = decode_section_type (symbol->section); - } - else - return '?'; - if (symbol->flags & BSF_GLOBAL) - c = TOUPPER (c); - return c; - - /* We don't have to handle these cases just yet, but we will soon: - N_SETV: 'v'; - N_SETA: 'l'; - N_SETT: 'x'; - N_SETD: 'z'; - N_SETB: 's'; - N_INDR: 'i'; - */ -} - -/* -FUNCTION - bfd_is_undefined_symclass - -DESCRIPTION - Returns non-zero if the class symbol returned by - bfd_decode_symclass represents an undefined symbol. - Returns zero otherwise. - -SYNOPSIS - bfd_boolean bfd_is_undefined_symclass (int symclass); -*/ - -bfd_boolean -bfd_is_undefined_symclass (int symclass) -{ - return symclass == 'U' || symclass == 'w' || symclass == 'v'; -} - -/* -FUNCTION - bfd_symbol_info - -DESCRIPTION - Fill in the basic info about symbol that nm needs. - Additional info may be added by the back-ends after - calling this function. - -SYNOPSIS - void bfd_symbol_info (asymbol *symbol, symbol_info *ret); -*/ - -void -bfd_symbol_info (asymbol *symbol, symbol_info *ret) -{ - ret->type = bfd_decode_symclass (symbol); - - if (bfd_is_undefined_symclass (ret->type)) - ret->value = 0; - else - ret->value = symbol->value + symbol->section->vma; - - ret->name = symbol->name; -} - -/* -FUNCTION - bfd_copy_private_symbol_data - -SYNOPSIS - bfd_boolean bfd_copy_private_symbol_data - (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); - -DESCRIPTION - Copy private symbol information from @var{isym} in the BFD - @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}. - Return <> on success, <> on error. Possible error - returns are: - - o <> - - Not enough memory exists to create private data for @var{osec}. - -.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ -. BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ -. (ibfd, isymbol, obfd, osymbol)) -. -*/ - -/* The generic version of the function which returns mini symbols. - This is used when the backend does not provide a more efficient - version. It just uses BFD asymbol structures as mini symbols. */ - -long -_bfd_generic_read_minisymbols (bfd *abfd, - bfd_boolean dynamic, - void **minisymsp, - unsigned int *sizep) -{ - long storage; - asymbol **syms = NULL; - long symcount; - - if (dynamic) - storage = bfd_get_dynamic_symtab_upper_bound (abfd); - else - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - goto error_return; - if (storage == 0) - return 0; - - syms = (asymbol **) bfd_malloc (storage); - if (syms == NULL) - goto error_return; - - if (dynamic) - symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); - else - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - goto error_return; - - *minisymsp = syms; - *sizep = sizeof (asymbol *); - return symcount; - - error_return: - bfd_set_error (bfd_error_no_symbols); - if (syms != NULL) - free (syms); - return -1; -} - -/* The generic version of the function which converts a minisymbol to - an asymbol. We don't worry about the sym argument we are passed; - we just return the asymbol the minisymbol points to. */ - -asymbol * -_bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED, - bfd_boolean dynamic ATTRIBUTE_UNUSED, - const void *minisym, - asymbol *sym ATTRIBUTE_UNUSED) -{ - return *(asymbol **) minisym; -} - -/* Look through stabs debugging information in .stab and .stabstr - sections to find the source file and line closest to a desired - location. This is used by COFF and ELF targets. It sets *pfound - to TRUE if it finds some information. The *pinfo field is used to - pass cached information in and out of this routine; this first time - the routine is called for a BFD, *pinfo should be NULL. The value - placed in *pinfo should be saved with the BFD, and passed back each - time this function is called. */ - -/* We use a cache by default. */ - -#define ENABLE_CACHING - -/* We keep an array of indexentry structures to record where in the - stabs section we should look to find line number information for a - particular address. */ - -struct indexentry -{ - bfd_vma val; - bfd_byte *stab; - bfd_byte *str; - char *directory_name; - char *file_name; - char *function_name; -}; - -/* Compare two indexentry structures. This is called via qsort. */ - -static int -cmpindexentry (const void *a, const void *b) -{ - const struct indexentry *contestantA = (const struct indexentry *) a; - const struct indexentry *contestantB = (const struct indexentry *) b; - - if (contestantA->val < contestantB->val) - return -1; - else if (contestantA->val > contestantB->val) - return 1; - else - return 0; -} - -/* A pointer to this structure is stored in *pinfo. */ - -struct stab_find_info -{ - /* The .stab section. */ - asection *stabsec; - /* The .stabstr section. */ - asection *strsec; - /* The contents of the .stab section. */ - bfd_byte *stabs; - /* The contents of the .stabstr section. */ - bfd_byte *strs; - - /* A table that indexes stabs by memory address. */ - struct indexentry *indextable; - /* The number of entries in indextable. */ - int indextablesize; - -#ifdef ENABLE_CACHING - /* Cached values to restart quickly. */ - struct indexentry *cached_indexentry; - bfd_vma cached_offset; - bfd_byte *cached_stab; - char *cached_file_name; -#endif - - /* Saved ptr to malloc'ed filename. */ - char *filename; -}; - -bfd_boolean -_bfd_stab_section_find_nearest_line (bfd *abfd, - asymbol **symbols, - asection *section, - bfd_vma offset, - bfd_boolean *pfound, - const char **pfilename, - const char **pfnname, - unsigned int *pline, - void **pinfo) -{ - struct stab_find_info *info; - bfd_size_type stabsize, strsize; - bfd_byte *stab, *str; - bfd_byte *last_stab = NULL; - bfd_size_type stroff; - struct indexentry *indexentry; - char *file_name; - char *directory_name; - int saw_fun; - bfd_boolean saw_line, saw_func; - - *pfound = FALSE; - *pfilename = bfd_get_filename (abfd); - *pfnname = NULL; - *pline = 0; - - /* Stabs entries use a 12 byte format: - 4 byte string table index - 1 byte stab type - 1 byte stab other field - 2 byte stab desc field - 4 byte stab value - FIXME: This will have to change for a 64 bit object format. - - The stabs symbols are divided into compilation units. For the - first entry in each unit, the type of 0, the value is the length - of the string table for this unit, and the desc field is the - number of stabs symbols for this unit. */ - -#define STRDXOFF (0) -#define TYPEOFF (4) -#define OTHEROFF (5) -#define DESCOFF (6) -#define VALOFF (8) -#define STABSIZE (12) - - info = (struct stab_find_info *) *pinfo; - if (info != NULL) - { - if (info->stabsec == NULL || info->strsec == NULL) - { - /* No stabs debugging information. */ - return TRUE; - } - - stabsize = (info->stabsec->rawsize - ? info->stabsec->rawsize - : info->stabsec->size); - strsize = (info->strsec->rawsize - ? info->strsec->rawsize - : info->strsec->size); - } - else - { - long reloc_size, reloc_count; - arelent **reloc_vector; - int i; - char *name; - char *function_name; - bfd_size_type amt = sizeof *info; - - info = (struct stab_find_info *) bfd_zalloc (abfd, amt); - if (info == NULL) - return FALSE; - - /* FIXME: When using the linker --split-by-file or - --split-by-reloc options, it is possible for the .stab and - .stabstr sections to be split. We should handle that. */ - - info->stabsec = bfd_get_section_by_name (abfd, ".stab"); - info->strsec = bfd_get_section_by_name (abfd, ".stabstr"); - - if (info->stabsec == NULL || info->strsec == NULL) - { - /* Try SOM section names. */ - info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$"); - info->strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$"); - - if (info->stabsec == NULL || info->strsec == NULL) - { - /* No stabs debugging information. Set *pinfo so that we - can return quickly in the info != NULL case above. */ - *pinfo = info; - return TRUE; - } - } - - stabsize = (info->stabsec->rawsize - ? info->stabsec->rawsize - : info->stabsec->size); - strsize = (info->strsec->rawsize - ? info->strsec->rawsize - : info->strsec->size); - - info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize); - info->strs = (bfd_byte *) bfd_alloc (abfd, strsize); - if (info->stabs == NULL || info->strs == NULL) - return FALSE; - - if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs, - 0, stabsize) - || ! bfd_get_section_contents (abfd, info->strsec, info->strs, - 0, strsize)) - return FALSE; - - /* If this is a relocatable object file, we have to relocate - the entries in .stab. This should always be simple 32 bit - relocations against symbols defined in this object file, so - this should be no big deal. */ - reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec); - if (reloc_size < 0) - return FALSE; - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - return FALSE; - reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector, - symbols); - if (reloc_count < 0) - { - if (reloc_vector != NULL) - free (reloc_vector); - return FALSE; - } - if (reloc_count > 0) - { - arelent **pr; - - for (pr = reloc_vector; *pr != NULL; pr++) - { - arelent *r; - unsigned long val; - asymbol *sym; - - r = *pr; - /* Ignore R_*_NONE relocs. */ - if (r->howto->dst_mask == 0) - continue; - - if (r->howto->rightshift != 0 - || r->howto->size != 2 - || r->howto->bitsize != 32 - || r->howto->pc_relative - || r->howto->bitpos != 0 - || r->howto->dst_mask != 0xffffffff) - { - (*_bfd_error_handler) - (_("Unsupported .stab relocation")); - bfd_set_error (bfd_error_invalid_operation); - if (reloc_vector != NULL) - free (reloc_vector); - return FALSE; - } - - val = bfd_get_32 (abfd, info->stabs + r->address); - val &= r->howto->src_mask; - sym = *r->sym_ptr_ptr; - val += sym->value + sym->section->vma + r->addend; - bfd_put_32 (abfd, (bfd_vma) val, info->stabs + r->address); - } - } - - if (reloc_vector != NULL) - free (reloc_vector); - - /* First time through this function, build a table matching - function VM addresses to stabs, then sort based on starting - VM address. Do this in two passes: once to count how many - table entries we'll need, and a second to actually build the - table. */ - - info->indextablesize = 0; - saw_fun = 1; - for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE) - { - if (stab[TYPEOFF] == (bfd_byte) N_SO) - { - /* N_SO with null name indicates EOF */ - if (bfd_get_32 (abfd, stab + STRDXOFF) == 0) - continue; - - /* if we did not see a function def, leave space for one. */ - if (saw_fun == 0) - ++info->indextablesize; - - saw_fun = 0; - - /* two N_SO's in a row is a filename and directory. Skip */ - if (stab + STABSIZE < info->stabs + stabsize - && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO) - { - stab += STABSIZE; - } - } - else if (stab[TYPEOFF] == (bfd_byte) N_FUN) - { - saw_fun = 1; - ++info->indextablesize; - } - } - - if (saw_fun == 0) - ++info->indextablesize; - - if (info->indextablesize == 0) - return TRUE; - ++info->indextablesize; - - amt = info->indextablesize; - amt *= sizeof (struct indexentry); - info->indextable = (struct indexentry *) bfd_alloc (abfd, amt); - if (info->indextable == NULL) - return FALSE; - - file_name = NULL; - directory_name = NULL; - saw_fun = 1; - - for (i = 0, stroff = 0, stab = info->stabs, str = info->strs; - i < info->indextablesize && stab < info->stabs + stabsize; - stab += STABSIZE) - { - switch (stab[TYPEOFF]) - { - case 0: - /* This is the first entry in a compilation unit. */ - if ((bfd_size_type) ((info->strs + strsize) - str) < stroff) - break; - str += stroff; - stroff = bfd_get_32 (abfd, stab + VALOFF); - break; - - case N_SO: - /* The main file name. */ - - /* The following code creates a new indextable entry with - a NULL function name if there were no N_FUNs in a file. - Note that a N_SO without a file name is an EOF and - there could be 2 N_SO following it with the new filename - and directory. */ - if (saw_fun == 0) - { - info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF); - info->indextable[i].stab = last_stab; - info->indextable[i].str = str; - info->indextable[i].directory_name = directory_name; - info->indextable[i].file_name = file_name; - info->indextable[i].function_name = NULL; - ++i; - } - saw_fun = 0; - - file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - if (*file_name == '\0') - { - directory_name = NULL; - file_name = NULL; - saw_fun = 1; - } - else - { - last_stab = stab; - if (stab + STABSIZE >= info->stabs + stabsize - || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO) - { - directory_name = NULL; - } - else - { - /* Two consecutive N_SOs are a directory and a - file name. */ - stab += STABSIZE; - directory_name = file_name; - file_name = ((char *) str - + bfd_get_32 (abfd, stab + STRDXOFF)); - } - } - break; - - case N_SOL: - /* The name of an include file. */ - file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - break; - - case N_FUN: - /* A function name. */ - saw_fun = 1; - name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - - if (*name == '\0') - name = NULL; - - function_name = name; - - if (name == NULL) - continue; - - info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF); - info->indextable[i].stab = stab; - info->indextable[i].str = str; - info->indextable[i].directory_name = directory_name; - info->indextable[i].file_name = file_name; - info->indextable[i].function_name = function_name; - ++i; - break; - } - } - - if (saw_fun == 0) - { - info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF); - info->indextable[i].stab = last_stab; - info->indextable[i].str = str; - info->indextable[i].directory_name = directory_name; - info->indextable[i].file_name = file_name; - info->indextable[i].function_name = NULL; - ++i; - } - - info->indextable[i].val = (bfd_vma) -1; - info->indextable[i].stab = info->stabs + stabsize; - info->indextable[i].str = str; - info->indextable[i].directory_name = NULL; - info->indextable[i].file_name = NULL; - info->indextable[i].function_name = NULL; - ++i; - - info->indextablesize = i; - qsort (info->indextable, (size_t) i, sizeof (struct indexentry), - cmpindexentry); - - *pinfo = info; - } - - /* We are passed a section relative offset. The offsets in the - stabs information are absolute. */ - offset += bfd_get_section_vma (abfd, section); - -#ifdef ENABLE_CACHING - if (info->cached_indexentry != NULL - && offset >= info->cached_offset - && offset < (info->cached_indexentry + 1)->val) - { - stab = info->cached_stab; - indexentry = info->cached_indexentry; - file_name = info->cached_file_name; - } - else -#endif - { - long low, high; - long mid = -1; - - /* Cache non-existent or invalid. Do binary search on - indextable. */ - indexentry = NULL; - - low = 0; - high = info->indextablesize - 1; - while (low != high) - { - mid = (high + low) / 2; - if (offset >= info->indextable[mid].val - && offset < info->indextable[mid + 1].val) - { - indexentry = &info->indextable[mid]; - break; - } - - if (info->indextable[mid].val > offset) - high = mid; - else - low = mid + 1; - } - - if (indexentry == NULL) - return TRUE; - - stab = indexentry->stab + STABSIZE; - file_name = indexentry->file_name; - } - - directory_name = indexentry->directory_name; - str = indexentry->str; - - saw_line = FALSE; - saw_func = FALSE; - for (; stab < (indexentry+1)->stab; stab += STABSIZE) - { - bfd_boolean done; - bfd_vma val; - - done = FALSE; - - switch (stab[TYPEOFF]) - { - case N_SOL: - /* The name of an include file. */ - val = bfd_get_32 (abfd, stab + VALOFF); - if (val <= offset) - { - file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); - *pline = 0; - } - break; - - case N_SLINE: - case N_DSLINE: - case N_BSLINE: - /* A line number. If the function was specified, then the value - is relative to the start of the function. Otherwise, the - value is an absolute address. */ - val = ((indexentry->function_name ? indexentry->val : 0) - + bfd_get_32 (abfd, stab + VALOFF)); - /* If this line starts before our desired offset, or if it's - the first line we've been able to find, use it. The - !saw_line check works around a bug in GCC 2.95.3, which emits - the first N_SLINE late. */ - if (!saw_line || val <= offset) - { - *pline = bfd_get_16 (abfd, stab + DESCOFF); - -#ifdef ENABLE_CACHING - info->cached_stab = stab; - info->cached_offset = val; - info->cached_file_name = file_name; - info->cached_indexentry = indexentry; -#endif - } - if (val > offset) - done = TRUE; - saw_line = TRUE; - break; - - case N_FUN: - case N_SO: - if (saw_func || saw_line) - done = TRUE; - saw_func = TRUE; - break; - } - - if (done) - break; - } - - *pfound = TRUE; - - if (file_name == NULL || IS_ABSOLUTE_PATH (file_name) - || directory_name == NULL) - *pfilename = file_name; - else - { - size_t dirlen; - - dirlen = strlen (directory_name); - if (info->filename == NULL - || filename_ncmp (info->filename, directory_name, dirlen) != 0 - || filename_cmp (info->filename + dirlen, file_name) != 0) - { - size_t len; - - /* Don't free info->filename here. objdump and other - apps keep a copy of a previously returned file name - pointer. */ - len = strlen (file_name) + 1; - info->filename = (char *) bfd_alloc (abfd, dirlen + len); - if (info->filename == NULL) - return FALSE; - memcpy (info->filename, directory_name, dirlen); - memcpy (info->filename + dirlen, file_name, len); - } - - *pfilename = info->filename; - } - - if (indexentry->function_name != NULL) - { - char *s; - - /* This will typically be something like main:F(0,1), so we want - to clobber the colon. It's OK to change the name, since the - string is in our own local storage anyhow. */ - s = strchr (indexentry->function_name, ':'); - if (s != NULL) - *s = '\0'; - - *pfnname = indexentry->function_name; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/bfd/sysdep.h b/contrib/binutils-2.22/bfd/sysdep.h deleted file mode 100644 index 20ef56d69a..0000000000 --- a/contrib/binutils-2.22/bfd/sysdep.h +++ /dev/null @@ -1,202 +0,0 @@ -/* sysdep.h -- handle host dependencies for the BFD library - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2009 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef BFD_SYSDEP_H -#define BFD_SYSDEP_H - -#include "config.h" - -#include "ansidecl.h" - -#ifdef HAVE_STDDEF_H -#include -#endif - -#include -#include -#include - -#include -#if !(defined(errno) || defined(_MSC_VER) && defined(_INC_ERRNO)) -extern int errno; -#endif - -#ifdef STRING_WITH_STRINGS -#include -#include -#else -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#else -extern char *strchr (); -extern char *strrchr (); -#endif -#endif -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef USE_BINARY_FOPEN -#include "fopen-bin.h" -#else -#include "fopen-same.h" -#endif - -#ifdef HAVE_FCNTL_H -#include -#else -#ifdef HAVE_SYS_FILE_H -#include -#endif -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#include "filenames.h" - -#if !HAVE_DECL_FFS -extern int ffs (int); -#endif - -#if !HAVE_DECL_FREE -extern void free (); -#endif - -#if !HAVE_DECL_GETENV -extern char *getenv (); -#endif - -#if !HAVE_DECL_MALLOC -extern PTR malloc (); -#endif - -#if !HAVE_DECL_REALLOC -extern PTR realloc (); -#endif - -#if !HAVE_DECL_STPCPY -extern char *stpcpy (char *__dest, const char *__src); -#endif - -#if !HAVE_DECL_STRSTR -extern char *strstr (); -#endif - -#ifdef HAVE_FTELLO -#if !HAVE_DECL_FTELLO -extern off_t ftello (FILE *stream); -#endif -#endif - -#ifdef HAVE_FTELLO64 -#if !HAVE_DECL_FTELLO64 -extern off64_t ftello64 (FILE *stream); -#endif -#endif - -#ifdef HAVE_FSEEKO -#if !HAVE_DECL_FSEEKO -extern int fseeko (FILE *stream, off_t offset, int whence); -#endif -#endif - -#ifdef HAVE_FSEEKO64 -#if !HAVE_DECL_FSEEKO64 -extern int fseeko64 (FILE *stream, off64_t offset, int whence); -#endif -#endif - -/* Define offsetof for those systems which lack it */ - -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -#ifdef ENABLE_NLS -#include -/* Note the use of dgetext() and PACKAGE here, rather than gettext(). - - This is because the code in this directory is used to build a library which - will be linked with code in other directories to form programs. We want to - maintain a seperate translation file for this directory however, rather - than being forced to merge it with that of any program linked to libbfd. - This is a library, so it cannot depend on the catalog currently loaded. - - In order to do this, we have to make sure that when we extract messages we - use the OPCODES domain rather than the domain of the program that included - the bfd library, (eg OBJDUMP). Hence we use dgettext (PACKAGE, String) - and define PACKAGE to be 'bfd'. (See the code in configure). */ -#define _(String) dgettext (PACKAGE, String) -#ifdef gettext_noop -#define N_(String) gettext_noop (String) -#else -#define N_(String) (String) -#endif -#else -# define gettext(Msgid) (Msgid) -# define dgettext(Domainname, Msgid) (Msgid) -# define dcgettext(Domainname, Msgid, Category) (Msgid) -# define textdomain(Domainname) while (0) /* nothing */ -# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ -# define _(String) (String) -# define N_(String) (String) -#endif - -#endif /* ! defined (BFD_SYSDEP_H) */ diff --git a/contrib/binutils-2.22/bfd/targets.c b/contrib/binutils-2.22/bfd/targets.c deleted file mode 100644 index 46c2c9442e..0000000000 --- a/contrib/binutils-2.22/bfd/targets.c +++ /dev/null @@ -1,1686 +0,0 @@ -/* Generic target-file-type support for the BFD library. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Cygnus Support. - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "fnmatch.h" - -/* - It's okay to see some: -#if 0 - directives in this source file, as targets.c uses them to exclude - certain BFD vectors. This comment is specially formatted to catch - users who grep for ^#if 0, so please keep it this way! -*/ - -/* -SECTION - Targets - -DESCRIPTION - Each port of BFD to a different machine requires the creation - of a target back end. All the back end provides to the root - part of BFD is a structure containing pointers to functions - which perform certain low level operations on files. BFD - translates the applications's requests through a pointer into - calls to the back end routines. - - When a file is opened with <>, its format and - target are unknown. BFD uses various mechanisms to determine - how to interpret the file. The operations performed are: - - o Create a BFD by calling the internal routine - <<_bfd_new_bfd>>, then call <> with the - target string supplied to <> and the new BFD pointer. - - o If a null target string was provided to <>, - look up the environment variable <> and use - that as the target string. - - o If the target string is still <>, or the target string is - <>, then use the first item in the target vector - as the target type, and set <> in the BFD to - cause <> to loop through all the targets. - @xref{bfd_target}. @xref{Formats}. - - o Otherwise, inspect the elements in the target vector - one by one, until a match on target name is found. When found, - use it. - - o Otherwise return the error <> to - <>. - - o <> attempts to open the file using - <>, and returns the BFD. - - Once the BFD has been opened and the target selected, the file - format may be determined. This is done by calling - <> on the BFD with a suggested format. - If <> has been set, each possible target - type is tried to see if it recognizes the specified format. - <> returns <> when the caller guesses right. -@menu -@* bfd_target:: -@end menu -*/ - -/* - -INODE - bfd_target, , Targets, Targets -DOCDD -SUBSECTION - bfd_target - -DESCRIPTION - This structure contains everything that BFD knows about a - target. It includes things like its byte order, name, and which - routines to call to do various operations. - - Every BFD points to a target structure with its <> - member. - - The macros below are used to dispatch to functions through the - <> vector. They are used in a number of macros further - down in @file{bfd.h}, and are also used when calling various - routines by hand inside the BFD implementation. The @var{arglist} - argument must be parenthesized; it contains all the arguments - to the called function. - - They make the documentation (more) unpleasant to read, so if - someone wants to fix this and not break the above, please do. - -.#define BFD_SEND(bfd, message, arglist) \ -. ((*((bfd)->xvec->message)) arglist) -. -.#ifdef DEBUG_BFD_SEND -.#undef BFD_SEND -.#define BFD_SEND(bfd, message, arglist) \ -. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ -. ((*((bfd)->xvec->message)) arglist) : \ -. (bfd_assert (__FILE__,__LINE__), NULL)) -.#endif - - For operations which index on the BFD format: - -.#define BFD_SEND_FMT(bfd, message, arglist) \ -. (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) -. -.#ifdef DEBUG_BFD_SEND -.#undef BFD_SEND_FMT -.#define BFD_SEND_FMT(bfd, message, arglist) \ -. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ -. (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ -. (bfd_assert (__FILE__,__LINE__), NULL)) -.#endif -. - This is the structure which defines the type of BFD this is. The - <> member of the struct <> itself points here. Each - module that implements access to a different target under BFD, - defines one of these. - - FIXME, these names should be rationalised with the names of - the entry points which call them. Too bad we can't have one - macro to define them both! - -.enum bfd_flavour -.{ -. bfd_target_unknown_flavour, -. bfd_target_aout_flavour, -. bfd_target_coff_flavour, -. bfd_target_ecoff_flavour, -. bfd_target_xcoff_flavour, -. bfd_target_elf_flavour, -. bfd_target_ieee_flavour, -. bfd_target_nlm_flavour, -. bfd_target_oasys_flavour, -. bfd_target_tekhex_flavour, -. bfd_target_srec_flavour, -. bfd_target_verilog_flavour, -. bfd_target_ihex_flavour, -. bfd_target_som_flavour, -. bfd_target_os9k_flavour, -. bfd_target_versados_flavour, -. bfd_target_msdos_flavour, -. bfd_target_ovax_flavour, -. bfd_target_evax_flavour, -. bfd_target_mmo_flavour, -. bfd_target_mach_o_flavour, -. bfd_target_pef_flavour, -. bfd_target_pef_xlib_flavour, -. bfd_target_sym_flavour -.}; -. -.enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; -. -.{* Forward declaration. *} -.typedef struct bfd_link_info _bfd_link_info; -. -.{* Forward declaration. *} -.typedef struct flag_info flag_info; -. -.typedef struct bfd_target -.{ -. {* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. *} -. char *name; -. -. {* The "flavour" of a back end is a general indication about -. the contents of a file. *} -. enum bfd_flavour flavour; -. -. {* The order of bytes within the data area of a file. *} -. enum bfd_endian byteorder; -. -. {* The order of bytes within the header parts of a file. *} -. enum bfd_endian header_byteorder; -. -. {* A mask of all the flags which an executable may have set - -. from the set <>, <>, ...<>. *} -. flagword object_flags; -. -. {* A mask of all the flags which a section may have set - from -. the set <>, <>, ...<>. *} -. flagword section_flags; -. -. {* The character normally found at the front of a symbol. -. (if any), perhaps `_'. *} -. char symbol_leading_char; -. -. {* The pad character for file names within an archive header. *} -. char ar_pad_char; -. -. {* The maximum number of characters in an archive header. *} -. unsigned char ar_max_namelen; -. -. {* How well this target matches, used to select between various -. possible targets when more than one target matches. *} -. unsigned char match_priority; -. -. {* Entries for byte swapping for data. These are different from the -. other entry points, since they don't take a BFD as the first argument. -. Certain other handlers could do the same. *} -. bfd_uint64_t (*bfd_getx64) (const void *); -. bfd_int64_t (*bfd_getx_signed_64) (const void *); -. void (*bfd_putx64) (bfd_uint64_t, void *); -. bfd_vma (*bfd_getx32) (const void *); -. bfd_signed_vma (*bfd_getx_signed_32) (const void *); -. void (*bfd_putx32) (bfd_vma, void *); -. bfd_vma (*bfd_getx16) (const void *); -. bfd_signed_vma (*bfd_getx_signed_16) (const void *); -. void (*bfd_putx16) (bfd_vma, void *); -. -. {* Byte swapping for the headers. *} -. bfd_uint64_t (*bfd_h_getx64) (const void *); -. bfd_int64_t (*bfd_h_getx_signed_64) (const void *); -. void (*bfd_h_putx64) (bfd_uint64_t, void *); -. bfd_vma (*bfd_h_getx32) (const void *); -. bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); -. void (*bfd_h_putx32) (bfd_vma, void *); -. bfd_vma (*bfd_h_getx16) (const void *); -. bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); -. void (*bfd_h_putx16) (bfd_vma, void *); -. -. {* Format dependent routines: these are vectors of entry points -. within the target vector structure, one for each format to check. *} -. -. {* Check the format of a file being read. Return a <> or zero. *} -. const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); -. -. {* Set the format of a file being written. *} -. bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); -. -. {* Write cached information into a file being written, at <>. *} -. bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); -. -The general target vector. These vectors are initialized using the -BFD_JUMP_TABLE macros. -. -. {* Generic entry points. *} -.#define BFD_JUMP_TABLE_GENERIC(NAME) \ -. NAME##_close_and_cleanup, \ -. NAME##_bfd_free_cached_info, \ -. NAME##_new_section_hook, \ -. NAME##_get_section_contents, \ -. NAME##_get_section_contents_in_window -. -. {* Called when the BFD is being closed to do any necessary cleanup. *} -. bfd_boolean (*_close_and_cleanup) (bfd *); -. {* Ask the BFD to free all cached information. *} -. bfd_boolean (*_bfd_free_cached_info) (bfd *); -. {* Called when a new section is created. *} -. bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); -. {* Read the contents of a section. *} -. bfd_boolean (*_bfd_get_section_contents) -. (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); -. bfd_boolean (*_bfd_get_section_contents_in_window) -. (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); -. -. {* Entry points to copy private data. *} -.#define BFD_JUMP_TABLE_COPY(NAME) \ -. NAME##_bfd_copy_private_bfd_data, \ -. NAME##_bfd_merge_private_bfd_data, \ -. _bfd_generic_init_private_section_data, \ -. NAME##_bfd_copy_private_section_data, \ -. NAME##_bfd_copy_private_symbol_data, \ -. NAME##_bfd_copy_private_header_data, \ -. NAME##_bfd_set_private_flags, \ -. NAME##_bfd_print_private_bfd_data -. -. {* Called to copy BFD general private data from one object file -. to another. *} -. bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); -. {* Called to merge BFD general private data from one object file -. to a common output file when linking. *} -. bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); -. {* Called to initialize BFD private section data from one object file -. to another. *} -.#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ -. BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) -. bfd_boolean (*_bfd_init_private_section_data) -. (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); -. {* Called to copy BFD private section data from one object file -. to another. *} -. bfd_boolean (*_bfd_copy_private_section_data) -. (bfd *, sec_ptr, bfd *, sec_ptr); -. {* Called to copy BFD private symbol data from one symbol -. to another. *} -. bfd_boolean (*_bfd_copy_private_symbol_data) -. (bfd *, asymbol *, bfd *, asymbol *); -. {* Called to copy BFD private header data from one object file -. to another. *} -. bfd_boolean (*_bfd_copy_private_header_data) -. (bfd *, bfd *); -. {* Called to set private backend flags. *} -. bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); -. -. {* Called to print private BFD data. *} -. bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); -. -. {* Core file entry points. *} -.#define BFD_JUMP_TABLE_CORE(NAME) \ -. NAME##_core_file_failing_command, \ -. NAME##_core_file_failing_signal, \ -. NAME##_core_file_matches_executable_p, \ -. NAME##_core_file_pid -. -. char * (*_core_file_failing_command) (bfd *); -. int (*_core_file_failing_signal) (bfd *); -. bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); -. int (*_core_file_pid) (bfd *); -. -. {* Archive entry points. *} -.#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ -. NAME##_slurp_armap, \ -. NAME##_slurp_extended_name_table, \ -. NAME##_construct_extended_name_table, \ -. NAME##_truncate_arname, \ -. NAME##_write_armap, \ -. NAME##_read_ar_hdr, \ -. NAME##_write_ar_hdr, \ -. NAME##_openr_next_archived_file, \ -. NAME##_get_elt_at_index, \ -. NAME##_generic_stat_arch_elt, \ -. NAME##_update_armap_timestamp -. -. bfd_boolean (*_bfd_slurp_armap) (bfd *); -. bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); -. bfd_boolean (*_bfd_construct_extended_name_table) -. (bfd *, char **, bfd_size_type *, const char **); -. void (*_bfd_truncate_arname) (bfd *, const char *, char *); -. bfd_boolean (*write_armap) -. (bfd *, unsigned int, struct orl *, unsigned int, int); -. void * (*_bfd_read_ar_hdr_fn) (bfd *); -. bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *); -. bfd * (*openr_next_archived_file) (bfd *, bfd *); -.#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) -. bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); -. int (*_bfd_stat_arch_elt) (bfd *, struct stat *); -. bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); -. -. {* Entry points used for symbols. *} -.#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ -. NAME##_get_symtab_upper_bound, \ -. NAME##_canonicalize_symtab, \ -. NAME##_make_empty_symbol, \ -. NAME##_print_symbol, \ -. NAME##_get_symbol_info, \ -. NAME##_bfd_is_local_label_name, \ -. NAME##_bfd_is_target_special_symbol, \ -. NAME##_get_lineno, \ -. NAME##_find_nearest_line, \ -. _bfd_generic_find_line, \ -. NAME##_find_inliner_info, \ -. NAME##_bfd_make_debug_symbol, \ -. NAME##_read_minisymbols, \ -. NAME##_minisymbol_to_symbol -. -. long (*_bfd_get_symtab_upper_bound) (bfd *); -. long (*_bfd_canonicalize_symtab) -. (bfd *, struct bfd_symbol **); -. struct bfd_symbol * -. (*_bfd_make_empty_symbol) (bfd *); -. void (*_bfd_print_symbol) -. (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); -.#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) -. void (*_bfd_get_symbol_info) -. (bfd *, struct bfd_symbol *, symbol_info *); -.#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) -. bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); -. bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); -. alent * (*_get_lineno) (bfd *, struct bfd_symbol *); -. bfd_boolean (*_bfd_find_nearest_line) -. (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, -. const char **, const char **, unsigned int *); -. bfd_boolean (*_bfd_find_line) -. (bfd *, struct bfd_symbol **, struct bfd_symbol *, -. const char **, unsigned int *); -. bfd_boolean (*_bfd_find_inliner_info) -. (bfd *, const char **, const char **, unsigned int *); -. {* Back-door to allow format-aware applications to create debug symbols -. while using BFD for everything else. Currently used by the assembler -. when creating COFF files. *} -. asymbol * (*_bfd_make_debug_symbol) -. (bfd *, void *, unsigned long size); -.#define bfd_read_minisymbols(b, d, m, s) \ -. BFD_SEND (b, _read_minisymbols, (b, d, m, s)) -. long (*_read_minisymbols) -. (bfd *, bfd_boolean, void **, unsigned int *); -.#define bfd_minisymbol_to_symbol(b, d, m, f) \ -. BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) -. asymbol * (*_minisymbol_to_symbol) -. (bfd *, bfd_boolean, const void *, asymbol *); -. -. {* Routines for relocs. *} -.#define BFD_JUMP_TABLE_RELOCS(NAME) \ -. NAME##_get_reloc_upper_bound, \ -. NAME##_canonicalize_reloc, \ -. NAME##_bfd_reloc_type_lookup, \ -. NAME##_bfd_reloc_name_lookup -. -. long (*_get_reloc_upper_bound) (bfd *, sec_ptr); -. long (*_bfd_canonicalize_reloc) -. (bfd *, sec_ptr, arelent **, struct bfd_symbol **); -. {* See documentation on reloc types. *} -. reloc_howto_type * -. (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); -. reloc_howto_type * -. (*reloc_name_lookup) (bfd *, const char *); -. -. -. {* Routines used when writing an object file. *} -.#define BFD_JUMP_TABLE_WRITE(NAME) \ -. NAME##_set_arch_mach, \ -. NAME##_set_section_contents -. -. bfd_boolean (*_bfd_set_arch_mach) -. (bfd *, enum bfd_architecture, unsigned long); -. bfd_boolean (*_bfd_set_section_contents) -. (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); -. -. {* Routines used by the linker. *} -.#define BFD_JUMP_TABLE_LINK(NAME) \ -. NAME##_sizeof_headers, \ -. NAME##_bfd_get_relocated_section_contents, \ -. NAME##_bfd_relax_section, \ -. NAME##_bfd_link_hash_table_create, \ -. NAME##_bfd_link_hash_table_free, \ -. NAME##_bfd_link_add_symbols, \ -. NAME##_bfd_link_just_syms, \ -. NAME##_bfd_copy_link_hash_symbol_type, \ -. NAME##_bfd_final_link, \ -. NAME##_bfd_link_split_section, \ -. NAME##_bfd_gc_sections, \ -. NAME##_bfd_lookup_section_flags, \ -. NAME##_bfd_merge_sections, \ -. NAME##_bfd_is_group_section, \ -. NAME##_bfd_discard_group, \ -. NAME##_section_already_linked, \ -. NAME##_bfd_define_common_symbol -. -. int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *); -. bfd_byte * (*_bfd_get_relocated_section_contents) -. (bfd *, struct bfd_link_info *, struct bfd_link_order *, -. bfd_byte *, bfd_boolean, struct bfd_symbol **); -. -. bfd_boolean (*_bfd_relax_section) -. (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); -. -. {* Create a hash table for the linker. Different backends store -. different information in this table. *} -. struct bfd_link_hash_table * -. (*_bfd_link_hash_table_create) (bfd *); -. -. {* Release the memory associated with the linker hash table. *} -. void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); -. -. {* Add symbols from this object file into the hash table. *} -. bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); -. -. {* Indicate that we are only retrieving symbol values from this section. *} -. void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); -. -. {* Copy the symbol type of a linker hash table entry. *} -.#define bfd_copy_link_hash_symbol_type(b, t, f) \ -. BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) -. void (*_bfd_copy_link_hash_symbol_type) -. (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); -. -. {* Do a link based on the link_order structures attached to each -. section of the BFD. *} -. bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); -. -. {* Should this section be split up into smaller pieces during linking. *} -. bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); -. -. {* Remove sections that are not referenced from the output. *} -. bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); -. -. {* Sets the bitmask of allowed and disallowed section flags. *} -. void (*_bfd_lookup_section_flags) (struct bfd_link_info *, -. struct flag_info *); -. -. {* Attempt to merge SEC_MERGE sections. *} -. bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); -. -. {* Is this section a member of a group? *} -. bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); -. -. {* Discard members of a group. *} -. bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); -. -. {* Check if SEC has been already linked during a reloceatable or -. final link. *} -. bfd_boolean (*_section_already_linked) (bfd *, asection *, -. struct bfd_link_info *); -. -. {* Define a common symbol. *} -. bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *, -. struct bfd_link_hash_entry *); -. -. {* Routines to handle dynamic symbols and relocs. *} -.#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ -. NAME##_get_dynamic_symtab_upper_bound, \ -. NAME##_canonicalize_dynamic_symtab, \ -. NAME##_get_synthetic_symtab, \ -. NAME##_get_dynamic_reloc_upper_bound, \ -. NAME##_canonicalize_dynamic_reloc -. -. {* Get the amount of memory required to hold the dynamic symbols. *} -. long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); -. {* Read in the dynamic symbols. *} -. long (*_bfd_canonicalize_dynamic_symtab) -. (bfd *, struct bfd_symbol **); -. {* Create synthetized symbols. *} -. long (*_bfd_get_synthetic_symtab) -. (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, -. struct bfd_symbol **); -. {* Get the amount of memory required to hold the dynamic relocs. *} -. long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); -. {* Read in the dynamic relocs. *} -. long (*_bfd_canonicalize_dynamic_reloc) -. (bfd *, arelent **, struct bfd_symbol **); -. - -A pointer to an alternative bfd_target in case the current one is not -satisfactory. This can happen when the target cpu supports both big -and little endian code, and target chosen by the linker has the wrong -endianness. The function open_output() in ld/ldlang.c uses this field -to find an alternative output format that is suitable. - -. {* Opposite endian version of this target. *} -. const struct bfd_target * alternative_target; -. - -. {* Data for use by back-end routines, which isn't -. generic enough to belong in this structure. *} -. const void *backend_data; -. -.} bfd_target; -. -*/ - -/* All known xvecs (even those that don't compile on all systems). - Alphabetized for easy reference. - They are listed a second time below, since - we can't intermix extern's and initializers. */ -extern const bfd_target a_out_adobe_vec; -extern const bfd_target aix5coff64_vec; -extern const bfd_target aout0_big_vec; -extern const bfd_target aout_arm_big_vec; -extern const bfd_target aout_arm_little_vec; -extern const bfd_target aout_mips_big_vec; -extern const bfd_target aout_mips_little_vec; -extern const bfd_target apollocoff_vec; -extern const bfd_target arm_epoc_pe_big_vec; -extern const bfd_target arm_epoc_pe_little_vec; -extern const bfd_target arm_epoc_pei_big_vec; -extern const bfd_target arm_epoc_pei_little_vec; -extern const bfd_target arm_wince_pe_big_vec; -extern const bfd_target arm_wince_pe_little_vec; -extern const bfd_target arm_wince_pei_big_vec; -extern const bfd_target arm_wince_pei_little_vec; -extern const bfd_target armcoff_big_vec; -extern const bfd_target armcoff_little_vec; -extern const bfd_target armnetbsd_vec; -extern const bfd_target armpe_big_vec; -extern const bfd_target armpe_little_vec; -extern const bfd_target armpei_big_vec; -extern const bfd_target armpei_little_vec; -extern const bfd_target b_out_vec_big_host; -extern const bfd_target b_out_vec_little_host; -extern const bfd_target bfd_pei_ia64_vec; -extern const bfd_target bfd_elf32_avr_vec; -extern const bfd_target bfd_elf32_bfin_vec; -extern const bfd_target bfd_elf32_bfinfdpic_vec; -extern const bfd_target bfd_elf32_big_generic_vec; -extern const bfd_target bfd_elf32_bigarc_vec; -extern const bfd_target bfd_elf32_bigarm_vec; -extern const bfd_target bfd_elf32_bigarm_symbian_vec; -extern const bfd_target bfd_elf32_bigarm_vxworks_vec; -extern const bfd_target bfd_elf32_bigmips_vec; -extern const bfd_target bfd_elf32_bigmips_vxworks_vec; -extern const bfd_target bfd_elf32_cr16_vec; -extern const bfd_target bfd_elf32_cr16c_vec; -extern const bfd_target bfd_elf32_cris_vec; -extern const bfd_target bfd_elf32_crx_vec; -extern const bfd_target bfd_elf32_d10v_vec; -extern const bfd_target bfd_elf32_d30v_vec; -extern const bfd_target bfd_elf32_dlx_big_vec; -extern const bfd_target bfd_elf32_fr30_vec; -extern const bfd_target bfd_elf32_frv_vec; -extern const bfd_target bfd_elf32_frvfdpic_vec; -extern const bfd_target bfd_elf32_moxie_vec; -extern const bfd_target bfd_elf32_h8300_vec; -extern const bfd_target bfd_elf32_hppa_linux_vec; -extern const bfd_target bfd_elf32_hppa_nbsd_vec; -extern const bfd_target bfd_elf32_hppa_vec; -extern const bfd_target bfd_elf32_i370_vec; -extern const bfd_target bfd_elf32_i386_freebsd_vec; -extern const bfd_target bfd_elf32_i386_nacl_vec; -extern const bfd_target bfd_elf32_i386_sol2_vec; -extern const bfd_target bfd_elf32_i386_vxworks_vec; -extern const bfd_target bfd_elf32_i386_vec; -extern const bfd_target bfd_elf32_i860_little_vec; -extern const bfd_target bfd_elf32_i860_vec; -extern const bfd_target bfd_elf32_i960_vec; -extern const bfd_target bfd_elf32_ia64_big_vec; -extern const bfd_target bfd_elf32_ia64_hpux_big_vec; -extern const bfd_target bfd_elf32_ip2k_vec; -extern const bfd_target bfd_elf32_iq2000_vec; -extern const bfd_target bfd_elf32_lm32_vec; -extern const bfd_target bfd_elf32_lm32fdpic_vec; -extern const bfd_target bfd_elf32_little_generic_vec; -extern const bfd_target bfd_elf32_littlearc_vec; -extern const bfd_target bfd_elf32_littlearm_vec; -extern const bfd_target bfd_elf32_littlearm_symbian_vec; -extern const bfd_target bfd_elf32_littlearm_vxworks_vec; -extern const bfd_target bfd_elf32_littlemips_vec; -extern const bfd_target bfd_elf32_littlemips_vxworks_vec; -extern const bfd_target bfd_elf32_m32c_vec; -extern const bfd_target bfd_elf32_m32r_vec; -extern const bfd_target bfd_elf32_m32rle_vec; -extern const bfd_target bfd_elf32_m32rlin_vec; -extern const bfd_target bfd_elf32_m32rlelin_vec; -extern const bfd_target bfd_elf32_m68hc11_vec; -extern const bfd_target bfd_elf32_m68hc12_vec; -extern const bfd_target bfd_elf32_m68k_vec; -extern const bfd_target bfd_elf32_m88k_vec; -extern const bfd_target bfd_elf32_mcore_big_vec; -extern const bfd_target bfd_elf32_mcore_little_vec; -extern const bfd_target bfd_elf32_mep_vec; -extern const bfd_target bfd_elf32_mep_little_vec; -extern const bfd_target bfd_elf32_microblaze_vec; -extern const bfd_target bfd_elf32_mn10200_vec; -extern const bfd_target bfd_elf32_mn10300_vec; -extern const bfd_target bfd_elf32_mt_vec; -extern const bfd_target bfd_elf32_msp430_vec; -extern const bfd_target bfd_elf32_nbigmips_vec; -extern const bfd_target bfd_elf32_nlittlemips_vec; -extern const bfd_target bfd_elf32_ntradbigmips_vec; -extern const bfd_target bfd_elf32_ntradlittlemips_vec; -extern const bfd_target bfd_elf32_ntradbigmips_freebsd_vec; -extern const bfd_target bfd_elf32_ntradlittlemips_freebsd_vec; -extern const bfd_target bfd_elf32_openrisc_vec; -extern const bfd_target bfd_elf32_or32_big_vec; -extern const bfd_target bfd_elf32_pj_vec; -extern const bfd_target bfd_elf32_pjl_vec; -extern const bfd_target bfd_elf32_powerpc_vec; -extern const bfd_target bfd_elf32_powerpcle_vec; -extern const bfd_target bfd_elf32_powerpc_vxworks_vec; -extern const bfd_target bfd_elf32_rx_le_vec; -extern const bfd_target bfd_elf32_rx_be_vec; -extern const bfd_target bfd_elf32_rx_be_ns_vec; -extern const bfd_target bfd_elf32_s390_vec; -extern const bfd_target bfd_elf32_bigscore_vec; -extern const bfd_target bfd_elf32_littlescore_vec; -extern const bfd_target bfd_elf32_sh64_vec; -extern const bfd_target bfd_elf32_sh64l_vec; -extern const bfd_target bfd_elf32_sh64lin_vec; -extern const bfd_target bfd_elf32_sh64blin_vec; -extern const bfd_target bfd_elf32_sh64lnbsd_vec; -extern const bfd_target bfd_elf32_sh64nbsd_vec; -extern const bfd_target bfd_elf32_sh_vec; -extern const bfd_target bfd_elf32_shbfd_vec; -extern const bfd_target bfd_elf32_shblin_vec; -extern const bfd_target bfd_elf32_shfd_vec; -extern const bfd_target bfd_elf32_shl_vec; -extern const bfd_target bfd_elf32_shl_symbian_vec; -extern const bfd_target bfd_elf32_shlin_vec; -extern const bfd_target bfd_elf32_shlnbsd_vec; -extern const bfd_target bfd_elf32_shlvxworks_vec; -extern const bfd_target bfd_elf32_shnbsd_vec; -extern const bfd_target bfd_elf32_shvxworks_vec; -extern const bfd_target bfd_elf32_sparc_vec; -extern const bfd_target bfd_elf32_sparc_sol2_vec; -extern const bfd_target bfd_elf32_sparc_vxworks_vec; -extern const bfd_target bfd_elf32_spu_vec; -extern const bfd_target bfd_elf32_tic6x_be_vec; -extern const bfd_target bfd_elf32_tic6x_le_vec; -extern const bfd_target bfd_elf32_tic6x_elf_be_vec; -extern const bfd_target bfd_elf32_tic6x_elf_le_vec; -extern const bfd_target bfd_elf32_tic6x_linux_be_vec; -extern const bfd_target bfd_elf32_tic6x_linux_le_vec; -extern const bfd_target bfd_elf32_tilegx_vec; -extern const bfd_target bfd_elf32_tilepro_vec; -extern const bfd_target bfd_elf32_tradbigmips_vec; -extern const bfd_target bfd_elf32_tradlittlemips_vec; -extern const bfd_target bfd_elf32_tradbigmips_freebsd_vec; -extern const bfd_target bfd_elf32_tradlittlemips_freebsd_vec; -extern const bfd_target bfd_elf32_us_cris_vec; -extern const bfd_target bfd_elf32_v850_vec; -extern const bfd_target bfd_elf32_vax_vec; -extern const bfd_target bfd_elf32_xc16x_vec; -extern const bfd_target bfd_elf32_xstormy16_vec; -extern const bfd_target bfd_elf32_xtensa_be_vec; -extern const bfd_target bfd_elf32_xtensa_le_vec; -extern const bfd_target bfd_elf64_alpha_freebsd_vec; -extern const bfd_target bfd_elf64_alpha_vec; -extern const bfd_target bfd_elf64_big_generic_vec; -extern const bfd_target bfd_elf64_bigmips_vec; -extern const bfd_target bfd_elf64_hppa_linux_vec; -extern const bfd_target bfd_elf64_hppa_vec; -extern const bfd_target bfd_elf64_ia64_big_vec; -extern const bfd_target bfd_elf64_ia64_hpux_big_vec; -extern const bfd_target bfd_elf64_ia64_little_vec; -extern const bfd_target bfd_elf64_ia64_vms_vec; -extern const bfd_target bfd_elf64_little_generic_vec; -extern const bfd_target bfd_elf64_littlemips_vec; -extern const bfd_target bfd_elf64_mmix_vec; -extern const bfd_target bfd_elf64_powerpc_vec; -extern const bfd_target bfd_elf64_powerpcle_vec; -extern const bfd_target bfd_elf64_s390_vec; -extern const bfd_target bfd_elf64_sh64_vec; -extern const bfd_target bfd_elf64_sh64l_vec; -extern const bfd_target bfd_elf64_sh64lin_vec; -extern const bfd_target bfd_elf64_sh64blin_vec; -extern const bfd_target bfd_elf64_sh64lnbsd_vec; -extern const bfd_target bfd_elf64_sh64nbsd_vec; -extern const bfd_target bfd_elf64_sparc_vec; -extern const bfd_target bfd_elf64_sparc_freebsd_vec; -extern const bfd_target bfd_elf64_sparc_sol2_vec; -extern const bfd_target bfd_elf64_tilegx_vec; -extern const bfd_target bfd_elf64_tradbigmips_vec; -extern const bfd_target bfd_elf64_tradlittlemips_vec; -extern const bfd_target bfd_elf64_tradbigmips_freebsd_vec; -extern const bfd_target bfd_elf64_tradlittlemips_freebsd_vec; -extern const bfd_target bfd_elf64_x86_64_freebsd_vec; -extern const bfd_target bfd_elf64_x86_64_sol2_vec; -extern const bfd_target bfd_elf64_x86_64_vec; -extern const bfd_target bfd_elf32_x86_64_vec; -extern const bfd_target bfd_elf64_l1om_freebsd_vec; -extern const bfd_target bfd_elf64_l1om_vec; -extern const bfd_target bfd_elf64_k1om_freebsd_vec; -extern const bfd_target bfd_elf64_k1om_vec; -extern const bfd_target bfd_mmo_vec; -extern const bfd_target bfd_powerpc_pe_vec; -extern const bfd_target bfd_powerpc_pei_vec; -extern const bfd_target bfd_powerpcle_pe_vec; -extern const bfd_target bfd_powerpcle_pei_vec; -extern const bfd_target cris_aout_vec; -extern const bfd_target demo_64_vec; -extern const bfd_target ecoff_big_vec; -extern const bfd_target ecoff_biglittle_vec; -extern const bfd_target ecoff_little_vec; -extern const bfd_target ecoffalpha_little_vec; -extern const bfd_target go32coff_vec; -extern const bfd_target go32stubbedcoff_vec; -extern const bfd_target h8300coff_vec; -extern const bfd_target h8500coff_vec; -extern const bfd_target host_aout_vec; -extern const bfd_target hp300bsd_vec; -extern const bfd_target hp300hpux_vec; -extern const bfd_target i386aout_vec; -extern const bfd_target i386bsd_vec; -extern const bfd_target i386coff_vec; -extern const bfd_target i386dynix_vec; -extern const bfd_target i386freebsd_vec; -extern const bfd_target i386linux_vec; -extern const bfd_target i386lynx_aout_vec; -extern const bfd_target i386lynx_coff_vec; -extern const bfd_target i386mach3_vec; -extern const bfd_target i386msdos_vec; -extern const bfd_target i386netbsd_vec; -extern const bfd_target i386os9k_vec; -extern const bfd_target i386pe_vec; -extern const bfd_target i386pei_vec; -extern const bfd_target i860coff_vec; -extern const bfd_target icoff_big_vec; -extern const bfd_target icoff_little_vec; -extern const bfd_target ieee_vec; -extern const bfd_target m68k4knetbsd_vec; -extern const bfd_target m68kaux_coff_vec; -extern const bfd_target m68kcoff_vec; -extern const bfd_target m68kcoffun_vec; -extern const bfd_target m68klinux_vec; -extern const bfd_target m68knetbsd_vec; -extern const bfd_target m68ksysvcoff_vec; -extern const bfd_target m88kbcs_vec; -extern const bfd_target m88kmach3_vec; -extern const bfd_target m88kopenbsd_vec; -extern const bfd_target mach_o_be_vec; -extern const bfd_target mach_o_le_vec; -extern const bfd_target mach_o_fat_vec; -extern const bfd_target mach_o_i386_vec; -extern const bfd_target mach_o_x86_64_vec; -extern const bfd_target mcore_pe_big_vec; -extern const bfd_target mcore_pe_little_vec; -extern const bfd_target mcore_pei_big_vec; -extern const bfd_target mcore_pei_little_vec; -extern const bfd_target mipslpe_vec; -extern const bfd_target mipslpei_vec; -extern const bfd_target newsos3_vec; -extern const bfd_target nlm32_alpha_vec; -extern const bfd_target nlm32_i386_vec; -extern const bfd_target nlm32_powerpc_vec; -extern const bfd_target nlm32_sparc_vec; -extern const bfd_target oasys_vec; -extern const bfd_target or32coff_big_vec; -extern const bfd_target pc532machaout_vec; -extern const bfd_target pc532netbsd_vec; -extern const bfd_target pdp11_aout_vec; -extern const bfd_target pef_vec; -extern const bfd_target pef_xlib_vec; -extern const bfd_target plugin_vec; -extern const bfd_target pmac_xcoff_vec; -extern const bfd_target ppcboot_vec; -extern const bfd_target riscix_vec; -extern const bfd_target rs6000coff64_vec; -extern const bfd_target rs6000coff_vec; -extern const bfd_target shcoff_small_vec; -extern const bfd_target shcoff_vec; -extern const bfd_target shlcoff_small_vec; -extern const bfd_target shlcoff_vec; -extern const bfd_target shlpe_vec; -extern const bfd_target shlpei_vec; -extern const bfd_target som_vec; -extern const bfd_target sparccoff_vec; -extern const bfd_target sparcle_aout_vec; -extern const bfd_target sparclinux_vec; -extern const bfd_target sparclynx_aout_vec; -extern const bfd_target sparclynx_coff_vec; -extern const bfd_target sparcnetbsd_vec; -extern const bfd_target sunos_big_vec; -extern const bfd_target sym_vec; -extern const bfd_target tic30_aout_vec; -extern const bfd_target tic30_coff_vec; -extern const bfd_target tic4x_coff0_beh_vec; -extern const bfd_target tic4x_coff0_vec; -extern const bfd_target tic4x_coff1_beh_vec; -extern const bfd_target tic4x_coff1_vec; -extern const bfd_target tic4x_coff2_beh_vec; -extern const bfd_target tic4x_coff2_vec; -extern const bfd_target tic54x_coff0_beh_vec; -extern const bfd_target tic54x_coff0_vec; -extern const bfd_target tic54x_coff1_beh_vec; -extern const bfd_target tic54x_coff1_vec; -extern const bfd_target tic54x_coff2_beh_vec; -extern const bfd_target tic54x_coff2_vec; -extern const bfd_target tic80coff_vec; -extern const bfd_target vaxbsd_vec; -extern const bfd_target vaxnetbsd_vec; -extern const bfd_target vax1knetbsd_vec; -extern const bfd_target versados_vec; -extern const bfd_target vms_alpha_vec; -extern const bfd_target vms_lib_txt_vec; -extern const bfd_target w65_vec; -extern const bfd_target we32kcoff_vec; -extern const bfd_target x86_64pe_vec; -extern const bfd_target x86_64pei_vec; -extern const bfd_target x86_64coff_vec; -extern const bfd_target z80coff_vec; -extern const bfd_target z8kcoff_vec; - -/* These are always included. */ -extern const bfd_target srec_vec; -extern const bfd_target verilog_vec; -extern const bfd_target symbolsrec_vec; -extern const bfd_target tekhex_vec; -extern const bfd_target binary_vec; -extern const bfd_target ihex_vec; - -/* All of the xvecs for core files. */ -extern const bfd_target aix386_core_vec; -extern const bfd_target cisco_core_big_vec; -extern const bfd_target cisco_core_little_vec; -extern const bfd_target hppabsd_core_vec; -extern const bfd_target hpux_core_vec; -extern const bfd_target irix_core_vec; -extern const bfd_target netbsd_core_vec; -extern const bfd_target osf_core_vec; -extern const bfd_target ptrace_core_vec; -extern const bfd_target sco5_core_vec; -extern const bfd_target trad_core_vec; - -extern const bfd_target bfd_elf32_am33lin_vec; -static const bfd_target * const _bfd_target_vector[] = -{ -#ifdef SELECT_VECS - - SELECT_VECS, - -#else /* not SELECT_VECS */ - -#ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, -#endif - /* This list is alphabetized to make it easy to compare - with other vector lists -- the decls above and - the case statement in configure.in. - Vectors that don't compile on all systems, or aren't finished, - should have an entry here with #if 0 around it, to show that - it wasn't omitted by mistake. */ - &a_out_adobe_vec, -#ifdef BFD64 - &aix5coff64_vec, -#endif - &aout0_big_vec, -#if 0 - /* We have no way of distinguishing these from other a.out variants. */ - &aout_arm_big_vec, - &aout_arm_little_vec, - /* No one seems to use this. */ - &aout_mips_big_vec, -#endif - &aout_mips_little_vec, -#if 0 - &apollocoff_vec, -#endif - &arm_epoc_pe_big_vec, - &arm_epoc_pe_little_vec, - &arm_epoc_pei_big_vec, - &arm_epoc_pei_little_vec, - &arm_wince_pe_big_vec, - &arm_wince_pe_little_vec, - &arm_wince_pei_big_vec, - &arm_wince_pei_little_vec, - &armcoff_big_vec, - &armcoff_little_vec, - &armnetbsd_vec, - &armpe_big_vec, - &armpe_little_vec, - &armpei_big_vec, - &armpei_little_vec, - &b_out_vec_big_host, - &b_out_vec_little_host, -#ifdef BFD64 - &bfd_pei_ia64_vec, -#endif - &bfd_elf32_avr_vec, - &bfd_elf32_bfin_vec, - &bfd_elf32_bfinfdpic_vec, - - /* This, and other vectors, may not be used in any *.mt configuration. - But that does not mean they are unnecessary. If configured with - --enable-targets=all, objdump or gdb should be able to examine - the file even if we don't recognize the machine type. */ - &bfd_elf32_big_generic_vec, - &bfd_elf32_bigarc_vec, - &bfd_elf32_bigarm_vec, - &bfd_elf32_bigarm_symbian_vec, - &bfd_elf32_bigarm_vxworks_vec, - &bfd_elf32_bigmips_vec, - &bfd_elf32_bigmips_vxworks_vec, - &bfd_elf32_cr16_vec, - &bfd_elf32_cr16c_vec, - &bfd_elf32_cris_vec, - &bfd_elf32_crx_vec, - &bfd_elf32_d10v_vec, - &bfd_elf32_d30v_vec, - &bfd_elf32_dlx_big_vec, - &bfd_elf32_fr30_vec, - &bfd_elf32_frv_vec, - &bfd_elf32_frvfdpic_vec, - &bfd_elf32_moxie_vec, - &bfd_elf32_h8300_vec, - &bfd_elf32_hppa_linux_vec, - &bfd_elf32_hppa_nbsd_vec, - &bfd_elf32_hppa_vec, - &bfd_elf32_i370_vec, - &bfd_elf32_i386_freebsd_vec, - &bfd_elf32_i386_nacl_vec, - &bfd_elf32_i386_sol2_vec, - &bfd_elf32_i386_vxworks_vec, - &bfd_elf32_i386_vec, - &bfd_elf32_i860_little_vec, - &bfd_elf32_i860_vec, - &bfd_elf32_i960_vec, -#if 0 - &bfd_elf32_ia64_big_vec, -#endif -#ifdef BFD64 - &bfd_elf32_ia64_hpux_big_vec, -#endif - &bfd_elf32_ip2k_vec, - &bfd_elf32_iq2000_vec, - &bfd_elf32_lm32_vec, - &bfd_elf32_little_generic_vec, - &bfd_elf32_littlearc_vec, - &bfd_elf32_littlearm_vec, - &bfd_elf32_littlearm_symbian_vec, - &bfd_elf32_littlearm_vxworks_vec, - &bfd_elf32_littlemips_vec, - &bfd_elf32_littlemips_vxworks_vec, - &bfd_elf32_m32c_vec, - &bfd_elf32_m32r_vec, - &bfd_elf32_m32rle_vec, - &bfd_elf32_m32rlin_vec, - &bfd_elf32_m32rlelin_vec, - &bfd_elf32_m68hc11_vec, - &bfd_elf32_m68hc12_vec, - &bfd_elf32_m68k_vec, - &bfd_elf32_m88k_vec, - &bfd_elf32_mcore_big_vec, - &bfd_elf32_mcore_little_vec, - &bfd_elf32_mep_vec, - &bfd_elf32_microblaze_vec, - &bfd_elf32_mn10200_vec, - &bfd_elf32_mn10300_vec, - &bfd_elf32_mt_vec, - &bfd_elf32_msp430_vec, -#ifdef BFD64 - &bfd_elf32_nbigmips_vec, - &bfd_elf32_nlittlemips_vec, - &bfd_elf32_ntradbigmips_vec, - &bfd_elf32_ntradlittlemips_vec, - &bfd_elf32_ntradbigmips_freebsd_vec, - &bfd_elf32_ntradlittlemips_freebsd_vec, -#endif - &bfd_elf32_openrisc_vec, - &bfd_elf32_or32_big_vec, - &bfd_elf32_pj_vec, - &bfd_elf32_pjl_vec, - &bfd_elf32_powerpc_vec, - &bfd_elf32_powerpc_vxworks_vec, - &bfd_elf32_powerpcle_vec, - &bfd_elf32_rx_be_vec, - &bfd_elf32_rx_be_ns_vec, - &bfd_elf32_rx_le_vec, - &bfd_elf32_s390_vec, -#ifdef BFD64 - &bfd_elf32_bigscore_vec, - &bfd_elf32_littlescore_vec, -#endif - &bfd_elf32_sh_vec, - &bfd_elf32_shbfd_vec, - &bfd_elf32_shblin_vec, - &bfd_elf32_shfd_vec, - &bfd_elf32_shl_vec, - &bfd_elf32_shl_symbian_vec, - &bfd_elf32_shlin_vec, - &bfd_elf32_shlnbsd_vec, - &bfd_elf32_shlvxworks_vec, - &bfd_elf32_shnbsd_vec, - &bfd_elf32_shvxworks_vec, -#ifdef BFD64 - &bfd_elf32_sh64_vec, - &bfd_elf32_sh64l_vec, - &bfd_elf32_sh64lnbsd_vec, - &bfd_elf32_sh64nbsd_vec, - &bfd_elf32_sh64lin_vec, - &bfd_elf32_sh64blin_vec, -#endif - &bfd_elf32_sparc_vec, - &bfd_elf32_sparc_sol2_vec, - &bfd_elf32_sparc_vxworks_vec, - &bfd_elf32_spu_vec, - &bfd_elf32_tic6x_be_vec, - &bfd_elf32_tic6x_le_vec, - &bfd_elf32_tilegx_vec, - &bfd_elf32_tilepro_vec, - &bfd_elf32_tradbigmips_vec, - &bfd_elf32_tradlittlemips_vec, - &bfd_elf32_tradbigmips_freebsd_vec, - &bfd_elf32_tradlittlemips_freebsd_vec, - &bfd_elf32_us_cris_vec, - &bfd_elf32_v850_vec, - &bfd_elf32_vax_vec, - &bfd_elf32_xc16x_vec, - &bfd_elf32_xstormy16_vec, - &bfd_elf32_xtensa_be_vec, - &bfd_elf32_xtensa_le_vec, -#ifdef BFD64 - &bfd_elf64_alpha_freebsd_vec, - &bfd_elf64_alpha_vec, - &bfd_elf64_big_generic_vec, - &bfd_elf64_bigmips_vec, - &bfd_elf64_hppa_linux_vec, - &bfd_elf64_hppa_vec, - &bfd_elf64_ia64_big_vec, - &bfd_elf64_ia64_hpux_big_vec, - &bfd_elf64_ia64_little_vec, - &bfd_elf64_ia64_vms_vec, - &bfd_elf64_little_generic_vec, - &bfd_elf64_littlemips_vec, - &bfd_elf64_mmix_vec, - &bfd_elf64_powerpc_vec, - &bfd_elf64_powerpcle_vec, - &bfd_elf64_s390_vec, - &bfd_elf64_sh64_vec, - &bfd_elf64_sh64l_vec, - &bfd_elf64_sh64lnbsd_vec, - &bfd_elf64_sh64nbsd_vec, - &bfd_elf64_sh64lin_vec, - &bfd_elf64_sh64blin_vec, - &bfd_elf64_sparc_vec, - &bfd_elf64_sparc_freebsd_vec, - &bfd_elf64_sparc_sol2_vec, - &bfd_elf64_tilegx_vec, - &bfd_elf64_tradbigmips_vec, - &bfd_elf64_tradlittlemips_vec, - &bfd_elf64_tradbigmips_freebsd_vec, - &bfd_elf64_tradlittlemips_freebsd_vec, - &bfd_elf64_x86_64_freebsd_vec, - &bfd_elf64_x86_64_sol2_vec, - &bfd_elf64_x86_64_vec, - &bfd_elf32_x86_64_vec, - &bfd_elf64_l1om_freebsd_vec, - &bfd_elf64_l1om_vec, - &bfd_elf64_k1om_freebsd_vec, - &bfd_elf64_k1om_vec, - &bfd_mmo_vec, -#endif - &bfd_powerpc_pe_vec, - &bfd_powerpc_pei_vec, - &bfd_powerpcle_pe_vec, - &bfd_powerpcle_pei_vec, - &cris_aout_vec, -#ifdef BFD64 - &demo_64_vec, /* Only compiled if host has long-long support. */ -#endif - &ecoff_big_vec, - &ecoff_biglittle_vec, - &ecoff_little_vec, -#ifdef BFD64 - &ecoffalpha_little_vec, -#endif - &go32coff_vec, - &go32stubbedcoff_vec, - &h8300coff_vec, - &h8500coff_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &host_aout_vec, - /* Clashes with sunos_big_vec magic no. */ - &hp300bsd_vec, -#endif - &hp300hpux_vec, - &i386aout_vec, - &i386bsd_vec, - &i386coff_vec, -#if 0 - &i386dynix_vec, -#endif - &i386freebsd_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &i386linux_vec, -#endif - &i386lynx_aout_vec, - &i386lynx_coff_vec, -#if 0 - /* No distinguishing features for Mach 3 executables. */ - &i386mach3_vec, -#endif - &i386msdos_vec, - &i386netbsd_vec, - &i386os9k_vec, - &i386pe_vec, - &i386pei_vec, -#ifdef BFD64 - &x86_64coff_vec, - &x86_64pe_vec, - &x86_64pei_vec, -#endif - &i860coff_vec, - &icoff_big_vec, - &icoff_little_vec, - &ieee_vec, -#if 0 - &m68k4knetbsd_vec, - &m68kaux_coff_vec, -#endif - &m68kcoff_vec, - &m68kcoffun_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &m68klinux_vec, -#endif - &m68knetbsd_vec, - &m68ksysvcoff_vec, - &m88kbcs_vec, - &m88kmach3_vec, - &m88kopenbsd_vec, - &mach_o_be_vec, - &mach_o_le_vec, - &mach_o_fat_vec, - &mach_o_i386_vec, -#ifdef BFD64 - &mach_o_x86_64_vec, -#endif - &mcore_pe_big_vec, - &mcore_pe_little_vec, - &mcore_pei_big_vec, - &mcore_pei_little_vec, - &mipslpe_vec, - &mipslpei_vec, - &newsos3_vec, -#ifdef BFD64 - &nlm32_alpha_vec, -#endif - &nlm32_i386_vec, - &nlm32_powerpc_vec, - &nlm32_sparc_vec, -#if 0 - /* We have no oasys tools anymore, so we can't test any of this - anymore. If you want to test the stuff yourself, go ahead... - steve@cygnus.com - Worse, since there is no magic number for archives, there - can be annoying target mis-matches. */ - &oasys_vec, -#endif - /* Entry for the OpenRISC family. */ - &or32coff_big_vec, - - &pc532machaout_vec, - &pc532netbsd_vec, - &pdp11_aout_vec, - &pef_vec, - &pef_xlib_vec, -#if BFD_SUPPORTS_PLUGINS - &plugin_vec, -#endif -#if 0 - /* This has the same magic number as RS/6000. */ - &pmac_xcoff_vec, -#endif - &ppcboot_vec, -#if 0 - /* We have no way of distinguishing these from other a.out variants. */ - &riscix_vec, -#endif -#ifdef BFD64 - &rs6000coff64_vec, -#endif - &rs6000coff_vec, - &shcoff_small_vec, - &shcoff_vec, - &shlcoff_small_vec, - &shlcoff_vec, - &shlpe_vec, - &shlpei_vec, - &som_vec, - &sparccoff_vec, - &sparcle_aout_vec, - &sparclinux_vec, - &sparclynx_aout_vec, - &sparclynx_coff_vec, - &sparcnetbsd_vec, - &sunos_big_vec, - &sym_vec, - &tic30_aout_vec, - &tic30_coff_vec, - &tic54x_coff0_beh_vec, - &tic54x_coff0_vec, - &tic54x_coff1_beh_vec, - &tic54x_coff1_vec, - &tic54x_coff2_beh_vec, - &tic54x_coff2_vec, - &tic80coff_vec, - &vaxbsd_vec, - &vaxnetbsd_vec, - &vax1knetbsd_vec, - &versados_vec, -#ifdef BFD64 - &vms_alpha_vec, -#endif - &vms_lib_txt_vec, - &w65_vec, - &we32kcoff_vec, - &z80coff_vec, - &z8kcoff_vec, - &bfd_elf32_am33lin_vec, -#endif /* not SELECT_VECS */ - -/* Always support S-records, for convenience. */ - &srec_vec, - &symbolsrec_vec, -/* And verilog. */ - &verilog_vec, -/* And tekhex */ - &tekhex_vec, -/* Likewise for binary output. */ - &binary_vec, -/* Likewise for ihex. */ - &ihex_vec, - -/* Add any required traditional-core-file-handler. */ - -#ifdef AIX386_CORE - &aix386_core_vec, -#endif -#if 0 - /* We don't include cisco_core_*_vec. Although it has a magic number, - the magic number isn't at the beginning of the file, and thus - might spuriously match other kinds of files. */ - &cisco_core_big_vec, - &cisco_core_little_vec, -#endif -#ifdef HPPABSD_CORE - &hppabsd_core_vec, -#endif -#ifdef HPUX_CORE - &hpux_core_vec, -#endif -#ifdef IRIX_CORE - &irix_core_vec, -#endif -#ifdef NETBSD_CORE - &netbsd_core_vec, -#endif -#ifdef OSF_CORE - &osf_core_vec, -#endif -#ifdef PTRACE_CORE - &ptrace_core_vec, -#endif -#ifdef SCO5_CORE - &sco5_core_vec, -#endif -#ifdef TRAD_CORE - &trad_core_vec, -#endif - - NULL /* end of list marker */ -}; -const bfd_target * const *bfd_target_vector = _bfd_target_vector; - -/* bfd_default_vector[0] contains either the address of the default vector, - if there is one, or zero if there isn't. */ - -const bfd_target *bfd_default_vector[] = { -#ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, -#endif - NULL -}; - -/* bfd_associated_vector[] contains the associated target vectors used - to reduce the ambiguity in bfd_check_format_matches. */ - -static const bfd_target *_bfd_associated_vector[] = { -#ifdef ASSOCIATED_VECS - ASSOCIATED_VECS, -#endif - NULL -}; -const bfd_target * const *bfd_associated_vector = _bfd_associated_vector; - -/* When there is an ambiguous match, bfd_check_format_matches puts the - names of the matching targets in an array. This variable is the maximum - number of entries that the array could possibly need. */ -const size_t _bfd_target_vector_entries = sizeof (_bfd_target_vector)/sizeof (*_bfd_target_vector); - -/* This array maps configuration triplets onto BFD vectors. */ - -struct targmatch -{ - /* The configuration triplet. */ - const char *triplet; - /* The BFD vector. If this is NULL, then the vector is found by - searching forward for the next structure with a non NULL vector - field. */ - const bfd_target *vector; -}; - -/* targmatch.h is built by Makefile out of config.bfd. */ -static const struct targmatch bfd_target_match[] = { -#include "targmatch.h" - { NULL, NULL } -}; - -/* Find a target vector, given a name or configuration triplet. */ - -static const bfd_target * -find_target (const char *name) -{ - const bfd_target * const *target; - const struct targmatch *match; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - if (strcmp (name, (*target)->name) == 0) - return *target; - - /* If we couldn't match on the exact name, try matching on the - configuration triplet. FIXME: We should run the triplet through - config.sub first, but that is hard. */ - for (match = &bfd_target_match[0]; match->triplet != NULL; match++) - { - if (fnmatch (match->triplet, name, 0) == 0) - { - while (match->vector == NULL) - ++match; - return match->vector; - } - } - - bfd_set_error (bfd_error_invalid_target); - return NULL; -} - -/* -FUNCTION - bfd_set_default_target - -SYNOPSIS - bfd_boolean bfd_set_default_target (const char *name); - -DESCRIPTION - Set the default target vector to use when recognizing a BFD. - This takes the name of the target, which may be a BFD target - name or a configuration triplet. -*/ - -bfd_boolean -bfd_set_default_target (const char *name) -{ - const bfd_target *target; - - if (bfd_default_vector[0] != NULL - && strcmp (name, bfd_default_vector[0]->name) == 0) - return TRUE; - - target = find_target (name); - if (target == NULL) - return FALSE; - - bfd_default_vector[0] = target; - return TRUE; -} - -/* -FUNCTION - bfd_find_target - -SYNOPSIS - const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); - -DESCRIPTION - Return a pointer to the transfer vector for the object target - named @var{target_name}. If @var{target_name} is <>, - choose the one in the environment variable <>; if - that is null or not defined, then choose the first entry in the - target list. Passing in the string "default" or setting the - environment variable to "default" will cause the first entry in - the target list to be returned, and "target_defaulted" will be - set in the BFD if @var{abfd} isn't <>. This causes - <> to loop over all the targets to find the - one that matches the file being read. -*/ - -const bfd_target * -bfd_find_target (const char *target_name, bfd *abfd) -{ - const char *targname; - const bfd_target *target; - - if (target_name != NULL) - targname = target_name; - else - targname = getenv ("GNUTARGET"); - - /* This is safe; the vector cannot be null. */ - if (targname == NULL || strcmp (targname, "default") == 0) - { - if (bfd_default_vector[0] != NULL) - target = bfd_default_vector[0]; - else - target = bfd_target_vector[0]; - if (abfd) - { - abfd->xvec = target; - abfd->target_defaulted = TRUE; - } - return target; - } - - if (abfd) - abfd->target_defaulted = FALSE; - - target = find_target (targname); - if (target == NULL) - return NULL; - - if (abfd) - abfd->xvec = target; - return target; -} - -/* Helper function for bfd_get_target_info to determine the target's - architecture. This method handles bfd internal target names as - tuples and triplets. */ -static bfd_boolean -_bfd_find_arch_match (const char *tname, const char **arch, - const char **def_target_arch) -{ - if (!arch) - return FALSE; - - while (*arch != NULL) - { - const char *in_a = strstr (*arch, tname); - char end_ch = (in_a ? in_a[strlen (tname)] : 0); - - if (in_a && (in_a == *arch || in_a[-1] == ':') - && end_ch == 0) - { - *def_target_arch = *arch; - return TRUE; - } - arch++; - } - return FALSE; -} - -/* -FUNCTION - bfd_get_target_info -SYNOPSIS - const bfd_target *bfd_get_target_info (const char *target_name, - bfd *abfd, - bfd_boolean *is_bigendian, - int *underscoring, - const char **def_target_arch); -DESCRIPTION - Return a pointer to the transfer vector for the object target - named @var{target_name}. If @var{target_name} is <>, - choose the one in the environment variable <>; if - that is null or not defined, then choose the first entry in the - target list. Passing in the string "default" or setting the - environment variable to "default" will cause the first entry in - the target list to be returned, and "target_defaulted" will be - set in the BFD if @var{abfd} isn't <>. This causes - <> to loop over all the targets to find the - one that matches the file being read. - If @var{is_bigendian} is not <>, then set this value to target's - endian mode. True for big-endian, FALSE for little-endian or for - invalid target. - If @var{underscoring} is not <>, then set this value to target's - underscoring mode. Zero for none-underscoring, -1 for invalid target, - else the value of target vector's symbol underscoring. - If @var{def_target_arch} is not <>, then set it to the architecture - string specified by the target_name. -*/ -const bfd_target * -bfd_get_target_info (const char *target_name, bfd *abfd, - bfd_boolean *is_bigendian, - int *underscoring, const char **def_target_arch) -{ - const bfd_target *target_vec; - - if (is_bigendian) - *is_bigendian = FALSE; - if (underscoring) - *underscoring = -1; - if (def_target_arch) - *def_target_arch = NULL; - target_vec = bfd_find_target (target_name, abfd); - if (! target_vec) - return NULL; - if (is_bigendian) - *is_bigendian = ((target_vec->byteorder == BFD_ENDIAN_BIG) ? TRUE - : FALSE); - if (underscoring) - *underscoring = ((int) target_vec->symbol_leading_char) & 0xff; - - if (def_target_arch) - { - const char *tname = target_vec->name; - const char **arches = bfd_arch_list (); - - if (arches && tname) - { - char *hyp = strchr (tname, '-'); - - if (hyp != NULL) - { - tname = ++hyp; - - /* Make sure we detect architecture names - for triplets like "pe-arm-wince-little". */ - if (!_bfd_find_arch_match (tname, arches, def_target_arch)) - { - char new_tname[50]; - - strcpy (new_tname, hyp); - while ((hyp = strrchr (new_tname, '-')) != NULL) - { - *hyp = 0; - if (_bfd_find_arch_match (new_tname, arches, - def_target_arch)) - break; - } - } - } - else - _bfd_find_arch_match (tname, arches, def_target_arch); - } - - if (arches) - free (arches); - } - return target_vec; -} - -/* -FUNCTION - bfd_target_list - -SYNOPSIS - const char ** bfd_target_list (void); - -DESCRIPTION - Return a freshly malloced NULL-terminated - vector of the names of all the valid BFD targets. Do not - modify the names. - -*/ - -const char ** -bfd_target_list (void) -{ - int vec_length = 0; - bfd_size_type amt; - const bfd_target * const *target; - const char **name_list, **name_ptr; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - vec_length++; - - amt = (vec_length + 1) * sizeof (char **); - name_ptr = name_list = (const char **) bfd_malloc (amt); - - if (name_list == NULL) - return NULL; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - if (target == &bfd_target_vector[0] - || *target != bfd_target_vector[0]) - *name_ptr++ = (*target)->name; - - *name_ptr = NULL; - return name_list; -} - -/* -FUNCTION - bfd_seach_for_target - -SYNOPSIS - const bfd_target *bfd_search_for_target - (int (*search_func) (const bfd_target *, void *), - void *); - -DESCRIPTION - Return a pointer to the first transfer vector in the list of - transfer vectors maintained by BFD that produces a non-zero - result when passed to the function @var{search_func}. The - parameter @var{data} is passed, unexamined, to the search - function. -*/ - -const bfd_target * -bfd_search_for_target (int (*search_func) (const bfd_target *, void *), - void *data) -{ - const bfd_target * const *target; - - for (target = bfd_target_vector; *target != NULL; target ++) - if (search_func (*target, data)) - return *target; - - return NULL; -} diff --git a/contrib/binutils-2.22/bfd/targmatch.sed b/contrib/binutils-2.22/bfd/targmatch.sed deleted file mode 100644 index 2716876547..0000000000 --- a/contrib/binutils-2.22/bfd/targmatch.sed +++ /dev/null @@ -1,33 +0,0 @@ -1,/START OF targmatch.h/ d -/END OF targmatch.h/,$ d -/^[ ]*case/,/^[ ]*esac/ d -s/^#if/KEEP #if/ -s/^#endif/KEEP #endif/ -s/^[ ]*#.*$// -s/^KEEP #/#/ -s/[ ]*\\$// -t lab1 - :lab1 -s/[| ][| ]*\([^|() ][^|() ]*\)[ ]*|/{ "\1", NULL },/g -s/[| ][| ]*\([^|() ][^|() ]*\)[ ]*)/{ "\1",/g -t lab2 -s/^[ ]*targ_defvec=\([^ ]*\)/#if !defined (SELECT_VECS) || defined (HAVE_\1)/ -t lab3 -s/.*=.*// -s/;;// -b - :lab2 -H -d - :lab3 -G -s/\n/%EOL%/g -s/\(defined (HAVE_\)\([^)]*\)\(.*\)/\1\2\3\ -\&\2 },\ -#endif/ -s/%EOL%/\ -/g -p -s/.*//g -s/\n//g -h diff --git a/contrib/binutils-2.22/bfd/tekhex.c b/contrib/binutils-2.22/bfd/tekhex.c deleted file mode 100644 index 0ed7b5032b..0000000000 --- a/contrib/binutils-2.22/bfd/tekhex.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* BFD backend for Extended Tektronix Hex Format objects. - Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2009, 2011 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support . - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* SUBSECTION - Tektronix Hex Format handling - - DESCRIPTION - - Tek Hex records can hold symbols and data, but not - relocations. Their main application is communication with - devices like PROM programmers and ICE equipment. - - It seems that the sections are described as being really big, - the example I have says that the text section is 0..ffffffff. - BFD would barf with this, many apps would try to alloc 4GB to - read in the file. - - Tex Hex may contain many sections, but the data which comes in - has no tag saying which section it belongs to, so we create - one section for each block of data, called "blknnnn" which we - stick all the data into. - - TekHex may come out of order and there is no header, so an - initial scan is required to discover the minimum and maximum - addresses used to create the vma and size of the sections we - create. - We read in the data into pages of CHUNK_MASK+1 size and read - them out from that whenever we need to. - - Any number of sections may be created for output, we save them - up and output them when it's time to close the bfd. - - A TekHex record looks like: - EXAMPLE - % - - DESCRIPTION - Where - o length - is the number of bytes in the record not including the % sign. - o type - is one of: - 3) symbol record - 6) data record - 8) termination record - - The data can come out of order, and may be discontigous. This is a - serial protocol, so big files are unlikely, so we keep a list of 8k chunks. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "libiberty.h" - -typedef struct -{ - bfd_vma low; - bfd_vma high; -} addr_range_type; - -typedef struct tekhex_symbol_struct -{ - asymbol symbol; - struct tekhex_symbol_struct *prev; -} tekhex_symbol_type; - -static const char digs[] = "0123456789ABCDEF"; - -static char sum_block[256]; - -#define NOT_HEX 20 -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1])) -#define ISHEX(x) hex_p(x) -#define TOHEX(d, x) \ - (d)[1] = digs[(x) & 0xf]; \ - (d)[0] = digs[((x)>>4)&0xf]; - -/* Here's an example - %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75 - %1B3709T_SEGMENT1108FFFFFFFF - %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10 - %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710 - %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10 - %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10 - %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10 - %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10 - %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010 - %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10 - %2734D9T_SEGMENT8Bvoid$t15$151035_main10 - %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110 - %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214 - %07 8 10 10 - - explanation: - %3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75 - ^ ^^ ^ ^-data - | || +------ 4 char integer 0x8000 - | |+-------- checksum - | +--------- type 6 (data record) - +----------- length 3a chars - <---------------------- 3a (58 chars) -------------------> - - %1B3709T_SEGMENT1108FFFFFFFF - ^ ^^ ^- 8 character integer 0xffffffff - | |+- 1 character integer 0 - | +-- type 1 symbol (section definition) - +------------ 9 char symbol T_SEGMENT - - %2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10 - %373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710 - %373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10 - %373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10 - %373049T_SEGMENT80long$long$int$t71080short$unsigned$i10 - %373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10 - %373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010 - %373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10 - %2734D9T_SEGMENT8Bvoid$t15$151035_main10 - %2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110 - %2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214 - %0781010 - - Turns into - sac@thepub$ ./objdump -dx -m m68k f - - f: file format tekhex - -----x--- 9/55728 -134219416 Sep 29 15:13 1995 f - architecture: UNKNOWN!, flags 0x00000010: - HAS_SYMS - start address 0x00000000 - SECTION 0 [D00000000] : size 00020000 vma 00000000 align 2**0 - ALLOC, LOAD - SECTION 1 [D00008000] : size 00002001 vma 00008000 align 2**0 - - SECTION 2 [T_SEGMENT] : size ffffffff vma 00000000 align 2**0 - - SYMBOL TABLE: - 00000000 g T_SEGMENT gcc_compiled$ - 00000000 g T_SEGMENT hello$c - 00000000 g T_SEGMENT int$t1$r1$$21474 - 00000000 g T_SEGMENT char$t2$r2$0$127 - 00000000 g T_SEGMENT long$int$t3$r1$$ - 00000000 g T_SEGMENT unsigned$int$t4$ - 00000000 g T_SEGMENT long$unsigned$in - 00000000 g T_SEGMENT short$int$t6$r1$ - 00000000 g T_SEGMENT long$long$int$t7 - 00000000 g T_SEGMENT short$unsigned$i - 00000000 g T_SEGMENT long$long$unsign - 00000000 g T_SEGMENT signed$char$t10$ - 00000000 g T_SEGMENT unsigned$char$t1 - 00000000 g T_SEGMENT float$t12$r1$4$0 - 00000000 g T_SEGMENT double$t13$r1$8$ - 00000000 g T_SEGMENT long$double$t14$ - 00000000 g T_SEGMENT void$t15$15 - 00000000 g T_SEGMENT _main - 00000000 g T_SEGMENT $ - 00000000 g T_SEGMENT $ - 00000000 g T_SEGMENT $ - 00000010 g T_SEGMENT $ - 00000000 g T_SEGMENT main$F1 - fcffffff g T_SEGMENT i$1 - 00000000 g T_SEGMENT $ - 00000010 g T_SEGMENT $ - - RELOCATION RECORDS FOR [D00000000]: (none) - - RELOCATION RECORDS FOR [D00008000]: (none) - - RELOCATION RECORDS FOR [T_SEGMENT]: (none) - - Disassembly of section D00000000: - ... - 00008000 ($+)7ff0 linkw fp,#-4 - 00008004 ($+)7ff4 nop - 00008006 ($+)7ff6 movel #99,d0 - 00008008 ($+)7ff8 cmpl fp@(-4),d0 - 0000800c ($+)7ffc blts 00008014 ($+)8004 - 0000800e ($+)7ffe addql #1,fp@(-4) - 00008012 ($+)8002 bras 00008006 ($+)7ff6 - 00008014 ($+)8004 unlk fp - 00008016 ($+)8006 rts - ... */ - -static void -tekhex_init (void) -{ - unsigned int i; - static bfd_boolean inited = FALSE; - int val; - - if (! inited) - { - inited = TRUE; - hex_init (); - val = 0; - for (i = 0; i < 10; i++) - sum_block[i + '0'] = val++; - - for (i = 'A'; i <= 'Z'; i++) - sum_block[i] = val++; - - sum_block['$'] = val++; - sum_block['%'] = val++; - sum_block['.'] = val++; - sum_block['_'] = val++; - for (i = 'a'; i <= 'z'; i++) - sum_block[i] = val++; - } -} - -/* The maximum number of bytes on a line is FF. */ -#define MAXCHUNK 0xff -/* The number of bytes we fit onto a line on output. */ -#define CHUNK 21 - -/* We cannot output our tekhexords as we see them, we have to glue them - together, this is done in this structure : */ - -struct tekhex_data_list_struct -{ - unsigned char *data; - bfd_vma where; - bfd_size_type size; - struct tekhex_data_list_struct *next; - -}; -typedef struct tekhex_data_list_struct tekhex_data_list_type; - -#define CHUNK_MASK 0x1fff - -struct data_struct -{ - char chunk_data[CHUNK_MASK + 1]; - char chunk_init[CHUNK_MASK + 1]; - bfd_vma vma; - struct data_struct *next; -}; - -typedef struct tekhex_data_struct -{ - tekhex_data_list_type *head; - unsigned int type; - struct tekhex_symbol_struct *symbols; - struct data_struct *data; -} tdata_type; - -#define enda(x) (x->vma + x->size) - -static bfd_boolean -getvalue (char **srcp, bfd_vma *valuep) -{ - char *src = *srcp; - bfd_vma value = 0; - unsigned int len; - - if (!ISHEX (*src)) - return FALSE; - - len = hex_value (*src++); - if (len == 0) - len = 16; - while (len--) - { - if (!ISHEX (*src)) - return FALSE; - value = value << 4 | hex_value (*src++); - } - - *srcp = src; - *valuep = value; - return TRUE; -} - -static bfd_boolean -getsym (char *dstp, char **srcp, unsigned int *lenp) -{ - char *src = *srcp; - unsigned int i; - unsigned int len; - - if (!ISHEX (*src)) - return FALSE; - - len = hex_value (*src++); - if (len == 0) - len = 16; - for (i = 0; i < len; i++) - dstp[i] = src[i]; - dstp[i] = 0; - *srcp = src + i; - *lenp = len; - return TRUE; -} - -static struct data_struct * -find_chunk (bfd *abfd, bfd_vma vma) -{ - struct data_struct *d = abfd->tdata.tekhex_data->data; - - vma &= ~CHUNK_MASK; - while (d && (d->vma) != vma) - d = d->next; - - if (!d) - { - /* No chunk for this address, so make one up. */ - d = (struct data_struct *) - bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct)); - - if (!d) - return NULL; - - d->next = abfd->tdata.tekhex_data->data; - d->vma = vma; - abfd->tdata.tekhex_data->data = d; - } - return d; -} - -static void -insert_byte (bfd *abfd, int value, bfd_vma addr) -{ - /* Find the chunk that this byte needs and put it in. */ - struct data_struct *d = find_chunk (abfd, addr); - - d->chunk_data[addr & CHUNK_MASK] = value; - d->chunk_init[addr & CHUNK_MASK] = 1; -} - -/* The first pass is to find the names of all the sections, and see - how big the data is. */ - -static bfd_boolean -first_phase (bfd *abfd, int type, char *src) -{ - asection *section = bfd_abs_section_ptr; - unsigned int len; - bfd_vma val; - char sym[17]; /* A symbol can only be 16chars long. */ - - switch (type) - { - case '6': - /* Data record - read it and store it. */ - { - bfd_vma addr; - - if (!getvalue (&src, &addr)) - return FALSE; - - while (*src) - { - insert_byte (abfd, HEX (src), addr); - src += 2; - addr++; - } - } - - return TRUE; - case '3': - /* Symbol record, read the segment. */ - if (!getsym (sym, &src, &len)) - return FALSE; - section = bfd_get_section_by_name (abfd, sym); - if (section == NULL) - { - char *n = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1); - - if (!n) - return FALSE; - memcpy (n, sym, len + 1); - section = bfd_make_section (abfd, n); - if (section == NULL) - return FALSE; - } - while (*src) - { - switch (*src) - { - case '1': /* Section range. */ - src++; - if (!getvalue (&src, §ion->vma)) - return FALSE; - if (!getvalue (&src, &val)) - return FALSE; - section->size = val - section->vma; - section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - break; - case '0': - case '2': - case '3': - case '4': - case '6': - case '7': - case '8': - /* Symbols, add to section. */ - { - bfd_size_type amt = sizeof (tekhex_symbol_type); - tekhex_symbol_type *new_symbol = (tekhex_symbol_type *) - bfd_alloc (abfd, amt); - char stype = (*src); - - if (!new_symbol) - return FALSE; - new_symbol->symbol.the_bfd = abfd; - src++; - abfd->symcount++; - abfd->flags |= HAS_SYMS; - new_symbol->prev = abfd->tdata.tekhex_data->symbols; - abfd->tdata.tekhex_data->symbols = new_symbol; - if (!getsym (sym, &src, &len)) - return FALSE; - new_symbol->symbol.name = (const char *) - bfd_alloc (abfd, (bfd_size_type) len + 1); - if (!new_symbol->symbol.name) - return FALSE; - memcpy ((char *) (new_symbol->symbol.name), sym, len + 1); - new_symbol->symbol.section = section; - if (stype <= '4') - new_symbol->symbol.flags = (BSF_GLOBAL | BSF_EXPORT); - else - new_symbol->symbol.flags = BSF_LOCAL; - if (!getvalue (&src, &val)) - return FALSE; - new_symbol->symbol.value = val - section->vma; - break; - } - default: - return FALSE; - } - } - } - - return TRUE; -} - -/* Pass over a tekhex, calling one of the above functions on each - record. */ - -static bfd_boolean -pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *)) -{ - unsigned int chars_on_line; - bfd_boolean is_eof = FALSE; - - /* To the front of the file. */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return FALSE; - while (! is_eof) - { - char src[MAXCHUNK]; - char type; - - /* Find first '%'. */ - is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); - while (*src != '%' && !is_eof) - is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); - - if (is_eof) - break; - - /* Fetch the type and the length and the checksum. */ - if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5) - return FALSE; - - type = src[2]; - - if (!ISHEX (src[0]) || !ISHEX (src[1])) - break; - - /* Already read five chars. */ - chars_on_line = HEX (src) - 5; - - if (chars_on_line >= MAXCHUNK) - return FALSE; - - if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line) - return FALSE; - - /* Put a null at the end. */ - src[chars_on_line] = 0; - - if (!func (abfd, type, src)) - return FALSE; - } - - return TRUE; -} - -static long -tekhex_canonicalize_symtab (bfd *abfd, asymbol **table) -{ - tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols; - unsigned int c = bfd_get_symcount (abfd); - - table[c] = 0; - while (p) - { - table[--c] = &(p->symbol); - p = p->prev; - } - - return bfd_get_symcount (abfd); -} - -static long -tekhex_get_symtab_upper_bound (bfd *abfd) -{ - return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *)); - -} - -static bfd_boolean -tekhex_mkobject (bfd *abfd) -{ - tdata_type *tdata; - - tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type)); - if (!tdata) - return FALSE; - abfd->tdata.tekhex_data = tdata; - tdata->type = 1; - tdata->head = NULL; - tdata->symbols = NULL; - tdata->data = NULL; - return TRUE; -} - -/* Return TRUE if the file looks like it's in TekHex format. Just look - for a percent sign and some hex digits. */ - -static const bfd_target * -tekhex_object_p (bfd *abfd) -{ - char b[4]; - - tekhex_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_bread (b, (bfd_size_type) 4, abfd) != 4) - return NULL; - - if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - return NULL; - - tekhex_mkobject (abfd); - - if (!pass_over (abfd, first_phase)) - return NULL; - - return abfd->xvec; -} - -static void -move_section_contents (bfd *abfd, - asection *section, - const void * locationp, - file_ptr offset, - bfd_size_type count, - bfd_boolean get) -{ - bfd_vma addr; - char *location = (char *) locationp; - bfd_vma prev_number = 1; /* Nothing can have this as a high bit. */ - struct data_struct *d = NULL; - - BFD_ASSERT (offset == 0); - for (addr = section->vma; count != 0; count--, addr++) - { - /* Get high bits of address. */ - bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK; - bfd_vma low_bits = addr & CHUNK_MASK; - - if (chunk_number != prev_number) - /* Different chunk, so move pointer. */ - d = find_chunk (abfd, chunk_number); - - if (get) - { - if (d->chunk_init[low_bits]) - *location = d->chunk_data[low_bits]; - else - *location = 0; - } - else - { - d->chunk_data[low_bits] = *location; - d->chunk_init[low_bits] = (*location != 0); - } - - location++; - } -} - -static bfd_boolean -tekhex_get_section_contents (bfd *abfd, - asection *section, - void * locationp, - file_ptr offset, - bfd_size_type count) -{ - if (section->flags & (SEC_LOAD | SEC_ALLOC)) - { - move_section_contents (abfd, section, locationp, offset, count, TRUE); - return TRUE; - } - - return FALSE; -} - -static bfd_boolean -tekhex_set_arch_mach (bfd *abfd, - enum bfd_architecture arch, - unsigned long machine) -{ - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -/* We have to save up all the Tekhexords for a splurge before output. */ - -static bfd_boolean -tekhex_set_section_contents (bfd *abfd, - sec_ptr section, - const void * locationp, - file_ptr offset, - bfd_size_type bytes_to_do) -{ - if (! abfd->output_has_begun) - { - /* The first time around, allocate enough sections to hold all the chunks. */ - asection *s = abfd->sections; - bfd_vma vma; - - for (s = abfd->sections; s; s = s->next) - { - if (s->flags & SEC_LOAD) - { - for (vma = s->vma & ~(bfd_vma) CHUNK_MASK; - vma < s->vma + s->size; - vma += CHUNK_MASK) - find_chunk (abfd, vma); - } - } - } - - if (section->flags & (SEC_LOAD | SEC_ALLOC)) - { - move_section_contents (abfd, section, locationp, offset, bytes_to_do, - FALSE); - return TRUE; - } - - return FALSE; -} - -static void -writevalue (char **dst, bfd_vma value) -{ - char *p = *dst; - int len; - int shift; - - for (len = 8, shift = 28; shift; shift -= 4, len--) - { - if ((value >> shift) & 0xf) - { - *p++ = len + '0'; - while (len) - { - *p++ = digs[(value >> shift) & 0xf]; - shift -= 4; - len--; - } - *dst = p; - return; - - } - } - *p++ = '1'; - *p++ = '0'; - *dst = p; -} - -static void -writesym (char **dst, const char *sym) -{ - char *p = *dst; - int len = (sym ? strlen (sym) : 0); - - if (len >= 16) - { - *p++ = '0'; - len = 16; - } - else - { - if (len == 0) - { - *p++ = '1'; - sym = "$"; - len = 1; - } - else - *p++ = digs[len]; - } - - while (len--) - *p++ = *sym++; - - *dst = p; -} - -static void -out (bfd *abfd, int type, char *start, char *end) -{ - int sum = 0; - char *s; - char front[6]; - bfd_size_type wrlen; - - front[0] = '%'; - TOHEX (front + 1, end - start + 5); - front[3] = type; - - for (s = start; s < end; s++) - sum += sum_block[(unsigned char) *s]; - - sum += sum_block[(unsigned char) front[1]]; /* Length. */ - sum += sum_block[(unsigned char) front[2]]; - sum += sum_block[(unsigned char) front[3]]; /* Type. */ - TOHEX (front + 4, sum); - if (bfd_bwrite (front, (bfd_size_type) 6, abfd) != 6) - abort (); - end[0] = '\n'; - wrlen = end - start + 1; - if (bfd_bwrite (start, wrlen, abfd) != wrlen) - abort (); -} - -static bfd_boolean -tekhex_write_object_contents (bfd *abfd) -{ - char buffer[100]; - asymbol **p; - asection *s; - struct data_struct *d; - - tekhex_init (); - - /* And the raw data. */ - for (d = abfd->tdata.tekhex_data->data; - d != NULL; - d = d->next) - { - int low; - - const int span = 32; - int addr; - - /* Write it in blocks of 32 bytes. */ - for (addr = 0; addr < CHUNK_MASK + 1; addr += span) - { - int need = 0; - - /* Check to see if necessary. */ - for (low = 0; !need && low < span; low++) - if (d->chunk_init[addr + low]) - need = 1; - - if (need) - { - char *dst = buffer; - - writevalue (&dst, addr + d->vma); - for (low = 0; low < span; low++) - { - TOHEX (dst, d->chunk_data[addr + low]); - dst += 2; - } - out (abfd, '6', buffer, dst); - } - } - } - - /* Write all the section headers for the sections. */ - for (s = abfd->sections; s != NULL; s = s->next) - { - char *dst = buffer; - - writesym (&dst, s->name); - *dst++ = '1'; - writevalue (&dst, s->vma); - writevalue (&dst, s->vma + s->size); - out (abfd, '3', buffer, dst); - } - - /* And the symbols. */ - if (abfd->outsymbols) - { - for (p = abfd->outsymbols; *p; p++) - { - int section_code = bfd_decode_symclass (*p); - - if (section_code != '?') - { - /* Do not include debug symbols. */ - asymbol *sym = *p; - char *dst = buffer; - - writesym (&dst, sym->section->name); - - switch (section_code) - { - case 'A': - *dst++ = '2'; - break; - case 'a': - *dst++ = '6'; - break; - case 'D': - case 'B': - case 'O': - *dst++ = '4'; - break; - case 'd': - case 'b': - case 'o': - *dst++ = '8'; - break; - case 'T': - *dst++ = '3'; - break; - case 't': - *dst++ = '7'; - break; - case 'C': - case 'U': - bfd_set_error (bfd_error_wrong_format); - return FALSE; - } - - writesym (&dst, sym->name); - writevalue (&dst, sym->value + sym->section->vma); - out (abfd, '3', buffer, dst); - } - } - } - - /* And the terminator. */ - if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9) - abort (); - return TRUE; -} - -static int -tekhex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, - struct bfd_link_info *info ATTRIBUTE_UNUSED) -{ - return 0; -} - -static asymbol * -tekhex_make_empty_symbol (bfd *abfd) -{ - bfd_size_type amt = sizeof (struct tekhex_symbol_struct); - tekhex_symbol_type *new_symbol = (tekhex_symbol_type *) bfd_zalloc (abfd, - amt); - - if (!new_symbol) - return NULL; - new_symbol->symbol.the_bfd = abfd; - new_symbol->prev = NULL; - return &(new_symbol->symbol); -} - -static void -tekhex_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, - asymbol *symbol, - symbol_info *ret) -{ - bfd_symbol_info (symbol, ret); -} - -static void -tekhex_print_symbol (bfd *abfd, - void * filep, - asymbol *symbol, - bfd_print_symbol_type how) -{ - FILE *file = (FILE *) filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - break; - - case bfd_print_symbol_all: - { - const char *section_name = symbol->section->name; - - bfd_print_symbol_vandf (abfd, (void *) file, symbol); - - fprintf (file, " %-5s %s", - section_name, symbol->name); - } - } -} - -#define tekhex_close_and_cleanup _bfd_generic_close_and_cleanup -#define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define tekhex_new_section_hook _bfd_generic_new_section_hook -#define tekhex_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name -#define tekhex_get_lineno _bfd_nosymbols_get_lineno -#define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line -#define tekhex_find_inliner_info _bfd_nosymbols_find_inliner_info -#define tekhex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define tekhex_read_minisymbols _bfd_generic_read_minisymbols -#define tekhex_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define tekhex_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define tekhex_bfd_relax_section bfd_generic_relax_section -#define tekhex_bfd_gc_sections bfd_generic_gc_sections -#define tekhex_bfd_lookup_section_flags bfd_generic_lookup_section_flags -#define tekhex_bfd_merge_sections bfd_generic_merge_sections -#define tekhex_bfd_is_group_section bfd_generic_is_group_section -#define tekhex_bfd_discard_group bfd_generic_discard_group -#define tekhex_section_already_linked _bfd_generic_section_already_linked -#define tekhex_bfd_define_common_symbol bfd_generic_define_common_symbol -#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define tekhex_bfd_link_just_syms _bfd_generic_link_just_syms -#define tekhex_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -#define tekhex_bfd_final_link _bfd_generic_final_link -#define tekhex_bfd_link_split_section _bfd_generic_link_split_section -#define tekhex_get_section_contents_in_window _bfd_generic_get_section_contents_in_window - -const bfd_target tekhex_vec = -{ - "tekhex", /* Name. */ - bfd_target_tekhex_flavour, - BFD_ENDIAN_UNKNOWN, /* Target byte order. */ - BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ - (EXEC_P | /* Object flags. */ - HAS_SYMS | HAS_LINENO | HAS_DEBUG | - HAS_RELOC | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ - 0, /* Leading underscore. */ - ' ', /* AR_pad_char. */ - 16, /* AR_max_namelen. */ - 0, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */ - - { - _bfd_dummy_target, - tekhex_object_p, /* bfd_check_format. */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - tekhex_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents. */ - bfd_false, - tekhex_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (tekhex), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (tekhex), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (tekhex), - BFD_JUMP_TABLE_LINK (tekhex), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; diff --git a/contrib/binutils-2.22/bfd/verilog.c b/contrib/binutils-2.22/bfd/verilog.c deleted file mode 100644 index a2d3ca7855..0000000000 --- a/contrib/binutils-2.22/bfd/verilog.c +++ /dev/null @@ -1,375 +0,0 @@ -/* BFD back-end for verilog hex memory dump files. - Copyright 2009, 2010, 2011 - Free Software Foundation, Inc. - Written by Anthony Green - - This file is part of BFD, the Binary File Descriptor library. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* SUBSECTION - Verilog hex memory file handling - - DESCRIPTION - - Verilog hex memory files cannot hold anything but addresses - and data, so that's all that we implement. - - The syntax of the text file is described in the IEEE standard - for Verilog. Briefly, the file contains two types of tokens: - data and optional addresses. The tokens are separated by - whitespace and comments. Comments may be single line or - multiline, using syntax similar to C++. Addresses are - specified by a leading "at" character (@) and are always - hexadecimal strings. Data and addresses may contain - underscore (_) characters. - - If no address is specified, the data is assumed to start at - address 0. Similarly, if data exists before the first - specified address, then that data is assumed to start at - address 0. - - - EXAMPLE - @1000 - 01 ae 3f 45 12 - - DESCRIPTION - @1000 specifies the starting address for the memory data. - The following characters describe the 5 bytes at 0x1000. */ - - -#include "sysdep.h" -#include "bfd.h" -#include "libbfd.h" -#include "libiberty.h" -#include "safe-ctype.h" - -/* Macros for converting between hex and binary. */ - -static const char digs[] = "0123456789ABCDEF"; - -#define NIBBLE(x) hex_value(x) -#define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1])) -#define TOHEX(d, x) \ - d[1] = digs[(x) & 0xf]; \ - d[0] = digs[((x) >> 4) & 0xf]; - -/* When writing a verilog memory dump file, we write them in the order - in which they appear in memory. This structure is used to hold them - in memory. */ - -struct verilog_data_list_struct -{ - struct verilog_data_list_struct *next; - bfd_byte * data; - bfd_vma where; - bfd_size_type size; -}; - -typedef struct verilog_data_list_struct verilog_data_list_type; - -/* The verilog tdata information. */ - -typedef struct verilog_data_struct -{ - verilog_data_list_type *head; - verilog_data_list_type *tail; -} -tdata_type; - -static bfd_boolean -verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach) -{ - if (arch != bfd_arch_unknown) - return bfd_default_set_arch_mach (abfd, arch, mach); - - abfd->arch_info = & bfd_default_arch_struct; - return TRUE; -} - -/* We have to save up all the outpu for a splurge before output. */ - -static bfd_boolean -verilog_set_section_contents (bfd *abfd, - sec_ptr section, - const void * location, - file_ptr offset, - bfd_size_type bytes_to_do) -{ - tdata_type *tdata = abfd->tdata.verilog_data; - verilog_data_list_type *entry; - - entry = (verilog_data_list_type *) bfd_alloc (abfd, sizeof (* entry)); - if (entry == NULL) - return FALSE; - - if (bytes_to_do - && (section->flags & SEC_ALLOC) - && (section->flags & SEC_LOAD)) - { - bfd_byte *data; - - data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); - if (data == NULL) - return FALSE; - memcpy ((void *) data, location, (size_t) bytes_to_do); - - entry->data = data; - entry->where = section->lma + offset; - entry->size = bytes_to_do; - - /* Sort the records by address. Optimize for the common case of - adding a record to the end of the list. */ - if (tdata->tail != NULL - && entry->where >= tdata->tail->where) - { - tdata->tail->next = entry; - entry->next = NULL; - tdata->tail = entry; - } - else - { - verilog_data_list_type **look; - - for (look = &tdata->head; - *look != NULL && (*look)->where < entry->where; - look = &(*look)->next) - ; - entry->next = *look; - *look = entry; - if (entry->next == NULL) - tdata->tail = entry; - } - } - return TRUE; -} - -static bfd_boolean -verilog_write_address (bfd *abfd, bfd_vma address) -{ - char buffer[12]; - char *dst = buffer; - bfd_size_type wrlen; - - /* Write the address. */ - *dst++ = '@'; - TOHEX (dst, (address >> 24)); - dst += 2; - TOHEX (dst, (address >> 16)); - dst += 2; - TOHEX (dst, (address >> 8)); - dst += 2; - TOHEX (dst, (address)); - dst += 2; - *dst++ = '\r'; - *dst++ = '\n'; - wrlen = dst - buffer; - - return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen; -} - -/* Write a record of type, of the supplied number of bytes. The - supplied bytes and length don't have a checksum. That's worked out - here. */ - -static bfd_boolean -verilog_write_record (bfd *abfd, - const bfd_byte *data, - const bfd_byte *end) -{ - char buffer[48]; - const bfd_byte *src = data; - char *dst = buffer; - bfd_size_type wrlen; - - /* Write the data. */ - for (src = data; src < end; src++) - { - TOHEX (dst, *src); - dst += 2; - *dst++ = ' '; - } - *dst++ = '\r'; - *dst++ = '\n'; - wrlen = dst - buffer; - - return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen; -} - -static bfd_boolean -verilog_write_section (bfd *abfd, - tdata_type *tdata ATTRIBUTE_UNUSED, - verilog_data_list_type *list) -{ - unsigned int octets_written = 0; - bfd_byte *location = list->data; - - verilog_write_address (abfd, list->where); - while (octets_written < list->size) - { - unsigned int octets_this_chunk = list->size - octets_written; - - if (octets_this_chunk > 16) - octets_this_chunk = 16; - - if (! verilog_write_record (abfd, - location, - location + octets_this_chunk)) - return FALSE; - - octets_written += octets_this_chunk; - location += octets_this_chunk; - } - - return TRUE; -} - -static bfd_boolean -verilog_write_object_contents (bfd *abfd) -{ - tdata_type *tdata = abfd->tdata.verilog_data; - verilog_data_list_type *list; - - /* Now wander though all the sections provided and output them. */ - list = tdata->head; - - while (list != (verilog_data_list_type *) NULL) - { - if (! verilog_write_section (abfd, tdata, list)) - return FALSE; - list = list->next; - } - return TRUE; -} - -/* Initialize by filling in the hex conversion array. */ - -static void -verilog_init (void) -{ - static bfd_boolean inited = FALSE; - - if (! inited) - { - inited = TRUE; - hex_init (); - } -} - -/* Set up the verilog tdata information. */ - -static bfd_boolean -verilog_mkobject (bfd *abfd) -{ - tdata_type *tdata; - - verilog_init (); - - tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (tdata == NULL) - return FALSE; - - abfd->tdata.verilog_data = tdata; - tdata->head = NULL; - tdata->tail = NULL; - - return TRUE; -} - -#define verilog_close_and_cleanup _bfd_generic_close_and_cleanup -#define verilog_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define verilog_new_section_hook _bfd_generic_new_section_hook -#define verilog_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) -#define verilog_bfd_is_local_label_name bfd_generic_is_local_label_name -#define verilog_get_lineno _bfd_nosymbols_get_lineno -#define verilog_find_nearest_line _bfd_nosymbols_find_nearest_line -#define verilog_find_inliner_info _bfd_nosymbols_find_inliner_info -#define verilog_make_empty_symbol _bfd_generic_make_empty_symbol -#define verilog_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define verilog_read_minisymbols _bfd_generic_read_minisymbols -#define verilog_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define verilog_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define verilog_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define verilog_bfd_relax_section bfd_generic_relax_section -#define verilog_bfd_gc_sections bfd_generic_gc_sections -#define verilog_bfd_merge_sections bfd_generic_merge_sections -#define verilog_bfd_is_group_section bfd_generic_is_group_section -#define verilog_bfd_discard_group bfd_generic_discard_group -#define verilog_section_already_linked _bfd_generic_section_already_linked -#define verilog_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define verilog_bfd_link_hash_table_free _bfd_generic_link_hash_table_free -#define verilog_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define verilog_bfd_link_just_syms _bfd_generic_link_just_syms -#define verilog_bfd_final_link _bfd_generic_final_link -#define verilog_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target verilog_vec = -{ - "verilog", /* Name. */ - bfd_target_verilog_flavour, - BFD_ENDIAN_UNKNOWN, /* Target byte order. */ - BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */ - (HAS_RELOC | EXEC_P | /* Object flags. */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ - 0, /* Leading underscore. */ - ' ', /* AR_pad_char. */ - 16, /* AR_max_namelen. */ - 0, /* match priority. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */ - - { - _bfd_dummy_target, - _bfd_dummy_target, - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - verilog_mkobject, - bfd_false, - bfd_false, - }, - { /* bfd_write_contents. */ - bfd_false, - verilog_write_object_contents, - bfd_false, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (verilog), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - NULL, - - NULL -}; diff --git a/contrib/binutils-2.22/bfd/version.h b/contrib/binutils-2.22/bfd/version.h deleted file mode 100644 index c6800ec4a6..0000000000 --- a/contrib/binutils-2.22/bfd/version.h +++ /dev/null @@ -1,4 +0,0 @@ -#define BFD_VERSION_DATE 20111121 -#define BFD_VERSION @bfd_version@ -#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ -#define REPORT_BUGS_TO @report_bugs_to@ diff --git a/contrib/binutils-2.22/binutils/README b/contrib/binutils-2.22/binutils/README deleted file mode 100644 index fc474a5410..0000000000 --- a/contrib/binutils-2.22/binutils/README +++ /dev/null @@ -1,284 +0,0 @@ - README for BINUTILS - -These are the GNU binutils. These are utilities of use when dealing -with binary files, either object files or executables. These tools -consist of the linker (ld), the assembler (gas), and the profiler -(gprof) each of which have their own sub-directory named after them. -There is also a collection of other binary tools, including the -disassembler (objdump) in this directory. These tools make use of a -pair of libraries (bfd and opcodes) and a common set of header files -(include). - -There are README and NEWS files in most of the program sub-directories -which give more information about those specific programs. - - -Unpacking and Installation -- quick overview -============================================ - -When you unpack the binutils archive file, you will get a directory -called something like `binutils-XXX', where XXX is the number of the -release. (Probably 2.13 or higher). This directory contains -various files and sub-directories. Most of the files in the top -directory are for information and for configuration. The actual -source code is in sub-directories. - -To build binutils, you can just do: - - cd binutils-XXX - ./configure [options] - make - make install # copies the programs files into /usr/local/bin - # by default. - -This will configure and build all the libraries as well as the -assembler, the binutils, and the linker. - -If you have GNU make, we recommend building in a different directory: - - mkdir objdir - cd objdir - ../binutils-XXX/configure [options] - make - make install - -This relies on the VPATH feature of GNU make. - -By default, the binutils will be configured to support the system on -which they are built. When doing cross development, use the --target -configure option to specify a different target, eg: - - ./configure --target=foo-elf - -The --enable-targets option adds support for more binary file formats -besides the default. List them as the argument to --enable-targets, -separated by commas. For example: - - ./configure --enable-targets=sun3,rs6000-aix,decstation - -The name 'all' compiles in support for all valid BFD targets: - - ./configure --enable-targets=all - -On 32-bit hosts though, this support will be restricted to 32-bit -target unless the --enable-64-bit-bfd option is also used: - - ./configure --enable-64-bit-bfd --enable-targets=all - -You can also specify the --enable-shared option when you run -configure. This will build the BFD and opcodes libraries as shared -libraries. You can use arguments with the --enable-shared option to -indicate that only certain libraries should be built shared; for -example, --enable-shared=bfd. The only potential shared libraries in -a binutils release are bfd and opcodes. - -The binutils will be linked against the shared libraries. The build -step will attempt to place the correct library in the run-time search -path for the binaries. However, in some cases, after you install the -binaries, you may have to set an environment variable, normally -LD_LIBRARY_PATH, so that the system can find the installed libbfd -shared library. - -On hosts that support shared system libraries the binutils will be -linked against them. If you have static versions of the system -libraries installed as well and you wish to create static binaries -instead then use the LDFLAGS environment variable, like this: - - ../binutils-XXX/configure LDFLAGS="--static" [more options] - -Note: the two dashes are important. The binutils make use of the -libtool script which has a special interpretation of "-static" when it -is in the LDFLAGS environment variable. - -To build under openVMS/AXP, see the file makefile.vms in the top level -directory. - - -Native Language Support -======================= - -By default Native Language Support will be enabled for binutils. On -some systems however this support is not present and can lead to error -messages such as "undefined reference to `libintl_gettext'" when -building there tools. If that happens the NLS support can be disabled -by adding the --disable-nls switch to the configure line like this: - - ../binutils-XXX/configure --disable-nls - - -If you don't have ar -==================== - -If your system does not already have an 'ar' program, the normal -binutils build process will not work. In this case, run configure as -usual. Before running make, run this script: - -#!/bin/sh -MAKE_PROG="${MAKE-make}" -MAKE="${MAKE_PROG} AR=true LINK=true" -export MAKE -${MAKE} $* all-libiberty -${MAKE} $* all-intl -${MAKE} $* all-bfd -cd binutils -MAKE="${MAKE_PROG}" -export MAKE -${MAKE} $* ar_DEPENDENCIES= ar_LDADD='../bfd/*.o ../libiberty/*.o `if test -f ../intl/gettext.o; then echo '../intl/*.o'; fi`' ar - -This script will build an ar program in binutils/ar. Move binutils/ar -into a directory on your PATH. After doing this, you can run make as -usual to build the complete binutils distribution. You do not need -the ranlib program in order to build the distribution. - -Porting -======= - -Binutils-2.13 supports many different architectures, but there -are many more not supported, including some that were supported -by earlier versions. We are hoping for volunteers to improve this -situation. - -The major effort in porting binutils to a new host and/or target -architecture involves the BFD library. There is some documentation -in ../bfd/doc. The file ../gdb/doc/gdbint.texinfo (distributed -with gdb-5.x) may also be of help. - -Reporting bugs -============== - -Send bug reports and patches to: - - bug-binutils@gnu.org. - -Please include the following in bug reports: - -- A description of exactly what went wrong, and exactly what should have - happened instead. - -- The configuration name(s) given to the "configure" script. The - "config.status" file should have this information. This is assuming - you built binutils yourself. If you didn't build binutils youself, - then we need information regarding your machine and operating system, - and it may be more appropriate to report bugs to wherever you obtained - binutils. - -- The options given to the tool (gas, objcopy, ld etc.) at run time. - -- The actual input file that caused the problem. - -Always mention the version number you are running; this is printed by -running any of the binutils with the --version option. We appreciate -reports about bugs, but we do not promise to fix them, particularly so -when the bug report is against an old version. If you are able, please -consider building the latest tools from CVS to check that your bug has -not already been fixed. - -When reporting problems about gas and ld, it's useful to provide a -testcase that triggers the problem. In the case of a gas problem, we -want input files to gas and command line switches used. The inputs to -gas are _NOT_ .c or .i files, but rather .s files. If your original -source was a C program, you can generate the .s file and see the command -line options by passing -v -save-temps to gcc in addition to all the -usual options you use. The reason we don't want C files is that we -might not have a C compiler around for the target you use. While it -might be possible to build a compiler, that takes considerable time and -disk space, and we might not end up with exactly the same compiler you -use. - -In the case of a ld problem, the input files are .o, .a and .so files, -and possibly a linker script specified with -T. Again, when using gcc -to link, you can see these files by adding options to the gcc command -line. Use -v -save-temps -Wl,-t, except that on targets that use gcc's -collect2, you would add -v -save-temps -Wl,-t,-debug. The -t option -tells ld to print all files and libraries used, so that, for example, -you can associate -lc on the ld command line with the actual libc used. -Note that your simple two line C program to trigger a problem typically -expands into several megabytes of objects by the time you include -libraries. - -It is antisocial to post megabyte sized attachments to mailing lists, so -please put large testcases somewhere on an ftp or web site so that only -interested developers need to download them, or offer to email them on -request. Better still, try to reduce the testcase, for example, try to -develop a ld testcase that doesn't use system libraries. However, -please be sure it is a complete testcase and that it really does -demonstrate the problem. Also, don't bother paring it down if that will -cause large delays in filing the bug report. - -If you expect to be contributing a large number of test cases, it would -be helpful if you would look at the test suite included in the release -(based on the Deja Gnu testing framework, available from the usual ftp -sites) and write test cases to fit into that framework. This is -certainly not required. - -VMS -=== - -This section was written by Klaus K"ampf . It -describes how to build and install the binutils on openVMS (Alpha and -Vax). (The BFD library only supports reading Vax object files.) - -Compiling the release: - -To compile the gnu binary utilities and the gnu assembler, you'll -need DEC C or GNU C for openVMS/Alpha. You'll need *both* compilers -on openVMS/Vax. - -Compiling with either DEC C or GNU C works on openVMS/Alpha only. Some -of the opcodes and binutils files trap a bug in the DEC C optimizer, -so these files must be compiled with /noopt. - -Compiling on openVMS/Vax is a bit complicated, as the bfd library traps -a bug in GNU C and the gnu assembler a bug in (my version of) DEC C. - -I never tried compiling with VAX C. - - -You further need GNU Make Version 3.76 or later. This is available -at ftp.progis.de or any GNU archive site. The makefiles assume that -gmake starts gnu make as a foreign command. - -If you're compiling with DEC C or VAX C, you must run - - $ @setup - -before starting gnu-make. This isn't needed with GNU C. - -On the Alpha you can choose the compiler by editing the toplevel -makefile.vms. Either select CC=cc (for DEC C) or CC=gcc (for GNU C) - - -Installing the release - -Provided that your directory setup conforms to the GNU on openVMS -standard, you already have a concealed device named 'GNU_ROOT'. -In this case, a simple - - $ gmake install - -suffices to copy all programs and libraries to the proper directories. - -Define the programs as foreign commands by adding these lines to your -login.com: - - $ gas :== $GNU_ROOT:[bin]as.exe - $ size :== $GNU_ROOT:[bin]size.exe - $ nm :== $GNU_ROOT:[bin]nm.exe - $ objdump :== $GNU_ROOT:[bin]objdump.exe - $ strings :== $GNU_ROOT:[bin]strings.exe - -If you have a different directory setup, copy the binary utilities -([.binutils]size.exe, [.binutils]nm.exe, [.binutils]objdump.exe, -and [.binutils]strings.exe) and the gnu assembler and preprocessor -([.gas]as.exe and [.gas]gasp.exe]) to a directory of your choice -and define all programs as foreign commands. - - -If you're satisfied with the compilation, you may want to remove -unneeded objects and libraries: - - $ gmake clean - - -If you have any problems or questions about the binutils on VMS, feel -free to mail me at kkaempf@rmi.de. diff --git a/contrib/binutils-2.22/binutils/addr2line.c b/contrib/binutils-2.22/binutils/addr2line.c deleted file mode 100644 index 1ece80aecd..0000000000 --- a/contrib/binutils-2.22/binutils/addr2line.c +++ /dev/null @@ -1,460 +0,0 @@ -/* addr2line.c -- convert addresses to line number and function name - Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2009 Free Software Foundation, Inc. - Contributed by Ulrich Lauther - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de - - Usage: - addr2line [options] addr addr ... - or - addr2line [options] - - both forms write results to stdout, the second form reads addresses - to be converted from stdin. */ - -#include "sysdep.h" -#include "bfd.h" -#include "getopt.h" -#include "libiberty.h" -#include "demangle.h" -#include "bucomm.h" -#include "elf-bfd.h" - -static bfd_boolean unwind_inlines; /* -i, unwind inlined functions. */ -static bfd_boolean with_addresses; /* -a, show addresses. */ -static bfd_boolean with_functions; /* -f, show function names. */ -static bfd_boolean do_demangle; /* -C, demangle names. */ -static bfd_boolean pretty_print; /* -p, print on one line. */ -static bfd_boolean base_names; /* -s, strip directory names. */ - -static int naddr; /* Number of addresses to process. */ -static char **addr; /* Hex addresses to process. */ - -static asymbol **syms; /* Symbol table. */ - -static struct option long_options[] = -{ - {"addresses", no_argument, NULL, 'a'}, - {"basenames", no_argument, NULL, 's'}, - {"demangle", optional_argument, NULL, 'C'}, - {"exe", required_argument, NULL, 'e'}, - {"functions", no_argument, NULL, 'f'}, - {"inlines", no_argument, NULL, 'i'}, - {"pretty-print", no_argument, NULL, 'p'}, - {"section", required_argument, NULL, 'j'}, - {"target", required_argument, NULL, 'b'}, - {"help", no_argument, NULL, 'H'}, - {"version", no_argument, NULL, 'V'}, - {0, no_argument, 0, 0} -}; - -static void usage (FILE *, int); -static void slurp_symtab (bfd *); -static void find_address_in_section (bfd *, asection *, void *); -static void find_offset_in_section (bfd *, asection *); -static void translate_addresses (bfd *, asection *); - -/* Print a usage message to STREAM and exit with STATUS. */ - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name); - fprintf (stream, _(" Convert addresses into line number/file name pairs.\n")); - fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n")); - fprintf (stream, _(" The options are:\n\ - @ Read options from \n\ - -a --addresses Show addresses\n\ - -b --target= Set the binary file format\n\ - -e --exe= Set the input file name (default is a.out)\n\ - -i --inlines Unwind inlined functions\n\ - -j --section= Read section-relative offsets instead of addresses\n\ - -p --pretty-print Make the output easier to read for humans\n\ - -s --basenames Strip directory names\n\ - -f --functions Show function names\n\ - -C --demangle[=style] Demangle function names\n\ - -h --help Display this information\n\ - -v --version Display the program's version\n\ -\n")); - - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (status); -} - -/* Read in the symbol table. */ - -static void -slurp_symtab (bfd *abfd) -{ - long storage; - long symcount; - bfd_boolean dynamic = FALSE; - - if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0) - return; - - storage = bfd_get_symtab_upper_bound (abfd); - if (storage == 0) - { - storage = bfd_get_dynamic_symtab_upper_bound (abfd); - dynamic = TRUE; - } - if (storage < 0) - bfd_fatal (bfd_get_filename (abfd)); - - syms = (asymbol **) xmalloc (storage); - if (dynamic) - symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); - else - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - bfd_fatal (bfd_get_filename (abfd)); -} - -/* These global variables are used to pass information between - translate_addresses and find_address_in_section. */ - -static bfd_vma pc; -static const char *filename; -static const char *functionname; -static unsigned int line; -static bfd_boolean found; - -/* Look for an address in a section. This is called via - bfd_map_over_sections. */ - -static void -find_address_in_section (bfd *abfd, asection *section, - void *data ATTRIBUTE_UNUSED) -{ - bfd_vma vma; - bfd_size_type size; - - if (found) - return; - - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) - return; - - vma = bfd_get_section_vma (abfd, section); - if (pc < vma) - return; - - size = bfd_get_section_size (section); - if (pc >= vma + size) - return; - - found = bfd_find_nearest_line (abfd, section, syms, pc - vma, - &filename, &functionname, &line); -} - -/* Look for an offset in a section. This is directly called. */ - -static void -find_offset_in_section (bfd *abfd, asection *section) -{ - bfd_size_type size; - - if (found) - return; - - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) - return; - - size = bfd_get_section_size (section); - if (pc >= size) - return; - - found = bfd_find_nearest_line (abfd, section, syms, pc, - &filename, &functionname, &line); -} - -/* Read hexadecimal addresses from stdin, translate into - file_name:line_number and optionally function name. */ - -static void -translate_addresses (bfd *abfd, asection *section) -{ - const struct elf_backend_data * bed; - - int read_stdin = (naddr == 0); - - for (;;) - { - if (read_stdin) - { - char addr_hex[100]; - - if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL) - break; - pc = bfd_scan_vma (addr_hex, NULL, 16); - } - else - { - if (naddr <= 0) - break; - --naddr; - pc = bfd_scan_vma (*addr++, NULL, 16); - } - - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && (bed = get_elf_backend_data (abfd)) != NULL - && bed->sign_extend_vma - && (pc & (bfd_vma) 1 << (bed->s->arch_size - 1))) - pc |= ((bfd_vma) -1) << bed->s->arch_size; - - if (with_addresses) - { - printf ("0x"); - bfd_printf_vma (abfd, pc); - - if (pretty_print) - printf (": "); - else - printf ("\n"); - } - - found = FALSE; - if (section) - find_offset_in_section (abfd, section); - else - bfd_map_over_sections (abfd, find_address_in_section, NULL); - - if (! found) - { - if (with_functions) - printf ("??\n"); - printf ("??:0\n"); - } - else - { - while (1) - { - if (with_functions) - { - const char *name; - char *alloc = NULL; - - name = functionname; - if (name == NULL || *name == '\0') - name = "??"; - else if (do_demangle) - { - alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); - if (alloc != NULL) - name = alloc; - } - - printf ("%s", name); - if (pretty_print) - printf (_(" at ")); - else - printf ("\n"); - - if (alloc != NULL) - free (alloc); - } - - if (base_names && filename != NULL) - { - char *h; - - h = strrchr (filename, '/'); - if (h != NULL) - filename = h + 1; - } - - printf ("%s:%u\n", filename ? filename : "??", line); - if (!unwind_inlines) - found = FALSE; - else - found = bfd_find_inliner_info (abfd, &filename, &functionname, &line); - if (! found) - break; - if (pretty_print) - printf (_(" (inlined by) ")); - } - } - - /* fflush() is essential for using this command as a server - child process that reads addresses from a pipe and responds - with line number information, processing one address at a - time. */ - fflush (stdout); - } -} - -/* Process a file. Returns an exit value for main(). */ - -static int -process_file (const char *file_name, const char *section_name, - const char *target) -{ - bfd *abfd; - asection *section; - char **matching; - - if (get_file_size (file_name) < 1) - return 1; - - abfd = bfd_openr (file_name, target); - if (abfd == NULL) - bfd_fatal (file_name); - - /* Decompress sections. */ - abfd->flags |= BFD_DECOMPRESS; - - if (bfd_check_format (abfd, bfd_archive)) - fatal (_("%s: cannot get addresses from archive"), file_name); - - if (! bfd_check_format_matches (abfd, bfd_object, &matching)) - { - bfd_nonfatal (bfd_get_filename (abfd)); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - xexit (1); - } - - if (section_name != NULL) - { - section = bfd_get_section_by_name (abfd, section_name); - if (section == NULL) - fatal (_("%s: cannot find section %s"), file_name, section_name); - } - else - section = NULL; - - slurp_symtab (abfd); - - translate_addresses (abfd, section); - - if (syms != NULL) - { - free (syms); - syms = NULL; - } - - bfd_close (abfd); - - return 0; -} - -int -main (int argc, char **argv) -{ - const char *file_name; - const char *section_name; - char *target; - int c; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = *argv; - xmalloc_set_program_name (program_name); - - expandargv (&argc, &argv); - - bfd_init (); - set_default_bfd_target (); - - file_name = NULL; - section_name = NULL; - target = NULL; - while ((c = getopt_long (argc, argv, "ab:Ce:sfHhij:pVv", long_options, (int *) 0)) - != EOF) - { - switch (c) - { - case 0: - break; /* We've been given a long option. */ - case 'a': - with_addresses = TRUE; - break; - case 'b': - target = optarg; - break; - case 'C': - do_demangle = TRUE; - if (optarg != NULL) - { - enum demangling_styles style; - - style = cplus_demangle_name_to_style (optarg); - if (style == unknown_demangling) - fatal (_("unknown demangling style `%s'"), - optarg); - - cplus_demangle_set_style (style); - } - break; - case 'e': - file_name = optarg; - break; - case 's': - base_names = TRUE; - break; - case 'f': - with_functions = TRUE; - break; - case 'p': - pretty_print = TRUE; - break; - case 'v': - case 'V': - print_version ("addr2line"); - break; - case 'h': - case 'H': - usage (stdout, 0); - break; - case 'i': - unwind_inlines = TRUE; - break; - case 'j': - section_name = optarg; - break; - default: - usage (stderr, 1); - break; - } - } - - if (file_name == NULL) - file_name = "a.out"; - - addr = argv + optind; - naddr = argc - optind; - - return process_file (file_name, section_name, target); -} diff --git a/contrib/binutils-2.22/binutils/ar.c b/contrib/binutils-2.22/binutils/ar.c deleted file mode 100644 index 22be2cd053..0000000000 --- a/contrib/binutils-2.22/binutils/ar.c +++ /dev/null @@ -1,1382 +0,0 @@ -/* ar.c - Archive modify and extract. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* - Bugs: GNU ar used to check file against filesystem in quick_update and - replace operations (would check mtime). Doesn't warn when name truncated. - No way to specify pos_end. Error messages should be more consistent. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "progress.h" -#include "getopt.h" -#include "aout/ar.h" -#include "libbfd.h" -#include "bucomm.h" -#include "arsup.h" -#include "filenames.h" -#include "binemul.h" -#include "plugin.h" -#include - -#ifdef __GO32___ -#define EXT_NAME_LEN 3 /* Bufflen of addition to name if it's MS-DOS. */ -#else -#define EXT_NAME_LEN 6 /* Ditto for *NIX. */ -#endif - -/* Static declarations. */ - -static void mri_emul (void); -static const char *normalize (const char *, bfd *); -static void remove_output (void); -static void map_over_members (bfd *, void (*)(bfd *), char **, int); -static void print_contents (bfd * member); -static void delete_members (bfd *, char **files_to_delete); - -static void move_members (bfd *, char **files_to_move); -static void replace_members - (bfd *, char **files_to_replace, bfd_boolean quick); -static void print_descr (bfd * abfd); -static void write_archive (bfd *); -static int ranlib_only (const char *archname); -static int ranlib_touch (const char *archname); -static void usage (int); - -/** Globals and flags. */ - -static int mri_mode; - -/* This flag distinguishes between ar and ranlib: - 1 means this is 'ranlib'; 0 means this is 'ar'. - -1 means if we should use argv[0] to decide. */ -extern int is_ranlib; - -/* Nonzero means don't warn about creating the archive file if necessary. */ -int silent_create = 0; - -/* Nonzero means describe each action performed. */ -int verbose = 0; - -/* Nonzero means preserve dates of members when extracting them. */ -int preserve_dates = 0; - -/* Nonzero means don't replace existing members whose dates are more recent - than the corresponding files. */ -int newer_only = 0; - -/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF - member). -1 means we've been explicitly asked to not write a symbol table; - +1 means we've been explicitly asked to write it; - 0 is the default. - Traditionally, the default in BSD has been to not write the table. - However, for POSIX.2 compliance the default is now to write a symbol table - if any of the members are object files. */ -int write_armap = 0; - -/* Operate in deterministic mode: write zero for timestamps, uids, - and gids for archive members and the archive symbol table, and write - consistent file modes. */ -int deterministic = 0; - -/* Nonzero means it's the name of an existing member; position new or moved - files with respect to this one. */ -char *posname = NULL; - -/* Sez how to use `posname': pos_before means position before that member. - pos_after means position after that member. pos_end means always at end. - pos_default means default appropriately. For the latter two, `posname' - should also be zero. */ -enum pos - { - pos_default, pos_before, pos_after, pos_end - } postype = pos_default; - -enum operations - { - none = 0, del, replace, print_table, - print_files, extract, move, quick_append - } operation = none; - -static bfd ** -get_pos_bfd (bfd **, enum pos, const char *); - -/* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only - extract the COUNTED_NAME_COUNTER instance of that name. */ -static bfd_boolean counted_name_mode = 0; -static int counted_name_counter = 0; - -/* Whether to truncate names of files stored in the archive. */ -static bfd_boolean ar_truncate = FALSE; - -/* Whether to use a full file name match when searching an archive. - This is convenient for archives created by the Microsoft lib - program. */ -static bfd_boolean full_pathname = FALSE; - -/* Whether to create a "thin" archive (symbol index only -- no files). */ -static bfd_boolean make_thin_archive = FALSE; - -static int show_version = 0; - -static int show_help = 0; - -static const char *plugin_target = NULL; - -static const char *target = NULL; - -#define OPTION_PLUGIN 201 -#define OPTION_TARGET 202 - -static struct option long_options[] = -{ - {"help", no_argument, &show_help, 1}, - {"plugin", required_argument, NULL, OPTION_PLUGIN}, - {"target", required_argument, NULL, OPTION_TARGET}, - {"version", no_argument, &show_version, 1}, - {NULL, no_argument, NULL, 0} -}; - -int interactive = 0; - -static void -mri_emul (void) -{ - interactive = isatty (fileno (stdin)); - yyparse (); -} - -/* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero, - COUNT is the length of the FILES chain; FUNCTION is called on each entry - whose name matches one in FILES. */ - -static void -map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count) -{ - bfd *head; - int match_count; - - if (count == 0) - { - for (head = arch->archive_next; head; head = head->archive_next) - { - PROGRESS (1); - function (head); - } - return; - } - - /* This may appear to be a baroque way of accomplishing what we want. - However we have to iterate over the filenames in order to notice where - a filename is requested but does not exist in the archive. Ditto - mapping over each file each time -- we want to hack multiple - references. */ - - for (; count > 0; files++, count--) - { - bfd_boolean found = FALSE; - - match_count = 0; - for (head = arch->archive_next; head; head = head->archive_next) - { - const char * filename; - - PROGRESS (1); - filename = head->filename; - if (filename == NULL) - { - /* Some archive formats don't get the filenames filled in - until the elements are opened. */ - struct stat buf; - bfd_stat_arch_elt (head, &buf); - } - else if (bfd_is_thin_archive (arch)) - { - /* Thin archives store full pathnames. Need to normalize. */ - filename = normalize (filename, arch); - } - - if (filename != NULL - && !FILENAME_CMP (normalize (*files, arch), filename)) - { - ++match_count; - if (counted_name_mode - && match_count != counted_name_counter) - { - /* Counting, and didn't match on count; go on to the - next one. */ - continue; - } - - found = TRUE; - function (head); - } - } - - if (!found) - /* xgettext:c-format */ - fprintf (stderr, _("no entry %s in archive\n"), *files); - } -} - -bfd_boolean operation_alters_arch = FALSE; - -static void -usage (int help) -{ - FILE *s; - - s = help ? stdout : stderr; - -#if BFD_SUPPORTS_PLUGINS - /* xgettext:c-format */ - const char *command_line - = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]" - " [--plugin ] [member-name] [count] archive-file file...\n"); - -#else - /* xgettext:c-format */ - const char *command_line - = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]" - " [member-name] [count] archive-file file...\n"); -#endif - fprintf (s, command_line, program_name); - - /* xgettext:c-format */ - fprintf (s, _(" %s -M [ - read options from \n")); - fprintf (s, _(" --target=BFDNAME - specify the target object format as BFDNAME\n")); -#if BFD_SUPPORTS_PLUGINS - fprintf (s, _(" optional:\n")); - fprintf (s, _(" --plugin

- load the specified plugin\n")); -#endif - - ar_emul_usage (s); - - list_supported_targets (program_name, s); - - if (REPORT_BUGS_TO[0] && help) - fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO); - - xexit (help ? 0 : 1); -} - -static void -ranlib_usage (int help) -{ - FILE *s; - - s = help ? stdout : stderr; - - /* xgettext:c-format */ - fprintf (s, _("Usage: %s [options] archive\n"), program_name); - fprintf (s, _(" Generate an index to speed access to archives\n")); - fprintf (s, _(" The options are:\n\ - @ Read options from \n")); -#if BFD_SUPPORTS_PLUGINS - fprintf (s, _("\ - --plugin Load the specified plugin\n")); -#endif - fprintf (s, _("\ - -t Update the archive's symbol map timestamp\n\ - -h --help Print this help message\n\ - -v --version Print version information\n")); - - list_supported_targets (program_name, s); - - if (REPORT_BUGS_TO[0] && help) - fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO); - - xexit (help ? 0 : 1); -} - -/* Normalize a file name specified on the command line into a file - name which we will use in an archive. */ - -static const char * -normalize (const char *file, bfd *abfd) -{ - const char *filename; - - if (full_pathname) - return file; - - filename = lbasename (file); - - if (ar_truncate - && abfd != NULL - && strlen (filename) > abfd->xvec->ar_max_namelen) - { - char *s; - - /* Space leak. */ - s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1); - memcpy (s, filename, abfd->xvec->ar_max_namelen); - s[abfd->xvec->ar_max_namelen] = '\0'; - filename = s; - } - - return filename; -} - -/* Remove any output file. This is only called via xatexit. */ - -static const char *output_filename = NULL; -static FILE *output_file = NULL; -static bfd *output_bfd = NULL; - -static void -remove_output (void) -{ - if (output_filename != NULL) - { - if (output_bfd != NULL) - bfd_cache_close (output_bfd); - if (output_file != NULL) - fclose (output_file); - unlink_if_ordinary (output_filename); - } -} - -static char ** -decode_options (int argc, char **argv) -{ - int c; - - /* Convert old-style tar call by exploding option element and rearranging - options accordingly. */ - - if (argc > 1 && argv[1][0] != '-') - { - int new_argc; /* argc value for rearranged arguments */ - char **new_argv; /* argv value for rearranged arguments */ - char *const *in; /* cursor into original argv */ - char **out; /* cursor into rearranged argv */ - const char *letter; /* cursor into old option letters */ - char buffer[3]; /* constructed option buffer */ - - /* Initialize a constructed option. */ - - buffer[0] = '-'; - buffer[2] = '\0'; - - /* Allocate a new argument array, and copy program name in it. */ - - new_argc = argc - 1 + strlen (argv[1]); - new_argv = xmalloc ((new_argc + 1) * sizeof (*argv)); - in = argv; - out = new_argv; - *out++ = *in++; - - /* Copy each old letter option as a separate option. */ - - for (letter = *in++; *letter; letter++) - { - buffer[1] = *letter; - *out++ = xstrdup (buffer); - } - - /* Copy all remaining options. */ - - while (in < argv + argc) - *out++ = *in++; - *out = NULL; - - /* Replace the old option list by the new one. */ - - argc = new_argc; - argv = new_argv; - } - - while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTD", - long_options, NULL)) != EOF) - { - switch (c) - { - case 'd': - case 'm': - case 'p': - case 'q': - case 'r': - case 't': - case 'x': - if (operation != none) - fatal (_("two different operation options specified")); - break; - } - - switch (c) - { - case 'h': - show_help = 1; - break; - case 'd': - operation = del; - operation_alters_arch = TRUE; - break; - case 'm': - operation = move; - operation_alters_arch = TRUE; - break; - case 'p': - operation = print_files; - break; - case 'q': - operation = quick_append; - operation_alters_arch = TRUE; - break; - case 'r': - operation = replace; - operation_alters_arch = TRUE; - break; - case 't': - operation = print_table; - break; - case 'x': - operation = extract; - break; - case 'l': - break; - case 'c': - silent_create = 1; - break; - case 'o': - preserve_dates = 1; - break; - case 'V': - show_version = TRUE; - break; - case 's': - write_armap = 1; - break; - case 'S': - write_armap = -1; - break; - case 'u': - newer_only = 1; - break; - case 'v': - verbose = 1; - break; - case 'a': - postype = pos_after; - break; - case 'b': - postype = pos_before; - break; - case 'i': - postype = pos_before; - break; - case 'M': - mri_mode = 1; - break; - case 'N': - counted_name_mode = TRUE; - break; - case 'f': - ar_truncate = TRUE; - break; - case 'P': - full_pathname = TRUE; - break; - case 'T': - make_thin_archive = TRUE; - break; - case 'D': - deterministic = TRUE; - break; - case OPTION_PLUGIN: -#if BFD_SUPPORTS_PLUGINS - plugin_target = "plugin"; - bfd_plugin_set_plugin (optarg); -#else - fprintf (stderr, _("sorry - this program has been built without plugin support\n")); - xexit (1); -#endif - break; - case OPTION_TARGET: - target = optarg; - break; - case 0: /* A long option that just sets a flag. */ - break; - default: - usage (0); - } - } - - return &argv[optind]; -} - -static void -ranlib_main (int argc, char **argv) -{ - int arg_index, status = 0; - bfd_boolean touch = FALSE; - int c; - - while ((c = getopt_long (argc, argv, "hHvVt", long_options, NULL)) != EOF) - { - switch (c) - { - case 'h': - case 'H': - show_help = 1; - break; - case 't': - touch = TRUE; - break; - case 'v': - case 'V': - show_version = 1; - break; - } - } - - if (argc < 2) - ranlib_usage (0); - - if (show_help) - usage (1); - - if (show_version) - print_version ("ranlib"); - - arg_index = optind; - - while (arg_index < argc) - { - if (! touch) - status |= ranlib_only (argv[arg_index]); - else - status |= ranlib_touch (argv[arg_index]); - ++arg_index; - } - - xexit (status); -} - -int main (int, char **); - -int -main (int argc, char **argv) -{ - int arg_index; - char **files; - int file_count; - char *inarch_filename; - int i; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = argv[0]; - xmalloc_set_program_name (program_name); -#if BFD_SUPPORTS_PLUGINS - bfd_plugin_set_program_name (program_name); -#endif - - expandargv (&argc, &argv); - - if (is_ranlib < 0) - { - const char *temp = lbasename (program_name); - - if (strlen (temp) >= 6 - && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0) - is_ranlib = 1; - else - is_ranlib = 0; - } - - START_PROGRESS (program_name, 0); - - bfd_init (); - set_default_bfd_target (); - - xatexit (remove_output); - - for (i = 1; i < argc; i++) - if (! ar_emul_parse_arg (argv[i])) - break; - argv += (i - 1); - argc -= (i - 1); - - if (is_ranlib) - ranlib_main (argc, argv); - - if (argc < 2) - usage (0); - - argv = decode_options (argc, argv); - - if (show_help) - usage (1); - - if (show_version) - print_version ("ar"); - - arg_index = 0; - - if (mri_mode) - { - mri_emul (); - } - else - { - bfd *arch; - - /* We don't use do_quick_append any more. Too many systems - expect ar to always rebuild the symbol table even when q is - used. */ - - /* We can't write an armap when using ar q, so just do ar r - instead. */ - if (operation == quick_append && write_armap) - operation = replace; - - if ((operation == none || operation == print_table) - && write_armap == 1) - xexit (ranlib_only (argv[arg_index])); - - if (operation == none) - fatal (_("no operation specified")); - - if (newer_only && operation != replace) - fatal (_("`u' is only meaningful with the `r' option.")); - - if (newer_only && deterministic) - fatal (_("`u' is not meaningful with the `D' option.")); - - if (postype != pos_default) - posname = argv[arg_index++]; - - if (counted_name_mode) - { - if (operation != extract && operation != del) - fatal (_("`N' is only meaningful with the `x' and `d' options.")); - counted_name_counter = atoi (argv[arg_index++]); - if (counted_name_counter <= 0) - fatal (_("Value for `N' must be positive.")); - } - - inarch_filename = argv[arg_index++]; - - for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++) - continue; - - files = (file_count > 0) ? argv + arg_index : NULL; - - arch = open_inarch (inarch_filename, - files == NULL ? (char *) NULL : files[0]); - - if (operation == extract && bfd_is_thin_archive (arch)) - fatal (_("`x' cannot be used on thin archives.")); - - switch (operation) - { - case print_table: - map_over_members (arch, print_descr, files, file_count); - break; - - case print_files: - map_over_members (arch, print_contents, files, file_count); - break; - - case extract: - map_over_members (arch, extract_file, files, file_count); - break; - - case del: - if (files != NULL) - delete_members (arch, files); - else - output_filename = NULL; - break; - - case move: - /* PR 12558: Creating and moving at the same time does - not make sense. Just create the archive instead. */ - if (! silent_create) - { - if (files != NULL) - move_members (arch, files); - else - output_filename = NULL; - break; - } - /* Fall through. */ - - case replace: - case quick_append: - if (files != NULL || write_armap > 0) - replace_members (arch, files, operation == quick_append); - else - output_filename = NULL; - break; - - /* Shouldn't happen! */ - default: - /* xgettext:c-format */ - fatal (_("internal error -- this option not implemented")); - } - } - - END_PROGRESS (program_name); - - xexit (0); - return 0; -} - -bfd * -open_inarch (const char *archive_filename, const char *file) -{ - bfd **last_one; - bfd *next_one; - struct stat sbuf; - bfd *arch; - char **matching; - - bfd_set_error (bfd_error_no_error); - - if (target == NULL) - target = plugin_target; - - if (stat (archive_filename, &sbuf) != 0) - { -#if !defined(__GO32__) || defined(__DJGPP__) - - /* FIXME: I don't understand why this fragment was ifndef'ed - away for __GO32__; perhaps it was in the days of DJGPP v1.x. - stat() works just fine in v2.x, so I think this should be - removed. For now, I enable it for DJGPP v2. -- EZ. */ - - /* KLUDGE ALERT! Temporary fix until I figger why - stat() is wrong ... think it's buried in GO32's IDT - Jax */ - if (errno != ENOENT) - bfd_fatal (archive_filename); -#endif - - if (!operation_alters_arch) - { - fprintf (stderr, "%s: ", program_name); - perror (archive_filename); - maybequit (); - return NULL; - } - - /* If the target isn't set, try to figure out the target to use - for the archive from the first object on the list. */ - if (target == NULL && file != NULL) - { - bfd *obj; - - obj = bfd_openr (file, target); - if (obj != NULL) - { - if (bfd_check_format (obj, bfd_object)) - target = bfd_get_target (obj); - (void) bfd_close (obj); - } - } - - /* Create an empty archive. */ - arch = bfd_openw (archive_filename, target); - if (arch == NULL - || ! bfd_set_format (arch, bfd_archive) - || ! bfd_close (arch)) - bfd_fatal (archive_filename); - else if (!silent_create) - non_fatal (_("creating %s"), archive_filename); - - /* If we die creating a new archive, don't leave it around. */ - output_filename = archive_filename; - } - - arch = bfd_openr (archive_filename, target); - if (arch == NULL) - { - bloser: - bfd_fatal (archive_filename); - } - - if (! bfd_check_format_matches (arch, bfd_archive, &matching)) - { - bfd_nonfatal (archive_filename); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - xexit (1); - } - - last_one = &(arch->archive_next); - /* Read all the contents right away, regardless. */ - for (next_one = bfd_openr_next_archived_file (arch, NULL); - next_one; - next_one = bfd_openr_next_archived_file (arch, next_one)) - { - PROGRESS (1); - *last_one = next_one; - last_one = &next_one->archive_next; - } - *last_one = (bfd *) NULL; - if (bfd_get_error () != bfd_error_no_more_archived_files) - goto bloser; - return arch; -} - -static void -print_contents (bfd *abfd) -{ - size_t ncopied = 0; - char *cbuf = (char *) xmalloc (BUFSIZE); - struct stat buf; - size_t size; - if (bfd_stat_arch_elt (abfd, &buf) != 0) - /* xgettext:c-format */ - fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); - - if (verbose) - printf ("\n<%s>\n\n", bfd_get_filename (abfd)); - - bfd_seek (abfd, (file_ptr) 0, SEEK_SET); - - size = buf.st_size; - while (ncopied < size) - { - - size_t nread; - size_t tocopy = size - ncopied; - if (tocopy > BUFSIZE) - tocopy = BUFSIZE; - - nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd); - if (nread != tocopy) - /* xgettext:c-format */ - fatal (_("%s is not a valid archive"), - bfd_get_filename (bfd_my_archive (abfd))); - - /* fwrite in mingw32 may return int instead of size_t. Cast the - return value to size_t to avoid comparison between signed and - unsigned values. */ - if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread) - fatal ("stdout: %s", strerror (errno)); - ncopied += tocopy; - } - free (cbuf); -} - -/* Extract a member of the archive into its own file. - - We defer opening the new file until after we have read a BUFSIZ chunk of the - old one, since we know we have just read the archive header for the old - one. Since most members are shorter than BUFSIZ, this means we will read - the old header, read the old data, write a new inode for the new file, and - write the new data, and be done. This 'optimization' is what comes from - sitting next to a bare disk and hearing it every time it seeks. -- Gnu - Gilmore */ - -void -extract_file (bfd *abfd) -{ - FILE *ostream; - char *cbuf = (char *) xmalloc (BUFSIZE); - size_t nread, tocopy; - size_t ncopied = 0; - size_t size; - struct stat buf; - - if (bfd_stat_arch_elt (abfd, &buf) != 0) - /* xgettext:c-format */ - fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); - size = buf.st_size; - - if (verbose) - printf ("x - %s\n", bfd_get_filename (abfd)); - - bfd_seek (abfd, (file_ptr) 0, SEEK_SET); - - ostream = NULL; - if (size == 0) - { - /* Seems like an abstraction violation, eh? Well it's OK! */ - output_filename = bfd_get_filename (abfd); - - ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); - if (ostream == NULL) - { - perror (bfd_get_filename (abfd)); - xexit (1); - } - - output_file = ostream; - } - else - while (ncopied < size) - { - tocopy = size - ncopied; - if (tocopy > BUFSIZE) - tocopy = BUFSIZE; - - nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd); - if (nread != tocopy) - /* xgettext:c-format */ - fatal (_("%s is not a valid archive"), - bfd_get_filename (bfd_my_archive (abfd))); - - /* See comment above; this saves disk arm motion */ - if (ostream == NULL) - { - /* Seems like an abstraction violation, eh? Well it's OK! */ - output_filename = bfd_get_filename (abfd); - - ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); - if (ostream == NULL) - { - perror (bfd_get_filename (abfd)); - xexit (1); - } - - output_file = ostream; - } - - /* fwrite in mingw32 may return int instead of size_t. Cast - the return value to size_t to avoid comparison between - signed and unsigned values. */ - if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread) - fatal ("%s: %s", output_filename, strerror (errno)); - ncopied += tocopy; - } - - if (ostream != NULL) - fclose (ostream); - - output_file = NULL; - output_filename = NULL; - - chmod (bfd_get_filename (abfd), buf.st_mode); - - if (preserve_dates) - { - /* Set access time to modification time. Only st_mtime is - initialized by bfd_stat_arch_elt. */ - buf.st_atime = buf.st_mtime; - set_times (bfd_get_filename (abfd), &buf); - } - - free (cbuf); -} - -static void -write_archive (bfd *iarch) -{ - bfd *obfd; - char *old_name, *new_name; - bfd *contents_head = iarch->archive_next; - - old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1); - strcpy (old_name, bfd_get_filename (iarch)); - new_name = make_tempname (old_name); - - if (new_name == NULL) - bfd_fatal ("could not create temporary file whilst writing archive"); - - output_filename = new_name; - - obfd = bfd_openw (new_name, bfd_get_target (iarch)); - - if (obfd == NULL) - bfd_fatal (old_name); - - output_bfd = obfd; - - bfd_set_format (obfd, bfd_archive); - - /* Request writing the archive symbol table unless we've - been explicitly requested not to. */ - obfd->has_armap = write_armap >= 0; - - if (ar_truncate) - { - /* This should really use bfd_set_file_flags, but that rejects - archives. */ - obfd->flags |= BFD_TRADITIONAL_FORMAT; - } - - if (deterministic) - obfd->flags |= BFD_DETERMINISTIC_OUTPUT; - - if (make_thin_archive || bfd_is_thin_archive (iarch)) - bfd_is_thin_archive (obfd) = 1; - - if (!bfd_set_archive_head (obfd, contents_head)) - bfd_fatal (old_name); - - if (!bfd_close (obfd)) - bfd_fatal (old_name); - - output_bfd = NULL; - output_filename = NULL; - - /* We don't care if this fails; we might be creating the archive. */ - bfd_close (iarch); - - if (smart_rename (new_name, old_name, 0) != 0) - xexit (1); - free (old_name); -} - -/* Return a pointer to the pointer to the entry which should be rplacd'd - into when altering. DEFAULT_POS should be how to interpret pos_default, - and should be a pos value. */ - -static bfd ** -get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname) -{ - bfd **after_bfd = contents; - enum pos realpos; - const char *realposname; - - if (postype == pos_default) - { - realpos = default_pos; - realposname = default_posname; - } - else - { - realpos = postype; - realposname = posname; - } - - if (realpos == pos_end) - { - while (*after_bfd) - after_bfd = &((*after_bfd)->archive_next); - } - else - { - for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next) - if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0) - { - if (realpos == pos_after) - after_bfd = &(*after_bfd)->archive_next; - break; - } - } - return after_bfd; -} - -static void -delete_members (bfd *arch, char **files_to_delete) -{ - bfd **current_ptr_ptr; - bfd_boolean found; - bfd_boolean something_changed = FALSE; - int match_count; - - for (; *files_to_delete != NULL; ++files_to_delete) - { - /* In a.out systems, the armap is optional. It's also called - __.SYMDEF. So if the user asked to delete it, we should remember - that fact. This isn't quite right for COFF systems (where - __.SYMDEF might be regular member), but it's very unlikely - to be a problem. FIXME */ - - if (!strcmp (*files_to_delete, "__.SYMDEF")) - { - arch->has_armap = FALSE; - write_armap = -1; - continue; - } - - found = FALSE; - match_count = 0; - current_ptr_ptr = &(arch->archive_next); - while (*current_ptr_ptr) - { - if (FILENAME_CMP (normalize (*files_to_delete, arch), - (*current_ptr_ptr)->filename) == 0) - { - ++match_count; - if (counted_name_mode - && match_count != counted_name_counter) - { - /* Counting, and didn't match on count; go on to the - next one. */ - } - else - { - found = TRUE; - something_changed = TRUE; - if (verbose) - printf ("d - %s\n", - *files_to_delete); - *current_ptr_ptr = ((*current_ptr_ptr)->archive_next); - goto next_file; - } - } - - current_ptr_ptr = &((*current_ptr_ptr)->archive_next); - } - - if (verbose && !found) - { - /* xgettext:c-format */ - printf (_("No member named `%s'\n"), *files_to_delete); - } - next_file: - ; - } - - if (something_changed) - write_archive (arch); - else - output_filename = NULL; -} - - -/* Reposition existing members within an archive */ - -static void -move_members (bfd *arch, char **files_to_move) -{ - bfd **after_bfd; /* New entries go after this one */ - bfd **current_ptr_ptr; /* cdr pointer into contents */ - - for (; *files_to_move; ++files_to_move) - { - current_ptr_ptr = &(arch->archive_next); - while (*current_ptr_ptr) - { - bfd *current_ptr = *current_ptr_ptr; - if (FILENAME_CMP (normalize (*files_to_move, arch), - current_ptr->filename) == 0) - { - /* Move this file to the end of the list - first cut from - where it is. */ - bfd *link_bfd; - *current_ptr_ptr = current_ptr->archive_next; - - /* Now glue to end */ - after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL); - link_bfd = *after_bfd; - *after_bfd = current_ptr; - current_ptr->archive_next = link_bfd; - - if (verbose) - printf ("m - %s\n", *files_to_move); - - goto next_file; - } - - current_ptr_ptr = &((*current_ptr_ptr)->archive_next); - } - /* xgettext:c-format */ - fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename); - - next_file:; - } - - write_archive (arch); -} - -/* Ought to default to replacing in place, but this is existing practice! */ - -static void -replace_members (bfd *arch, char **files_to_move, bfd_boolean quick) -{ - bfd_boolean changed = FALSE; - bfd **after_bfd; /* New entries go after this one. */ - bfd *current; - bfd **current_ptr; - - while (files_to_move && *files_to_move) - { - if (! quick) - { - current_ptr = &arch->archive_next; - while (*current_ptr) - { - current = *current_ptr; - - /* For compatibility with existing ar programs, we - permit the same file to be added multiple times. */ - if (FILENAME_CMP (normalize (*files_to_move, arch), - normalize (current->filename, arch)) == 0 - && current->arelt_data != NULL) - { - if (newer_only) - { - struct stat fsbuf, asbuf; - - if (stat (*files_to_move, &fsbuf) != 0) - { - if (errno != ENOENT) - bfd_fatal (*files_to_move); - goto next_file; - } - if (bfd_stat_arch_elt (current, &asbuf) != 0) - /* xgettext:c-format */ - fatal (_("internal stat error on %s"), - current->filename); - - if (fsbuf.st_mtime <= asbuf.st_mtime) - goto next_file; - } - - after_bfd = get_pos_bfd (&arch->archive_next, pos_after, - current->filename); - if (ar_emul_replace (after_bfd, *files_to_move, - target, verbose)) - { - /* Snip out this entry from the chain. */ - *current_ptr = (*current_ptr)->archive_next; - changed = TRUE; - } - - goto next_file; - } - current_ptr = &(current->archive_next); - } - } - - /* Add to the end of the archive. */ - after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL); - - if (ar_emul_append (after_bfd, *files_to_move, target, - verbose, make_thin_archive)) - changed = TRUE; - - next_file:; - - files_to_move++; - } - - if (changed) - write_archive (arch); - else - output_filename = NULL; -} - -static int -ranlib_only (const char *archname) -{ - bfd *arch; - - if (get_file_size (archname) < 1) - return 1; - write_armap = 1; - arch = open_inarch (archname, (char *) NULL); - if (arch == NULL) - xexit (1); - write_archive (arch); - return 0; -} - -/* Update the timestamp of the symbol map of an archive. */ - -static int -ranlib_touch (const char *archname) -{ -#ifdef __GO32__ - /* I don't think updating works on go32. */ - ranlib_only (archname); -#else - int f; - bfd *arch; - char **matching; - - if (get_file_size (archname) < 1) - return 1; - f = open (archname, O_RDWR | O_BINARY, 0); - if (f < 0) - { - bfd_set_error (bfd_error_system_call); - bfd_fatal (archname); - } - - arch = bfd_fdopenr (archname, (const char *) NULL, f); - if (arch == NULL) - bfd_fatal (archname); - if (! bfd_check_format_matches (arch, bfd_archive, &matching)) - { - bfd_nonfatal (archname); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - xexit (1); - } - - if (! bfd_has_map (arch)) - /* xgettext:c-format */ - fatal (_("%s: no archive map to update"), archname); - - bfd_update_armap_timestamp (arch); - - if (! bfd_close (arch)) - bfd_fatal (archname); -#endif - return 0; -} - -/* Things which are interesting to map over all or some of the files: */ - -static void -print_descr (bfd *abfd) -{ - print_arelt_descr (stdout, abfd, verbose); -} diff --git a/contrib/binutils-2.22/binutils/arlex.l b/contrib/binutils-2.22/binutils/arlex.l deleted file mode 100644 index 4080580125..0000000000 --- a/contrib/binutils-2.22/binutils/arlex.l +++ /dev/null @@ -1,95 +0,0 @@ -%option noinput nounput - -%{ -/* arlex.l - Strange script language lexer */ - -/* Copyright 1992, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Contributed by Steve Chamberlain . */ - -#define DONTDECLARE_MALLOC -#include "ansidecl.h" -#include "libiberty.h" -#include "arparse.h" - -#ifndef YY_NO_UNPUT -#define YY_NO_UNPUT -#endif - -extern int yylex (void); - -int linenumber; -%} - -%a 10000 -%o 25000 - -%% - -"ADDLIB" { return ADDLIB; } -"ADDMOD" { return ADDMOD; } -"CLEAR" { return CLEAR; } -"CREATE" { return CREATE; } -"DELETE" { return DELETE; } -"DIRECTORY" { return DIRECTORY; } -"END" { return END; } -"EXTRACT" { return EXTRACT; } -"FULLDIR" { return FULLDIR; } -"HELP" { return HELP; } -"LIST" { return LIST; } -"OPEN" { return OPEN; } -"REPLACE" { return REPLACE; } -"VERBOSE" { return VERBOSE; } -"SAVE" { return SAVE; } -"addlib" { return ADDLIB; } -"addmod" { return ADDMOD; } -"clear" { return CLEAR; } -"create" { return CREATE; } -"delete" { return DELETE; } -"directory" { return DIRECTORY; } -"end" { return END; } -"extract" { return EXTRACT; } -"fulldir" { return FULLDIR; } -"help" { return HELP; } -"list" { return LIST; } -"open" { return OPEN; } -"replace" { return REPLACE; } -"verbose" { return VERBOSE; } -"save" { return SAVE; } -"+\n" { linenumber ++; } -"(" { return '('; } -")" { return ')'; } -"," { return ','; } -[A-Za-z0-9/\\$:.\-\_]+ { - yylval.name = xstrdup (yytext); - return FILENAME; - } -"*".* { } -";".* { } -" " { } -"\n" { linenumber ++; return NEWLINE; } - -%% -#ifndef yywrap -/* Needed for lex, though not flex. */ -int yywrap(void) { return 1; } -#endif diff --git a/contrib/binutils-2.22/binutils/arparse.y b/contrib/binutils-2.22/binutils/arparse.y deleted file mode 100644 index 113c5483b9..0000000000 --- a/contrib/binutils-2.22/binutils/arparse.y +++ /dev/null @@ -1,204 +0,0 @@ -%{ -/* arparse.y - Stange script language parser */ - -/* Copyright 1992, 1993, 1995, 1997, 1999, 2002, 2003, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Contributed by Steve Chamberlain - sac@cygnus.com - -*/ -#define DONTDECLARE_MALLOC -#include "sysdep.h" -#include "bfd.h" -#include "arsup.h" -extern int verbose; -extern int yylex (void); -static int yyerror (const char *); -%} - -%union { - char *name; -struct list *list ; - -}; - -%token NEWLINE -%token VERBOSE -%token FILENAME -%token ADDLIB -%token LIST -%token ADDMOD -%token CLEAR -%token CREATE -%token DELETE -%token DIRECTORY -%token END -%token EXTRACT -%token FULLDIR -%token HELP -%token QUIT -%token REPLACE -%token SAVE -%token OPEN - -%type modulelist -%type modulename -%type optional_filename -%% - -start: - { prompt(); } session - ; - -session: - session command_line - | - ; - -command_line: - command NEWLINE { prompt(); } - ; - -command: - open_command - | create_command - | verbose_command - | directory_command - | addlib_command - | clear_command - | addmod_command - | save_command - | extract_command - | replace_command - | delete_command - | list_command - | END { ar_end(); return 0; } - | error - | FILENAME { yyerror("foo"); } - | - ; - - -extract_command: - EXTRACT modulename - { ar_extract($2); } - ; - -replace_command: - REPLACE modulename - { ar_replace($2); } - ; - -clear_command: - CLEAR - { ar_clear(); } - ; - -delete_command: - DELETE modulename - { ar_delete($2); } - ; -addmod_command: - ADDMOD modulename - { ar_addmod($2); } - ; - -list_command: - LIST - { ar_list(); } - ; - -save_command: - SAVE - { ar_save(); } - ; - - - -open_command: - OPEN FILENAME - { ar_open($2,0); } - ; - -create_command: - CREATE FILENAME - { ar_open($2,1); } - ; - - -addlib_command: - ADDLIB FILENAME modulelist - { ar_addlib($2,$3); } - ; -directory_command: - DIRECTORY FILENAME modulelist optional_filename - { ar_directory($2, $3, $4); } - ; - - - -optional_filename: - FILENAME - { $$ = $1; } - | { $$ = 0; } - ; - -modulelist: - '(' modulename ')' - { $$ = $2; } - | - { $$ = 0; } - ; - -modulename: - modulename optcomma FILENAME - { struct list *n = (struct list *) malloc(sizeof(struct list)); - n->next = $1; - n->name = $3; - $$ = n; - } - | { $$ = 0; } - ; - - -optcomma: - ',' - | - ; - - -verbose_command: - VERBOSE - { verbose = !verbose; } - ; - - -%% - -static int -yyerror (const char *x ATTRIBUTE_UNUSED) -{ - extern int linenumber; - - printf (_("Syntax error in archive script, line %d\n"), linenumber + 1); - return 0; -} diff --git a/contrib/binutils-2.22/binutils/arsup.c b/contrib/binutils-2.22/binutils/arsup.c deleted file mode 100644 index 9ddc55d64a..0000000000 --- a/contrib/binutils-2.22/binutils/arsup.c +++ /dev/null @@ -1,481 +0,0 @@ -/* arsup.c - Archive support for MRI compatibility - Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2007, 2008 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Contributed by Steve Chamberlain - sac@cygnus.com - - This file looks after requests from arparse.y, to provide the MRI - style librarian command syntax + 1 word LIST. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "filenames.h" -#include "bucomm.h" -#include "arsup.h" - -static void map_over_list - (bfd *, void (*function) (bfd *, bfd *), struct list *); -static void ar_directory_doer (bfd *, bfd *); -static void ar_addlib_doer (bfd *, bfd *); - -extern int verbose; - -static bfd *obfd; -static char *real_name; -static FILE *outfile; - -static void -map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list) -{ - bfd *head; - - if (list == NULL) - { - bfd *next; - - head = arch->archive_next; - while (head != NULL) - { - next = head->archive_next; - function (head, (bfd *) NULL); - head = next; - } - } - else - { - struct list *ptr; - - /* This may appear to be a baroque way of accomplishing what we - want. however we have to iterate over the filenames in order - to notice where a filename is requested but does not exist in - the archive. Ditto mapping over each file each time -- we - want to hack multiple references. */ - for (ptr = list; ptr; ptr = ptr->next) - { - bfd_boolean found = FALSE; - bfd *prev = arch; - - for (head = arch->archive_next; head; head = head->archive_next) - { - if (head->filename != NULL - && FILENAME_CMP (ptr->name, head->filename) == 0) - { - found = TRUE; - function (head, prev); - } - prev = head; - } - if (! found) - fprintf (stderr, _("No entry %s in archive.\n"), ptr->name); - } - } -} - - - -static void -ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED) -{ - print_arelt_descr(outfile, abfd, verbose); -} - -void -ar_directory (char *ar_name, struct list *list, char *output) -{ - bfd *arch; - - arch = open_inarch (ar_name, (char *) NULL); - if (output) - { - outfile = fopen(output,"w"); - if (outfile == 0) - { - outfile = stdout; - fprintf (stderr,_("Can't open file %s\n"), output); - output = 0; - } - } - else - outfile = stdout; - - map_over_list (arch, ar_directory_doer, list); - - bfd_close (arch); - - if (output) - fclose (outfile); -} - -void -prompt (void) -{ - extern int interactive; - - if (interactive) - { - printf ("AR >"); - fflush (stdout); - } -} - -void -maybequit (void) -{ - if (! interactive) - xexit (9); -} - - -void -ar_open (char *name, int t) -{ - char *tname = (char *) xmalloc (strlen (name) + 10); - const char *bname = lbasename (name); - real_name = name; - - /* Prepend tmp- to the beginning, to avoid file-name clashes after - truncation on filesystems with limited namespaces (DOS). */ - sprintf (tname, "%.*stmp-%s", (int) (bname - name), name, bname); - obfd = bfd_openw (tname, NULL); - - if (!obfd) - { - fprintf (stderr, - _("%s: Can't open output archive %s\n"), - program_name, tname); - - maybequit (); - } - else - { - if (!t) - { - bfd **ptr; - bfd *element; - bfd *ibfd; - - ibfd = bfd_openr (name, NULL); - - if (!ibfd) - { - fprintf (stderr,_("%s: Can't open input archive %s\n"), - program_name, name); - maybequit (); - return; - } - - if (!bfd_check_format(ibfd, bfd_archive)) - { - fprintf (stderr, - _("%s: file %s is not an archive\n"), - program_name, name); - maybequit (); - return; - } - - ptr = &(obfd->archive_head); - element = bfd_openr_next_archived_file (ibfd, NULL); - - while (element) - { - *ptr = element; - ptr = &element->archive_next; - element = bfd_openr_next_archived_file (ibfd, element); - } - } - - bfd_set_format (obfd, bfd_archive); - - obfd->has_armap = 1; - obfd->is_thin_archive = 0; - } -} - -static void -ar_addlib_doer (bfd *abfd, bfd *prev) -{ - /* Add this module to the output bfd. */ - if (prev != NULL) - prev->archive_next = abfd->archive_next; - - abfd->archive_next = obfd->archive_head; - obfd->archive_head = abfd; -} - -void -ar_addlib (char *name, struct list *list) -{ - if (obfd == NULL) - { - fprintf (stderr, _("%s: no output archive specified yet\n"), program_name); - maybequit (); - } - else - { - bfd *arch; - - arch = open_inarch (name, (char *) NULL); - if (arch != NULL) - map_over_list (arch, ar_addlib_doer, list); - - /* Don't close the bfd, since it will make the elements disappear. */ - } -} - -void -ar_addmod (struct list *list) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open output archive\n"), program_name); - maybequit (); - } - else - { - while (list) - { - bfd *abfd = bfd_openr (list->name, NULL); - - if (!abfd) - { - fprintf (stderr, _("%s: can't open file %s\n"), - program_name, list->name); - maybequit (); - } - else - { - abfd->archive_next = obfd->archive_head; - obfd->archive_head = abfd; - } - list = list->next; - } - } -} - - -void -ar_clear (void) -{ - if (obfd) - obfd->archive_head = 0; -} - -void -ar_delete (struct list *list) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open output archive\n"), program_name); - maybequit (); - } - else - { - while (list) - { - /* Find this name in the archive. */ - bfd *member = obfd->archive_head; - bfd **prev = &(obfd->archive_head); - int found = 0; - - while (member) - { - if (FILENAME_CMP(member->filename, list->name) == 0) - { - *prev = member->archive_next; - found = 1; - } - else - prev = &(member->archive_next); - - member = member->archive_next; - } - - if (!found) - { - fprintf (stderr, _("%s: can't find module file %s\n"), - program_name, list->name); - maybequit (); - } - - list = list->next; - } - } -} - -void -ar_save (void) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open output archive\n"), program_name); - maybequit (); - } - else - { - char *ofilename = xstrdup (bfd_get_filename (obfd)); - - bfd_close (obfd); - - smart_rename (ofilename, real_name, 0); - obfd = 0; - free (ofilename); - } -} - -void -ar_replace (struct list *list) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open output archive\n"), program_name); - maybequit (); - } - else - { - while (list) - { - /* Find this name in the archive. */ - bfd *member = obfd->archive_head; - bfd **prev = &(obfd->archive_head); - int found = 0; - - while (member) - { - if (FILENAME_CMP (member->filename, list->name) == 0) - { - /* Found the one to replace. */ - bfd *abfd = bfd_openr (list->name, 0); - - if (!abfd) - { - fprintf (stderr, _("%s: can't open file %s\n"), - program_name, list->name); - maybequit (); - } - else - { - *prev = abfd; - abfd->archive_next = member->archive_next; - found = 1; - } - } - else - { - prev = &(member->archive_next); - } - member = member->archive_next; - } - - if (!found) - { - bfd *abfd = bfd_openr (list->name, 0); - - fprintf (stderr,_("%s: can't find module file %s\n"), - program_name, list->name); - if (!abfd) - { - fprintf (stderr, _("%s: can't open file %s\n"), - program_name, list->name); - maybequit (); - } - else - *prev = abfd; - } - - list = list->next; - } - } -} - -/* And I added this one. */ -void -ar_list (void) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open output archive\n"), program_name); - maybequit (); - } - else - { - bfd *abfd; - - outfile = stdout; - verbose =1 ; - printf (_("Current open archive is %s\n"), bfd_get_filename (obfd)); - - for (abfd = obfd->archive_head; - abfd != (bfd *)NULL; - abfd = abfd->archive_next) - ar_directory_doer (abfd, (bfd *) NULL); - } -} - -void -ar_end (void) -{ - if (obfd) - { - bfd_cache_close (obfd); - unlink (bfd_get_filename (obfd)); - } -} - -void -ar_extract (struct list *list) -{ - if (!obfd) - { - fprintf (stderr, _("%s: no open archive\n"), program_name); - maybequit (); - } - else - { - while (list) - { - /* Find this name in the archive. */ - bfd *member = obfd->archive_head; - int found = 0; - - while (member && !found) - { - if (FILENAME_CMP (member->filename, list->name) == 0) - { - extract_file (member); - found = 1; - } - - member = member->archive_next; - } - - if (!found) - { - bfd_openr (list->name, 0); - fprintf (stderr, _("%s: can't find module file %s\n"), - program_name, list->name); - } - - list = list->next; - } - } -} diff --git a/contrib/binutils-2.22/binutils/arsup.h b/contrib/binutils-2.22/binutils/arsup.h deleted file mode 100644 index 5b176810af..0000000000 --- a/contrib/binutils-2.22/binutils/arsup.h +++ /dev/null @@ -1,63 +0,0 @@ -/* arsup.h - archive support header file - Copyright 1992, 1993, 1994, 1996, 2001, 2002, 2003, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -struct list { - char *name; - struct list *next; -}; - -void maybequit (void); - -void prompt (void); - -void ar_clear (void); - -void ar_replace (struct list *); - -void ar_delete (struct list *); - -void ar_save (void); - -void ar_list (void); - -void ar_open (char *, int); - -void ar_directory (char *, struct list *, char *); - -void ar_addmod (struct list *); - -void ar_addlib (char *, struct list *); - -void ar_end (void); - -void ar_extract (struct list *); - -bfd *open_inarch (const char *archive_filename, const char *); - -extern int yylex (void); - -int yyparse (void); - -/* Functions from ar.c */ - -void extract_file (bfd * abfd); - -extern int interactive; diff --git a/contrib/binutils-2.22/binutils/binemul.c b/contrib/binutils-2.22/binutils/binemul.c deleted file mode 100644 index 6bfcb15a85..0000000000 --- a/contrib/binutils-2.22/binutils/binemul.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Binutils emulation layer. - Copyright 2002, 2003, 2005, 2007, 2008, 2010 - Free Software Foundation, Inc. - Written by Tom Rix, Red Hat Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "binemul.h" - -extern bin_emulation_xfer_type bin_dummy_emulation; - -void -ar_emul_usage (FILE *fp) -{ - if (bin_dummy_emulation.ar_usage) - bin_dummy_emulation.ar_usage (fp); -} - -void -ar_emul_default_usage (FILE *fp) -{ - AR_EMUL_USAGE_PRINT_OPTION_HEADER (fp); - /* xgettext:c-format */ - fprintf (fp, _(" No emulation specific options\n")); -} - -bfd_boolean -ar_emul_append (bfd **after_bfd, char *file_name, const char *target, - bfd_boolean verbose, bfd_boolean flatten) -{ - if (bin_dummy_emulation.ar_append) - return bin_dummy_emulation.ar_append (after_bfd, file_name, target, - verbose, flatten); - - return FALSE; -} - -static bfd_boolean -any_ok (bfd *new_bfd ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -bfd_boolean -do_ar_emul_append (bfd **after_bfd, bfd *new_bfd, - bfd_boolean verbose, bfd_boolean flatten, - bfd_boolean (*check) (bfd *)) -{ - /* When flattening, add the members of an archive instead of the - archive itself. */ - if (flatten && bfd_check_format (new_bfd, bfd_archive)) - { - bfd *elt; - bfd_boolean added = FALSE; - - for (elt = bfd_openr_next_archived_file (new_bfd, NULL); - elt; - elt = bfd_openr_next_archived_file (new_bfd, elt)) - { - if (do_ar_emul_append (after_bfd, elt, verbose, TRUE, check)) - { - added = TRUE; - after_bfd = &((*after_bfd)->archive_next); - } - } - - return added; - } - - if (!check (new_bfd)) - return FALSE; - - AR_EMUL_APPEND_PRINT_VERBOSE (verbose, new_bfd->filename); - - new_bfd->archive_next = *after_bfd; - *after_bfd = new_bfd; - - return TRUE; -} - -bfd_boolean -ar_emul_default_append (bfd **after_bfd, char *file_name, - const char *target, bfd_boolean verbose, - bfd_boolean flatten) -{ - bfd *new_bfd; - - new_bfd = bfd_openr (file_name, target); - AR_EMUL_ELEMENT_CHECK (new_bfd, file_name); - return do_ar_emul_append (after_bfd, new_bfd, verbose, flatten, any_ok); -} - -bfd_boolean -ar_emul_replace (bfd **after_bfd, char *file_name, const char *target, - bfd_boolean verbose) -{ - if (bin_dummy_emulation.ar_replace) - return bin_dummy_emulation.ar_replace (after_bfd, file_name, - target, verbose); - - return FALSE; -} - -bfd_boolean -ar_emul_default_replace (bfd **after_bfd, char *file_name, - const char *target, bfd_boolean verbose) -{ - bfd *new_bfd; - - new_bfd = bfd_openr (file_name, target); - AR_EMUL_ELEMENT_CHECK (new_bfd, file_name); - - AR_EMUL_REPLACE_PRINT_VERBOSE (verbose, file_name); - - new_bfd->archive_next = *after_bfd; - *after_bfd = new_bfd; - - return TRUE; -} - -bfd_boolean -ar_emul_parse_arg (char *arg) -{ - if (bin_dummy_emulation.ar_parse_arg) - return bin_dummy_emulation.ar_parse_arg (arg); - - return FALSE; -} - -bfd_boolean -ar_emul_default_parse_arg (char *arg ATTRIBUTE_UNUSED) -{ - return FALSE; -} diff --git a/contrib/binutils-2.22/binutils/binemul.h b/contrib/binutils-2.22/binutils/binemul.h deleted file mode 100644 index a93b7b0bd1..0000000000 --- a/contrib/binutils-2.22/binutils/binemul.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Binutils emulation layer. - Copyright 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. - Written by Tom Rix, Red Hat Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef BINEMUL_H -#define BINEMUL_H - -#include "sysdep.h" -#include "bfd.h" -#include "bucomm.h" - -extern void ar_emul_usage (FILE *); -extern void ar_emul_default_usage (FILE *); -extern bfd_boolean ar_emul_append (bfd **, char *, const char *, - bfd_boolean, bfd_boolean); -extern bfd_boolean ar_emul_default_append (bfd **, char *, const char *, - bfd_boolean, bfd_boolean); -extern bfd_boolean do_ar_emul_append (bfd **, bfd *, - bfd_boolean, bfd_boolean, - bfd_boolean (*)(bfd *)); -extern bfd_boolean ar_emul_replace (bfd **, char *, const char *, - bfd_boolean); -extern bfd_boolean ar_emul_default_replace (bfd **, char *, - const char *, bfd_boolean); -extern bfd_boolean ar_emul_parse_arg (char *); -extern bfd_boolean ar_emul_default_parse_arg (char *); - -/* Macros for common output. */ - -#define AR_EMUL_USAGE_PRINT_OPTION_HEADER(fp) \ - /* xgettext:c-format */ \ - fprintf (fp, _(" emulation options: \n")) - -#define AR_EMUL_ELEMENT_CHECK(abfd, file_name) \ - do { if ((abfd) == NULL) bfd_fatal (file_name); } while (0) - -#define AR_EMUL_APPEND_PRINT_VERBOSE(verbose, file_name) \ - do { if (verbose) printf ("a - %s\n", file_name); } while (0) - -#define AR_EMUL_REPLACE_PRINT_VERBOSE(verbose, file_name) \ - do { if (verbose) printf ("r - %s\n", file_name); } while (0) - -typedef struct bin_emulation_xfer_struct -{ - /* Print out the extra options. */ - void (* ar_usage) (FILE *fp); - bfd_boolean (* ar_append) (bfd **, char *, const char *, bfd_boolean, - bfd_boolean); - bfd_boolean (* ar_replace) (bfd **, char *, const char *, bfd_boolean); - bfd_boolean (* ar_parse_arg) (char *); -} -bin_emulation_xfer_type; - -#endif diff --git a/contrib/binutils-2.22/binutils/bucomm.c b/contrib/binutils-2.22/binutils/bucomm.c deleted file mode 100644 index 9977b50137..0000000000 --- a/contrib/binutils-2.22/binutils/bucomm.c +++ /dev/null @@ -1,625 +0,0 @@ -/* bucomm.c -- Bin Utils COMmon code. - Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, - 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* We might put this in a library someday so it could be dynamically - loaded, but for now it's not necessary. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "filenames.h" -#include "libbfd.h" - -#include -#include /* ctime, maybe time_t */ -#include -#include "bucomm.h" - -#ifndef HAVE_TIME_T_IN_TIME_H -#ifndef HAVE_TIME_T_IN_TYPES_H -typedef long time_t; -#endif -#endif - -static const char * endian_string (enum bfd_endian); -static int display_target_list (void); -static int display_info_table (int, int); -static int display_target_tables (void); - -/* Error reporting. */ - -char *program_name; - -void -bfd_nonfatal (const char *string) -{ - const char *errmsg; - - errmsg = bfd_errmsg (bfd_get_error ()); - fflush (stdout); - if (string) - fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg); - else - fprintf (stderr, "%s: %s\n", program_name, errmsg); -} - -/* Issue a non fatal error message. FILENAME, or if NULL then BFD, - are used to indicate the problematic file. SECTION, if non NULL, - is used to provide a section name. If FORMAT is non-null, then it - is used to print additional information via vfprintf. Finally the - bfd error message is printed. In summary, error messages are of - one of the following forms: - - PROGRAM:file: bfd-error-message - PROGRAM:file[section]: bfd-error-message - PROGRAM:file: printf-message: bfd-error-message - PROGRAM:file[section]: printf-message: bfd-error-message. */ - -void -bfd_nonfatal_message (const char *filename, - const bfd *abfd, - const asection *section, - const char *format, ...) -{ - const char *errmsg; - const char *section_name; - va_list args; - - errmsg = bfd_errmsg (bfd_get_error ()); - fflush (stdout); - section_name = NULL; - va_start (args, format); - fprintf (stderr, "%s", program_name); - - if (abfd) - { - if (!filename) - filename = bfd_get_archive_filename (abfd); - if (section) - section_name = bfd_get_section_name (abfd, section); - } - if (section_name) - fprintf (stderr, ":%s[%s]", filename, section_name); - else - fprintf (stderr, ":%s", filename); - - if (format) - { - fprintf (stderr, ": "); - vfprintf (stderr, format, args); - } - fprintf (stderr, ": %s\n", errmsg); - va_end (args); -} - -void -bfd_fatal (const char *string) -{ - bfd_nonfatal (string); - xexit (1); -} - -void -report (const char * format, va_list args) -{ - fflush (stdout); - fprintf (stderr, "%s: ", program_name); - vfprintf (stderr, format, args); - putc ('\n', stderr); -} - -void -fatal VPARAMS ((const char *format, ...)) -{ - VA_OPEN (args, format); - VA_FIXEDARG (args, const char *, format); - - report (format, args); - VA_CLOSE (args); - xexit (1); -} - -void -non_fatal VPARAMS ((const char *format, ...)) -{ - VA_OPEN (args, format); - VA_FIXEDARG (args, const char *, format); - - report (format, args); - VA_CLOSE (args); -} - -/* Set the default BFD target based on the configured target. Doing - this permits the binutils to be configured for a particular target, - and linked against a shared BFD library which was configured for a - different target. */ - -void -set_default_bfd_target (void) -{ - /* The macro TARGET is defined by Makefile. */ - const char *target = TARGET; - - if (! bfd_set_default_target (target)) - fatal (_("can't set BFD default target to `%s': %s"), - target, bfd_errmsg (bfd_get_error ())); -} - -/* After a FALSE return from bfd_check_format_matches with - bfd_get_error () == bfd_error_file_ambiguously_recognized, print - the possible matching targets. */ - -void -list_matching_formats (char **p) -{ - fflush (stdout); - fprintf (stderr, _("%s: Matching formats:"), program_name); - while (*p) - fprintf (stderr, " %s", *p++); - fputc ('\n', stderr); -} - -/* List the supported targets. */ - -void -list_supported_targets (const char *name, FILE *f) -{ - int t; - const char **targ_names; - - if (name == NULL) - fprintf (f, _("Supported targets:")); - else - fprintf (f, _("%s: supported targets:"), name); - - targ_names = bfd_target_list (); - for (t = 0; targ_names[t] != NULL; t++) - fprintf (f, " %s", targ_names[t]); - fprintf (f, "\n"); - free (targ_names); -} - -/* List the supported architectures. */ - -void -list_supported_architectures (const char *name, FILE *f) -{ - const char ** arch; - const char ** arches; - - if (name == NULL) - fprintf (f, _("Supported architectures:")); - else - fprintf (f, _("%s: supported architectures:"), name); - - for (arch = arches = bfd_arch_list (); *arch; arch++) - fprintf (f, " %s", *arch); - fprintf (f, "\n"); - free (arches); -} - -/* The length of the longest architecture name + 1. */ -#define LONGEST_ARCH sizeof ("powerpc:common") - -static const char * -endian_string (enum bfd_endian endian) -{ - switch (endian) - { - case BFD_ENDIAN_BIG: return "big endian"; - case BFD_ENDIAN_LITTLE: return "little endian"; - default: return "endianness unknown"; - } -} - -/* List the targets that BFD is configured to support, each followed - by its endianness and the architectures it supports. */ - -static int -display_target_list (void) -{ - char *dummy_name; - int t; - int ret = 1; - - dummy_name = make_temp_file (NULL); - for (t = 0; bfd_target_vector[t]; t++) - { - const bfd_target *p = bfd_target_vector[t]; - bfd *abfd = bfd_openw (dummy_name, p->name); - int a; - - printf ("%s\n (header %s, data %s)\n", p->name, - endian_string (p->header_byteorder), - endian_string (p->byteorder)); - - if (abfd == NULL) - { - bfd_nonfatal (dummy_name); - ret = 0; - continue; - } - - if (! bfd_set_format (abfd, bfd_object)) - { - if (bfd_get_error () != bfd_error_invalid_operation) - { - bfd_nonfatal (p->name); - ret = 0; - } - bfd_close_all_done (abfd); - continue; - } - - for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++) - if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0)) - printf (" %s\n", - bfd_printable_arch_mach ((enum bfd_architecture) a, 0)); - bfd_close_all_done (abfd); - } - unlink (dummy_name); - free (dummy_name); - - return ret; -} - -/* Print a table showing which architectures are supported for entries - FIRST through LAST-1 of bfd_target_vector (targets across, - architectures down). */ - -static int -display_info_table (int first, int last) -{ - int t; - int ret = 1; - char *dummy_name; - int a; - - /* Print heading of target names. */ - printf ("\n%*s", (int) LONGEST_ARCH, " "); - for (t = first; t < last && bfd_target_vector[t]; t++) - printf ("%s ", bfd_target_vector[t]->name); - putchar ('\n'); - - dummy_name = make_temp_file (NULL); - for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++) - if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0), - "UNKNOWN!") != 0) - { - printf ("%*s ", (int) LONGEST_ARCH - 1, - bfd_printable_arch_mach ((enum bfd_architecture) a, 0)); - for (t = first; t < last && bfd_target_vector[t]; t++) - { - const bfd_target *p = bfd_target_vector[t]; - bfd_boolean ok = TRUE; - bfd *abfd = bfd_openw (dummy_name, p->name); - - if (abfd == NULL) - { - bfd_nonfatal (p->name); - ret = 0; - ok = FALSE; - } - - if (ok) - { - if (! bfd_set_format (abfd, bfd_object)) - { - if (bfd_get_error () != bfd_error_invalid_operation) - { - bfd_nonfatal (p->name); - ret = 0; - } - ok = FALSE; - } - } - - if (ok) - { - if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0)) - ok = FALSE; - } - - if (ok) - printf ("%s ", p->name); - else - { - int l = strlen (p->name); - while (l--) - putchar ('-'); - putchar (' '); - } - if (abfd != NULL) - bfd_close_all_done (abfd); - } - putchar ('\n'); - } - unlink (dummy_name); - free (dummy_name); - - return ret; -} - -/* Print tables of all the target-architecture combinations that - BFD has been configured to support. */ - -static int -display_target_tables (void) -{ - int t; - int columns; - int ret = 1; - char *colum; - - columns = 0; - colum = getenv ("COLUMNS"); - if (colum != NULL) - columns = atoi (colum); - if (columns == 0) - columns = 80; - - t = 0; - while (bfd_target_vector[t] != NULL) - { - int oldt = t, wid; - - wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1; - ++t; - while (wid < columns && bfd_target_vector[t] != NULL) - { - int newwid; - - newwid = wid + strlen (bfd_target_vector[t]->name) + 1; - if (newwid >= columns) - break; - wid = newwid; - ++t; - } - if (! display_info_table (oldt, t)) - ret = 0; - } - - return ret; -} - -int -display_info (void) -{ - printf (_("BFD header file version %s\n"), BFD_VERSION_STRING); - if (! display_target_list () || ! display_target_tables ()) - return 1; - else - return 0; -} - -/* Display the archive header for an element as if it were an ls -l listing: - - Mode User\tGroup\tSize\tDate Name */ - -void -print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose) -{ - struct stat buf; - - if (verbose) - { - if (bfd_stat_arch_elt (abfd, &buf) == 0) - { - char modebuf[11]; - char timebuf[40]; - time_t when = buf.st_mtime; - const char *ctime_result = (const char *) ctime (&when); - - /* POSIX format: skip weekday and seconds from ctime output. */ - sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20); - - mode_string (buf.st_mode, modebuf); - modebuf[10] = '\0'; - /* POSIX 1003.2/D11 says to skip first character (entry type). */ - fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1, - (long) buf.st_uid, (long) buf.st_gid, - (long) buf.st_size, timebuf); - } - } - - fprintf (file, "%s\n", bfd_get_filename (abfd)); -} - -/* Return a path for a new temporary file in the same directory - as file PATH. */ - -static char * -template_in_dir (const char *path) -{ -#define template "stXXXXXX" - const char *slash = strrchr (path, '/'); - char *tmpname; - size_t len; - -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - { - /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ - char *bslash = strrchr (path, '\\'); - - if (slash == NULL || (bslash != NULL && bslash > slash)) - slash = bslash; - if (slash == NULL && path[0] != '\0' && path[1] == ':') - slash = path + 1; - } -#endif - - if (slash != (char *) NULL) - { - len = slash - path; - tmpname = (char *) xmalloc (len + sizeof (template) + 2); - memcpy (tmpname, path, len); - -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* If tmpname is "X:", appending a slash will make it a root - directory on drive X, which is NOT the same as the current - directory on drive X. */ - if (len == 2 && tmpname[1] == ':') - tmpname[len++] = '.'; -#endif - tmpname[len++] = '/'; - } - else - { - tmpname = (char *) xmalloc (sizeof (template)); - len = 0; - } - - memcpy (tmpname + len, template, sizeof (template)); - return tmpname; -#undef template -} - -/* Return the name of a created temporary file in the same directory - as FILENAME. */ - -char * -make_tempname (char *filename) -{ - char *tmpname = template_in_dir (filename); - int fd; - -#ifdef HAVE_MKSTEMP - fd = mkstemp (tmpname); -#else - tmpname = mktemp (tmpname); - if (tmpname == NULL) - return NULL; - fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600); -#endif - if (fd == -1) - { - free (tmpname); - return NULL; - } - close (fd); - return tmpname; -} - -/* Return the name of a created temporary directory inside the - directory containing FILENAME. */ - -char * -make_tempdir (char *filename) -{ - char *tmpname = template_in_dir (filename); - -#ifdef HAVE_MKDTEMP - return mkdtemp (tmpname); -#else - tmpname = mktemp (tmpname); - if (tmpname == NULL) - return NULL; -#if defined (_WIN32) && !defined (__CYGWIN32__) - if (mkdir (tmpname) != 0) - return NULL; -#else - if (mkdir (tmpname, 0700) != 0) - return NULL; -#endif - return tmpname; -#endif -} - -/* Parse a string into a VMA, with a fatal error if it can't be - parsed. */ - -bfd_vma -parse_vma (const char *s, const char *arg) -{ - bfd_vma ret; - const char *end; - - ret = bfd_scan_vma (s, &end, 0); - - if (*end != '\0') - fatal (_("%s: bad number: %s"), arg, s); - - return ret; -} - -/* Returns the size of the named file. If the file does not - exist, or if it is not a real file, then a suitable non-fatal - error message is printed and (off_t) -1 is returned. */ - -off_t -get_file_size (const char * file_name) -{ - struct stat statbuf; - - if (stat (file_name, &statbuf) < 0) - { - if (errno == ENOENT) - non_fatal (_("'%s': No such file"), file_name); - else - non_fatal (_("Warning: could not locate '%s'. reason: %s"), - file_name, strerror (errno)); - } - else if (! S_ISREG (statbuf.st_mode)) - non_fatal (_("Warning: '%s' is not an ordinary file"), file_name); - else if (statbuf.st_size < 0) - non_fatal (_("Warning: '%s' has negative size, probably it is too large"), - file_name); - else - return statbuf.st_size; - - return (off_t) -1; -} - -/* Return the filename in a static buffer. */ - -const char * -bfd_get_archive_filename (const bfd *abfd) -{ - static size_t curr = 0; - static char *buf; - size_t needed; - - assert (abfd != NULL); - - if (!abfd->my_archive) - return bfd_get_filename (abfd); - - needed = (strlen (bfd_get_filename (abfd->my_archive)) - + strlen (bfd_get_filename (abfd)) + 3); - if (needed > curr) - { - if (curr) - free (buf); - curr = needed + (needed >> 1); - buf = (char *) bfd_malloc (curr); - /* If we can't malloc, fail safe by returning just the file name. - This function is only used when building error messages. */ - if (!buf) - { - curr = 0; - return bfd_get_filename (abfd); - } - } - sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive), - bfd_get_filename (abfd)); - return buf; -} diff --git a/contrib/binutils-2.22/binutils/bucomm.h b/contrib/binutils-2.22/binutils/bucomm.h deleted file mode 100644 index fcbc32b738..0000000000 --- a/contrib/binutils-2.22/binutils/bucomm.h +++ /dev/null @@ -1,79 +0,0 @@ -/* bucomm.h -- binutils common include file. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#ifndef _BUCOMM_H -#define _BUCOMM_H - -/* Return the filename in a static buffer. */ -const char *bfd_get_archive_filename (const bfd *); - -void bfd_nonfatal (const char *); - -void bfd_nonfatal_message (const char *, const bfd *, const asection *, - const char *, ...); - -void bfd_fatal (const char *) ATTRIBUTE_NORETURN; - -void report (const char *, va_list) ATTRIBUTE_PRINTF(1,0); - -void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; - -void non_fatal (const char *, ...) ATTRIBUTE_PRINTF_1; - -void set_default_bfd_target (void); - -void list_matching_formats (char **); - -void list_supported_targets (const char *, FILE *); - -void list_supported_architectures (const char *, FILE *); - -int display_info (void); - -void print_arelt_descr (FILE *, bfd *, bfd_boolean); - -char *make_tempname (char *); -char *make_tempdir (char *); - -bfd_vma parse_vma (const char *, const char *); - -off_t get_file_size (const char *); - -extern char *program_name; - -/* filemode.c */ -void mode_string (unsigned long, char *); - -/* version.c */ -extern void print_version (const char *); - -/* rename.c */ -extern void set_times (const char *, const struct stat *); - -extern int smart_rename (const char *, const char *, int); - -/* libiberty. */ -void *xmalloc (size_t); - -void *xrealloc (void *, size_t); - -#endif /* _BUCOMM_H */ diff --git a/contrib/binutils-2.22/binutils/budbg.h b/contrib/binutils-2.22/binutils/budbg.h deleted file mode 100644 index b9de0223dd..0000000000 --- a/contrib/binutils-2.22/binutils/budbg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* budbg.c -- Interfaces to the generic debugging information routines. - Copyright 1995, 1996, 2002, 2003, 2005, 2007, 2008 - Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef BUDBG_H -#define BUDBG_H - -#include - -/* Routine used to read generic debugging information. */ - -extern void *read_debugging_info (bfd *, asymbol **, long, bfd_boolean); - -/* Routine used to print generic debugging information. */ - -extern bfd_boolean print_debugging_info - (FILE *, void *, bfd *, asymbol **, void *, bfd_boolean); - -/* Routines used to read and write stabs information. */ - -extern void *start_stab (void *, bfd *, bfd_boolean, asymbol **, long); - -extern bfd_boolean finish_stab (void *, void *); - -extern bfd_boolean parse_stab - (void *, void *, int, int, bfd_vma, const char *); - -extern bfd_boolean write_stabs_in_sections_debugging_info - (bfd *, void *, bfd_byte **, bfd_size_type *, bfd_byte **, bfd_size_type *); - -/* Routines used to read and write IEEE debugging information. */ - -extern bfd_boolean parse_ieee (void *, bfd *, const bfd_byte *, bfd_size_type); - -extern bfd_boolean write_ieee_debugging_info (bfd *, void *); - -/* Routine used to read COFF debugging information. */ - -extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *); - -#endif diff --git a/contrib/binutils-2.22/binutils/cxxfilt.c b/contrib/binutils-2.22/binutils/cxxfilt.c deleted file mode 100644 index 770df9baf6..0000000000 --- a/contrib/binutils-2.22/binutils/cxxfilt.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Demangler for GNU C++ - main program - Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc. - Written by James Clark (jjc@jclark.uucp) - Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling - Modified by Satish Pai (pai@apollo.hp.com) for HP demangling - - This file is part of GNU Binutils. - - 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 GCC; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "demangle.h" -#include "getopt.h" -#include "safe-ctype.h" -#include "bucomm.h" - -static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE; -static int strip_underscore = TARGET_PREPENDS_UNDERSCORE; - -static const struct option long_options[] = -{ - {"strip-underscore", no_argument, NULL, '_'}, - {"format", required_argument, NULL, 's'}, - {"help", no_argument, NULL, 'h'}, - {"no-params", no_argument, NULL, 'p'}, - {"no-strip-underscores", no_argument, NULL, 'n'}, - {"no-verbose", no_argument, NULL, 'i'}, - {"types", no_argument, NULL, 't'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0} -}; - -static void -demangle_it (char *mangled_name) -{ - char *result; - unsigned int skip_first = 0; - - /* _ and $ are sometimes found at the start of function names - in assembler sources in order to distinguish them from other - names (eg register names). So skip them here. */ - if (mangled_name[0] == '.' || mangled_name[0] == '$') - ++skip_first; - if (strip_underscore && mangled_name[skip_first] == '_') - ++skip_first; - - result = cplus_demangle (mangled_name + skip_first, flags); - - if (result == NULL) - printf ("%s", mangled_name); - else - { - if (mangled_name[0] == '.') - putchar ('.'); - printf ("%s", result); - free (result); - } -} - -static void -print_demangler_list (FILE *stream) -{ - const struct demangler_engine *demangler; - - fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name); - - for (demangler = libiberty_demanglers + 1; - demangler->demangling_style != unknown_demangling; - ++demangler) - fprintf (stream, ",%s", demangler->demangling_style_name); - - fprintf (stream, "}"); -} - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, "\ -Usage: %s [options] [mangled names]\n", program_name); - fprintf (stream, "\ -Options are:\n\ - [-_|--strip-underscore] Ignore first leading underscore%s\n", - TARGET_PREPENDS_UNDERSCORE ? " (default)" : ""); - fprintf (stream, "\ - [-n|--no-strip-underscore] Do not ignore a leading underscore%s\n", - TARGET_PREPENDS_UNDERSCORE ? "" : " (default)"); - fprintf (stream, "\ - [-p|--no-params] Do not display function arguments\n\ - [-i|--no-verbose] Do not show implementation details (if any)\n\ - [-t|--types] Also attempt to demangle type encodings\n\ - [-s|--format "); - print_demangler_list (stream); - fprintf (stream, "]\n"); - - fprintf (stream, "\ - [@] Read extra options from \n\ - [-h|--help] Display this information\n\ - [-v|--version] Show the version information\n\ -Demangled names are displayed to stdout.\n\ -If a name cannot be demangled it is just echoed to stdout.\n\ -If no names are provided on the command line, stdin is read.\n"); - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO); - exit (status); -} - -/* Return the string of non-alnum characters that may occur - as a valid symbol component, in the standard assembler symbol - syntax. */ - -static const char * -standard_symbol_characters (void) -{ - return "_$."; -} - -/* Return the string of non-alnum characters that may occur - as a valid symbol name component in an HP object file. - - Note that, since HP's compiler generates object code straight from - C++ source, without going through an assembler, its mangled - identifiers can use all sorts of characters that no assembler would - tolerate, so the alphabet this function creates is a little odd. - Here are some sample mangled identifiers offered by HP: - - typeid*__XT24AddressIndExpClassMember_ - [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv - __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv - - This still seems really weird to me, since nowhere else in this - file is there anything to recognize curly brackets, parens, etc. - I've talked with Srikanth , and he assures me - this is right, but I still strongly suspect that there's a - misunderstanding here. - - If we decide it's better for c++filt to use HP's assembler syntax - to scrape identifiers out of its input, here's the definition of - the symbol name syntax from the HP assembler manual: - - Symbols are composed of uppercase and lowercase letters, decimal - digits, dollar symbol, period (.), ampersand (&), pound sign(#) and - underscore (_). A symbol can begin with a letter, digit underscore or - dollar sign. If a symbol begins with a digit, it must contain a - non-digit character. - - So have fun. */ -static const char * -hp_symbol_characters (void) -{ - return "_$.<>#,*&[]:(){}"; -} - -extern int main (int, char **); - -int -main (int argc, char **argv) -{ - int c; - const char *valid_symbols; - enum demangling_styles style = auto_demangling; - - program_name = argv[0]; - xmalloc_set_program_name (program_name); - - expandargv (&argc, &argv); - - while ((c = getopt_long (argc, argv, "_hinps:tv", long_options, (int *) 0)) != EOF) - { - switch (c) - { - case '?': - usage (stderr, 1); - break; - case 'h': - usage (stdout, 0); - case 'n': - strip_underscore = 0; - break; - case 'p': - flags &= ~ DMGL_PARAMS; - break; - case 't': - flags |= DMGL_TYPES; - break; - case 'i': - flags &= ~ DMGL_VERBOSE; - break; - case 'v': - print_version ("c++filt"); - return 0; - case '_': - strip_underscore = 1; - break; - case 's': - style = cplus_demangle_name_to_style (optarg); - if (style == unknown_demangling) - { - fprintf (stderr, "%s: unknown demangling style `%s'\n", - program_name, optarg); - return 1; - } - cplus_demangle_set_style (style); - break; - } - } - - if (optind < argc) - { - for ( ; optind < argc; optind++) - { - demangle_it (argv[optind]); - putchar ('\n'); - } - - return 0; - } - - switch (current_demangling_style) - { - case gnu_demangling: - case lucid_demangling: - case arm_demangling: - case java_demangling: - case edg_demangling: - case gnat_demangling: - case gnu_v3_demangling: - case auto_demangling: - valid_symbols = standard_symbol_characters (); - break; - case hp_demangling: - valid_symbols = hp_symbol_characters (); - break; - default: - /* Folks should explicitly indicate the appropriate alphabet for - each demangling. Providing a default would allow the - question to go unconsidered. */ - fatal ("Internal error: no symbol alphabet for current style"); - } - - for (;;) - { - static char mbuffer[32767]; - unsigned i = 0; - - c = getchar (); - /* Try to read a mangled name. */ - while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c))) - { - if (i >= sizeof (mbuffer) - 1) - break; - mbuffer[i++] = c; - c = getchar (); - } - - if (i > 0) - { - mbuffer[i] = 0; - demangle_it (mbuffer); - } - - if (c == EOF) - break; - - /* Echo the whitespace characters so that the output looks - like the input, only with the mangled names demangled. */ - putchar (c); - if (c == '\n') - fflush (stdout); - } - - fflush (stdout); - return 0; -} diff --git a/contrib/binutils-2.22/binutils/debug.c b/contrib/binutils-2.22/binutils/debug.c deleted file mode 100644 index ee0d62e8ff..0000000000 --- a/contrib/binutils-2.22/binutils/debug.c +++ /dev/null @@ -1,3371 +0,0 @@ -/* debug.c -- Handle generic debugging information. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2007, - 2009 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - - -/* This file implements a generic debugging format. We may eventually - have readers which convert different formats into this generic - format, and writers which write it out. The initial impetus for - this was writing a converter from stabs to HP IEEE-695 debugging - format. */ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "libiberty.h" -#include "filenames.h" -#include "debug.h" - -/* Global information we keep for debugging. A pointer to this - structure is the debugging handle passed to all the routines. */ - -struct debug_handle -{ - /* A linked list of compilation units. */ - struct debug_unit *units; - /* The current compilation unit. */ - struct debug_unit *current_unit; - /* The current source file. */ - struct debug_file *current_file; - /* The current function. */ - struct debug_function *current_function; - /* The current block. */ - struct debug_block *current_block; - /* The current line number information for the current unit. */ - struct debug_lineno *current_lineno; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* A struct/class ID used by debug_write. */ - unsigned int class_id; - /* The base for class_id for this call to debug_write. */ - unsigned int base_id; - /* The current line number in debug_write. */ - struct debug_lineno *current_write_lineno; - unsigned int current_write_lineno_index; - /* A list of classes which have assigned ID's during debug_write. - This is linked through the next_id field of debug_class_type. */ - struct debug_class_id *id_list; - /* A list used to avoid recursion during debug_type_samep. */ - struct debug_type_compare_list *compare_list; -}; - -/* Information we keep for a single compilation unit. */ - -struct debug_unit -{ - /* The next compilation unit. */ - struct debug_unit *next; - /* A list of files included in this compilation unit. The first - file is always the main one, and that is where the main file name - is stored. */ - struct debug_file *files; - /* Line number information for this compilation unit. This is not - stored by function, because assembler code may have line number - information without function information. */ - struct debug_lineno *linenos; -}; - -/* Information kept for a single source file. */ - -struct debug_file -{ - /* The next source file in this compilation unit. */ - struct debug_file *next; - /* The name of the source file. */ - const char *filename; - /* Global functions, variables, types, etc. */ - struct debug_namespace *globals; -}; - -/* A type. */ - -struct debug_type_s -{ - /* Kind of type. */ - enum debug_type_kind kind; - /* Size of type (0 if not known). */ - unsigned int size; - /* Type which is a pointer to this type. */ - debug_type pointer; - /* Tagged union with additional information about the type. */ - union - { - /* DEBUG_KIND_INDIRECT. */ - struct debug_indirect_type *kindirect; - /* DEBUG_KIND_INT. */ - /* Whether the integer is unsigned. */ - bfd_boolean kint; - /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS, - DEBUG_KIND_UNION_CLASS. */ - struct debug_class_type *kclass; - /* DEBUG_KIND_ENUM. */ - struct debug_enum_type *kenum; - /* DEBUG_KIND_POINTER. */ - struct debug_type_s *kpointer; - /* DEBUG_KIND_FUNCTION. */ - struct debug_function_type *kfunction; - /* DEBUG_KIND_REFERENCE. */ - struct debug_type_s *kreference; - /* DEBUG_KIND_RANGE. */ - struct debug_range_type *krange; - /* DEBUG_KIND_ARRAY. */ - struct debug_array_type *karray; - /* DEBUG_KIND_SET. */ - struct debug_set_type *kset; - /* DEBUG_KIND_OFFSET. */ - struct debug_offset_type *koffset; - /* DEBUG_KIND_METHOD. */ - struct debug_method_type *kmethod; - /* DEBUG_KIND_CONST. */ - struct debug_type_s *kconst; - /* DEBUG_KIND_VOLATILE. */ - struct debug_type_s *kvolatile; - /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */ - struct debug_named_type *knamed; - } u; -}; - -/* Information kept for an indirect type. */ - -struct debug_indirect_type -{ - /* Slot where the final type will appear. */ - debug_type *slot; - /* Tag. */ - const char *tag; -}; - -/* Information kept for a struct, union, or class. */ - -struct debug_class_type -{ - /* NULL terminated array of fields. */ - debug_field *fields; - /* A mark field which indicates whether the struct has already been - printed. */ - unsigned int mark; - /* This is used to uniquely identify unnamed structs when printing. */ - unsigned int id; - /* The remaining fields are only used for DEBUG_KIND_CLASS and - DEBUG_KIND_UNION_CLASS. */ - /* NULL terminated array of base classes. */ - debug_baseclass *baseclasses; - /* NULL terminated array of methods. */ - debug_method *methods; - /* The type of the class providing the virtual function table for - this class. This may point to the type itself. */ - debug_type vptrbase; -}; - -/* Information kept for an enum. */ - -struct debug_enum_type -{ - /* NULL terminated array of names. */ - const char **names; - /* Array of corresponding values. */ - bfd_signed_vma *values; -}; - -/* Information kept for a function. FIXME: We should be able to - record the parameter types. */ - -struct debug_function_type -{ - /* Return type. */ - debug_type return_type; - /* NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the function takes a variable number of arguments. */ - bfd_boolean varargs; -}; - -/* Information kept for a range. */ - -struct debug_range_type -{ - /* Range base type. */ - debug_type type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; -}; - -/* Information kept for an array. */ - -struct debug_array_type -{ - /* Element type. */ - debug_type element_type; - /* Range type. */ - debug_type range_type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; - /* Whether this array is really a string. */ - bfd_boolean stringp; -}; - -/* Information kept for a set. */ - -struct debug_set_type -{ - /* Base type. */ - debug_type type; - /* Whether this set is really a bitstring. */ - bfd_boolean bitstringp; -}; - -/* Information kept for an offset type (a based pointer). */ - -struct debug_offset_type -{ - /* The type the pointer is an offset from. */ - debug_type base_type; - /* The type the pointer points to. */ - debug_type target_type; -}; - -/* Information kept for a method type. */ - -struct debug_method_type -{ - /* The return type. */ - debug_type return_type; - /* The object type which this method is for. */ - debug_type domain_type; - /* A NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the method takes a variable number of arguments. */ - bfd_boolean varargs; -}; - -/* Information kept for a named type. */ - -struct debug_named_type -{ - /* Name. */ - struct debug_name *name; - /* Real type. */ - debug_type type; -}; - -/* A field in a struct or union. */ - -struct debug_field_s -{ - /* Name of the field. */ - const char *name; - /* Type of the field. */ - struct debug_type_s *type; - /* Visibility of the field. */ - enum debug_visibility visibility; - /* Whether this is a static member. */ - bfd_boolean static_member; - union - { - /* If static_member is false. */ - struct - { - /* Bit position of the field in the struct. */ - unsigned int bitpos; - /* Size of the field in bits. */ - unsigned int bitsize; - } f; - /* If static_member is true. */ - struct - { - const char *physname; - } s; - } u; -}; - -/* A base class for an object. */ - -struct debug_baseclass_s -{ - /* Type of the base class. */ - struct debug_type_s *type; - /* Bit position of the base class in the object. */ - unsigned int bitpos; - /* Whether the base class is virtual. */ - bfd_boolean is_virtual; - /* Visibility of the base class. */ - enum debug_visibility visibility; -}; - -/* A method of an object. */ - -struct debug_method_s -{ - /* The name of the method. */ - const char *name; - /* A NULL terminated array of different types of variants. */ - struct debug_method_variant_s **variants; -}; - -/* The variants of a method function of an object. These indicate - which method to run. */ - -struct debug_method_variant_s -{ - /* The physical name of the function. */ - const char *physname; - /* The type of the function. */ - struct debug_type_s *type; - /* The visibility of the function. */ - enum debug_visibility visibility; - /* Whether the function is const. */ - bfd_boolean constp; - /* Whether the function is volatile. */ - bfd_boolean volatilep; - /* The offset to the function in the virtual function table. */ - bfd_vma voffset; - /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */ -#define VOFFSET_STATIC_METHOD ((bfd_vma) -1) - /* Context of a virtual method function. */ - struct debug_type_s *context; -}; - -/* A variable. This is the information we keep for a variable object. - This has no name; a name is associated with a variable in a - debug_name structure. */ - -struct debug_variable -{ - /* Kind of variable. */ - enum debug_var_kind kind; - /* Type. */ - debug_type type; - /* Value. The interpretation of the value depends upon kind. */ - bfd_vma val; -}; - -/* A function. This has no name; a name is associated with a function - in a debug_name structure. */ - -struct debug_function -{ - /* Return type. */ - debug_type return_type; - /* Parameter information. */ - struct debug_parameter *parameters; - /* Block information. The first structure on the list is the main - block of the function, and describes function local variables. */ - struct debug_block *blocks; -}; - -/* A function parameter. */ - -struct debug_parameter -{ - /* Next parameter. */ - struct debug_parameter *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_parm_kind kind; - /* Value (meaning depends upon kind). */ - bfd_vma val; -}; - -/* A typed constant. */ - -struct debug_typed_constant -{ - /* Type. */ - debug_type type; - /* Value. FIXME: We may eventually need to support non-integral - values. */ - bfd_vma val; -}; - -/* Information about a block within a function. */ - -struct debug_block -{ - /* Next block with the same parent. */ - struct debug_block *next; - /* Parent block. */ - struct debug_block *parent; - /* List of child blocks. */ - struct debug_block *children; - /* Start address of the block. */ - bfd_vma start; - /* End address of the block. */ - bfd_vma end; - /* Local variables. */ - struct debug_namespace *locals; -}; - -/* Line number information we keep for a compilation unit. FIXME: - This structure is easy to create, but can be very space - inefficient. */ - -struct debug_lineno -{ - /* More line number information for this block. */ - struct debug_lineno *next; - /* Source file. */ - struct debug_file *file; - /* Line numbers, terminated by a -1 or the end of the array. */ -#define DEBUG_LINENO_COUNT 10 - unsigned long linenos[DEBUG_LINENO_COUNT]; - /* Addresses for the line numbers. */ - bfd_vma addrs[DEBUG_LINENO_COUNT]; -}; - -/* A namespace. This is a mapping from names to objects. FIXME: This - should be implemented as a hash table. */ - -struct debug_namespace -{ - /* List of items in this namespace. */ - struct debug_name *list; - /* Pointer to where the next item in this namespace should go. */ - struct debug_name **tail; -}; - -/* Kinds of objects that appear in a namespace. */ - -enum debug_object_kind -{ - /* A type. */ - DEBUG_OBJECT_TYPE, - /* A tagged type (really a different sort of namespace). */ - DEBUG_OBJECT_TAG, - /* A variable. */ - DEBUG_OBJECT_VARIABLE, - /* A function. */ - DEBUG_OBJECT_FUNCTION, - /* An integer constant. */ - DEBUG_OBJECT_INT_CONSTANT, - /* A floating point constant. */ - DEBUG_OBJECT_FLOAT_CONSTANT, - /* A typed constant. */ - DEBUG_OBJECT_TYPED_CONSTANT -}; - -/* Linkage of an object that appears in a namespace. */ - -enum debug_object_linkage -{ - /* Local variable. */ - DEBUG_LINKAGE_AUTOMATIC, - /* Static--either file static or function static, depending upon the - namespace is. */ - DEBUG_LINKAGE_STATIC, - /* Global. */ - DEBUG_LINKAGE_GLOBAL, - /* No linkage. */ - DEBUG_LINKAGE_NONE -}; - -/* A name in a namespace. */ - -struct debug_name -{ - /* Next name in this namespace. */ - struct debug_name *next; - /* Name. */ - const char *name; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* Kind of object. */ - enum debug_object_kind kind; - /* Linkage of object. */ - enum debug_object_linkage linkage; - /* Tagged union with additional information about the object. */ - union - { - /* DEBUG_OBJECT_TYPE. */ - struct debug_type_s *type; - /* DEBUG_OBJECT_TAG. */ - struct debug_type_s *tag; - /* DEBUG_OBJECT_VARIABLE. */ - struct debug_variable *variable; - /* DEBUG_OBJECT_FUNCTION. */ - struct debug_function *function; - /* DEBUG_OBJECT_INT_CONSTANT. */ - bfd_vma int_constant; - /* DEBUG_OBJECT_FLOAT_CONSTANT. */ - double float_constant; - /* DEBUG_OBJECT_TYPED_CONSTANT. */ - struct debug_typed_constant *typed_constant; - } u; -}; - -/* During debug_write, a linked list of these structures is used to - keep track of ID numbers that have been assigned to classes. */ - -struct debug_class_id -{ - /* Next ID number. */ - struct debug_class_id *next; - /* The type with the ID. */ - struct debug_type_s *type; - /* The tag; NULL if no tag. */ - const char *tag; -}; - -/* During debug_type_samep, a linked list of these structures is kept - on the stack to avoid infinite recursion. */ - -struct debug_type_compare_list -{ - /* Next type on list. */ - struct debug_type_compare_list *next; - /* The types we are comparing. */ - struct debug_type_s *t1; - struct debug_type_s *t2; -}; - -/* During debug_get_real_type, a linked list of these structures is - kept on the stack to avoid infinite recursion. */ - -struct debug_type_real_list -{ - /* Next type on list. */ - struct debug_type_real_list *next; - /* The type we are checking. */ - struct debug_type_s *t; -}; - -/* Local functions. */ - -static void debug_error (const char *); -static struct debug_name *debug_add_to_namespace - (struct debug_handle *, struct debug_namespace **, const char *, - enum debug_object_kind, enum debug_object_linkage); -static struct debug_name *debug_add_to_current_namespace - (struct debug_handle *, const char *, enum debug_object_kind, - enum debug_object_linkage); -static struct debug_type_s *debug_make_type - (struct debug_handle *, enum debug_type_kind, unsigned int); -static struct debug_type_s *debug_get_real_type - (void *, debug_type, struct debug_type_real_list *); -static bfd_boolean debug_write_name - (struct debug_handle *, const struct debug_write_fns *, void *, - struct debug_name *); -static bfd_boolean debug_write_type - (struct debug_handle *, const struct debug_write_fns *, void *, - struct debug_type_s *, struct debug_name *); -static bfd_boolean debug_write_class_type - (struct debug_handle *, const struct debug_write_fns *, void *, - struct debug_type_s *, const char *); -static bfd_boolean debug_write_function - (struct debug_handle *, const struct debug_write_fns *, void *, - const char *, enum debug_object_linkage, struct debug_function *); -static bfd_boolean debug_write_block - (struct debug_handle *, const struct debug_write_fns *, void *, - struct debug_block *); -static bfd_boolean debug_write_linenos - (struct debug_handle *, const struct debug_write_fns *, void *, bfd_vma); -static bfd_boolean debug_set_class_id - (struct debug_handle *, const char *, struct debug_type_s *); -static bfd_boolean debug_type_samep - (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); -static bfd_boolean debug_class_type_samep - (struct debug_handle *, struct debug_type_s *, struct debug_type_s *); - -/* Issue an error message. */ - -static void -debug_error (const char *message) -{ - fprintf (stderr, "%s\n", message); -} - -/* Add an object to a namespace. */ - -static struct debug_name * -debug_add_to_namespace (struct debug_handle *info ATTRIBUTE_UNUSED, - struct debug_namespace **nsp, const char *name, - enum debug_object_kind kind, - enum debug_object_linkage linkage) -{ - struct debug_name *n; - struct debug_namespace *ns; - - n = (struct debug_name *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->name = name; - n->kind = kind; - n->linkage = linkage; - - ns = *nsp; - if (ns == NULL) - { - ns = (struct debug_namespace *) xmalloc (sizeof *ns); - memset (ns, 0, sizeof *ns); - - ns->tail = &ns->list; - - *nsp = ns; - } - - *ns->tail = n; - ns->tail = &n->next; - - return n; -} - -/* Add an object to the current namespace. */ - -static struct debug_name * -debug_add_to_current_namespace (struct debug_handle *info, const char *name, - enum debug_object_kind kind, - enum debug_object_linkage linkage) -{ - struct debug_namespace **nsp; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error (_("debug_add_to_current_namespace: no current file")); - return NULL; - } - - if (info->current_block != NULL) - nsp = &info->current_block->locals; - else - nsp = &info->current_file->globals; - - return debug_add_to_namespace (info, nsp, name, kind, linkage); -} - -/* Return a handle for debugging information. */ - -void * -debug_init (void) -{ - struct debug_handle *ret; - - ret = (struct debug_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - return (void *) ret; -} - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -bfd_boolean -debug_set_filename (void *handle, const char *name) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *nfile; - struct debug_unit *nunit; - - if (name == NULL) - name = ""; - - nfile = (struct debug_file *) xmalloc (sizeof *nfile); - memset (nfile, 0, sizeof *nfile); - - nfile->filename = name; - - nunit = (struct debug_unit *) xmalloc (sizeof *nunit); - memset (nunit, 0, sizeof *nunit); - - nunit->files = nfile; - info->current_file = nfile; - - if (info->current_unit != NULL) - info->current_unit->next = nunit; - else - { - assert (info->units == NULL); - info->units = nunit; - } - - info->current_unit = nunit; - - info->current_function = NULL; - info->current_block = NULL; - info->current_lineno = NULL; - - return TRUE; -} - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -bfd_boolean -debug_start_source (void *handle, const char *name) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *f, **pf; - - if (name == NULL) - name = ""; - - if (info->current_unit == NULL) - { - debug_error (_("debug_start_source: no debug_set_filename call")); - return FALSE; - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (filename_cmp (f->filename, name) == 0) - { - info->current_file = f; - return TRUE; - } - } - - f = (struct debug_file *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->filename = name; - - for (pf = &info->current_file->next; - *pf != NULL; - pf = &(*pf)->next) - ; - *pf = f; - - info->current_file = f; - - return TRUE; -} - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. FIXME: There is no way to specify nested - functions. */ - -bfd_boolean -debug_record_function (void *handle, const char *name, - debug_type return_type, bfd_boolean global, - bfd_vma addr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_function *f; - struct debug_block *b; - struct debug_name *n; - - if (name == NULL) - name = ""; - if (return_type == NULL) - return FALSE; - - if (info->current_unit == NULL) - { - debug_error (_("debug_record_function: no debug_set_filename call")); - return FALSE; - } - - f = (struct debug_function *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = return_type; - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->start = addr; - b->end = (bfd_vma) -1; - - f->blocks = b; - - info->current_function = f; - info->current_block = b; - - /* FIXME: If we could handle nested functions, this would be the - place: we would want to use a different namespace. */ - n = debug_add_to_namespace (info, - &info->current_file->globals, - name, - DEBUG_OBJECT_FUNCTION, - (global - ? DEBUG_LINKAGE_GLOBAL - : DEBUG_LINKAGE_STATIC)); - if (n == NULL) - return FALSE; - - n->u.function = f; - - return TRUE; -} - -/* Record a parameter for the current function. */ - -bfd_boolean -debug_record_parameter (void *handle, const char *name, debug_type type, - enum debug_parm_kind kind, bfd_vma val) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_parameter *p, **pp; - - if (name == NULL || type == NULL) - return FALSE; - - if (info->current_unit == NULL - || info->current_function == NULL) - { - debug_error (_("debug_record_parameter: no current function")); - return FALSE; - } - - p = (struct debug_parameter *) xmalloc (sizeof *p); - memset (p, 0, sizeof *p); - - p->name = name; - p->type = type; - p->kind = kind; - p->val = val; - - for (pp = &info->current_function->parameters; - *pp != NULL; - pp = &(*pp)->next) - ; - *pp = p; - - return TRUE; -} - -/* End a function. FIXME: This should handle function nesting. */ - -bfd_boolean -debug_end_function (void *handle, bfd_vma addr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - - if (info->current_unit == NULL - || info->current_block == NULL - || info->current_function == NULL) - { - debug_error (_("debug_end_function: no current function")); - return FALSE; - } - - if (info->current_block->parent != NULL) - { - debug_error (_("debug_end_function: some blocks were not closed")); - return FALSE; - } - - info->current_block->end = addr; - - info->current_function = NULL; - info->current_block = NULL; - - return TRUE; -} - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The bfd_vma - argument is the address at which this block starts. */ - -bfd_boolean -debug_start_block (void *handle, bfd_vma addr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b, **pb; - - /* We must always have a current block: debug_record_function sets - one up. */ - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error (_("debug_start_block: no current block")); - return FALSE; - } - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->parent = info->current_block; - b->start = addr; - b->end = (bfd_vma) -1; - - /* This new block is a child of the current block. */ - for (pb = &info->current_block->children; - *pb != NULL; - pb = &(*pb)->next) - ; - *pb = b; - - info->current_block = b; - - return TRUE; -} - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -bfd_boolean -debug_end_block (void *handle, bfd_vma addr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *parent; - - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error (_("debug_end_block: no current block")); - return FALSE; - } - - parent = info->current_block->parent; - if (parent == NULL) - { - debug_error (_("debug_end_block: attempt to close top level block")); - return FALSE; - } - - info->current_block->end = addr; - - info->current_block = parent; - - return TRUE; -} - -/* Associate a line number in the current source file and function - with a given address. */ - -bfd_boolean -debug_record_line (void *handle, unsigned long lineno, bfd_vma addr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_lineno *l; - unsigned int i; - - if (info->current_unit == NULL) - { - debug_error (_("debug_record_line: no current unit")); - return FALSE; - } - - l = info->current_lineno; - if (l != NULL && l->file == info->current_file) - { - for (i = 0; i < DEBUG_LINENO_COUNT; i++) - { - if (l->linenos[i] == (unsigned long) -1) - { - l->linenos[i] = lineno; - l->addrs[i] = addr; - return TRUE; - } - } - } - - /* If we get here, then either 1) there is no current_lineno - structure, which means this is the first line number in this - compilation unit, 2) the current_lineno structure is for a - different file, or 3) the current_lineno structure is full. - Regardless, we want to allocate a new debug_lineno structure, put - it in the right place, and make it the new current_lineno - structure. */ - - l = (struct debug_lineno *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->file = info->current_file; - l->linenos[0] = lineno; - l->addrs[0] = addr; - for (i = 1; i < DEBUG_LINENO_COUNT; i++) - l->linenos[i] = (unsigned long) -1; - - if (info->current_lineno != NULL) - info->current_lineno->next = l; - else - info->current_unit->linenos = l; - - info->current_lineno = l; - - return TRUE; -} - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -bfd_boolean -debug_start_common_block (void *handle ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) -{ - /* FIXME */ - debug_error (_("debug_start_common_block: not implemented")); - return FALSE; -} - -/* End a named common block. */ - -bfd_boolean -debug_end_common_block (void *handle ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) -{ - /* FIXME */ - debug_error (_("debug_end_common_block: not implemented")); - return FALSE; -} - -/* Record a named integer constant. */ - -bfd_boolean -debug_record_int_const (void *handle, const char *name, bfd_vma val) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return FALSE; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return FALSE; - - n->u.int_constant = val; - - return TRUE; -} - -/* Record a named floating point constant. */ - -bfd_boolean -debug_record_float_const (void *handle, const char *name, double val) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return FALSE; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return FALSE; - - n->u.float_constant = val; - - return TRUE; -} - -/* Record a typed constant with an integral value. */ - -bfd_boolean -debug_record_typed_const (void *handle, const char *name, debug_type type, - bfd_vma val) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - struct debug_typed_constant *tc; - - if (name == NULL || type == NULL) - return FALSE; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return FALSE; - - tc = (struct debug_typed_constant *) xmalloc (sizeof *tc); - memset (tc, 0, sizeof *tc); - - tc->type = type; - tc->val = val; - - n->u.typed_constant = tc; - - return TRUE; -} - -/* Record a label. */ - -bfd_boolean -debug_record_label (void *handle ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - debug_type type ATTRIBUTE_UNUSED, - bfd_vma addr ATTRIBUTE_UNUSED) -{ - /* FIXME. */ - debug_error (_("debug_record_label: not implemented")); - return FALSE; -} - -/* Record a variable. */ - -bfd_boolean -debug_record_variable (void *handle, const char *name, debug_type type, - enum debug_var_kind kind, bfd_vma val) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_namespace **nsp; - enum debug_object_linkage linkage; - struct debug_name *n; - struct debug_variable *v; - - if (name == NULL || type == NULL) - return FALSE; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error (_("debug_record_variable: no current file")); - return FALSE; - } - - if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - { - nsp = &info->current_file->globals; - if (kind == DEBUG_GLOBAL) - linkage = DEBUG_LINKAGE_GLOBAL; - else - linkage = DEBUG_LINKAGE_STATIC; - } - else - { - if (info->current_block == NULL) - nsp = &info->current_file->globals; - else - nsp = &info->current_block->locals; - linkage = DEBUG_LINKAGE_AUTOMATIC; - } - - n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage); - if (n == NULL) - return FALSE; - - v = (struct debug_variable *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->kind = kind; - v->type = type; - v->val = val; - - n->u.variable = v; - - return TRUE; -} - -/* Make a type with a given kind and size. */ - -static struct debug_type_s * -debug_make_type (struct debug_handle *info ATTRIBUTE_UNUSED, - enum debug_type_kind kind, unsigned int size) -{ - struct debug_type_s *t; - - t = (struct debug_type_s *) xmalloc (sizeof *t); - memset (t, 0, sizeof *t); - - t->kind = kind; - t->size = size; - - return t; -} - -/* Make an indirect type which may be used as a placeholder for a type - which is referenced before it is defined. */ - -debug_type -debug_make_indirect_type (void *handle, debug_type *slot, const char *tag) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_indirect_type *i; - - t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - i = (struct debug_indirect_type *) xmalloc (sizeof *i); - memset (i, 0, sizeof *i); - - i->slot = slot; - i->tag = tag; - - t->u.kindirect = i; - - return t; -} - -/* Make a void type. There is only one of these. */ - -debug_type -debug_make_void_type (void *handle) -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_VOID, 0); -} - -/* Make an integer type of a given size. The boolean argument is true - if the integer is unsigned. */ - -debug_type -debug_make_int_type (void *handle, unsigned int size, bfd_boolean unsignedp) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - t = debug_make_type (info, DEBUG_KIND_INT, size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kint = unsignedp; - - return t; -} - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -debug_type -debug_make_float_type (void *handle, unsigned int size) -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_FLOAT, size); -} - -/* Make a boolean type of a given size. */ - -debug_type -debug_make_bool_type (void *handle, unsigned int size) -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_BOOL, size); -} - -/* Make a complex type of a given size. */ - -debug_type -debug_make_complex_type (void *handle, unsigned int size) -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_COMPLEX, size); -} - -/* Make a structure type. The second argument is true for a struct, - false for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -debug_type -debug_make_struct_type (void *handle, bfd_boolean structp, bfd_vma size, - debug_field *fields) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - - t->u.kclass = c; - - return t; -} - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a boolean which is true if this - object has its own virtual function table. */ - -debug_type -debug_make_object_type (void *handle, bfd_boolean structp, bfd_vma size, - debug_field *fields, debug_baseclass *baseclasses, - debug_method *methods, debug_type vptrbase, - bfd_boolean ownvptr) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - c->baseclasses = baseclasses; - c->methods = methods; - if (ownvptr) - c->vptrbase = t; - else - c->vptrbase = vptrbase; - - t->u.kclass = c; - - return t; -} - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -debug_type -debug_make_enum_type (void *handle, const char **names, - bfd_signed_vma *values) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_enum_type *e; - - t = debug_make_type (info, DEBUG_KIND_ENUM, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - e = (struct debug_enum_type *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->names = names; - e->values = values; - - t->u.kenum = e; - - return t; -} - -/* Make a pointer to a given type. */ - -debug_type -debug_make_pointer_type (void *handle, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - if (type->pointer != DEBUG_TYPE_NULL) - return type->pointer; - - t = debug_make_type (info, DEBUG_KIND_POINTER, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kpointer = type; - - type->pointer = t; - - return t; -} - -/* Make a function returning a given type. FIXME: We should be able - to record the parameter types. */ - -debug_type -debug_make_function_type (void *handle, debug_type type, - debug_type *arg_types, bfd_boolean varargs) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_function_type *f; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - f = (struct debug_function_type *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = type; - f->arg_types = arg_types; - f->varargs = varargs; - - t->u.kfunction = f; - - return t; -} - -/* Make a reference to a given type. */ - -debug_type -debug_make_reference_type (void *handle, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kreference = type; - - return t; -} - -/* Make a range of a given type from a lower to an upper bound. */ - -debug_type -debug_make_range_type (void *handle, debug_type type, bfd_signed_vma lower, - bfd_signed_vma upper) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_range_type *r; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_RANGE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - r = (struct debug_range_type *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->type = type; - r->lower = lower; - r->upper = upper; - - t->u.krange = r; - - return t; -} - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively. The sixth argument is true if this array is - actually a string, as in C. */ - -debug_type -debug_make_array_type (void *handle, debug_type element_type, - debug_type range_type, bfd_signed_vma lower, - bfd_signed_vma upper, bfd_boolean stringp) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_array_type *a; - - if (element_type == NULL || range_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_ARRAY, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - a = (struct debug_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->element_type = element_type; - a->range_type = range_type; - a->lower = lower; - a->upper = upper; - a->stringp = stringp; - - t->u.karray = a; - - return t; -} - -/* Make a set of a given type. For example, a Pascal set type. The - boolean argument is true if this set is actually a bitstring, as in - CHILL. */ - -debug_type -debug_make_set_type (void *handle, debug_type type, bfd_boolean bitstringp) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_set_type *s; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_SET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - s = (struct debug_set_type *) xmalloc (sizeof *s); - memset (s, 0, sizeof *s); - - s->type = type; - s->bitstringp = bitstringp; - - t->u.kset = s; - - return t; -} - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -debug_type -debug_make_offset_type (void *handle, debug_type base_type, - debug_type target_type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_offset_type *o; - - if (base_type == NULL || target_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_OFFSET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - o = (struct debug_offset_type *) xmalloc (sizeof *o); - memset (o, 0, sizeof *o); - - o->base_type = base_type; - o->target_type = target_type; - - t->u.koffset = o; - - return t; -} - -/* Make a type for a method function. The second argument is the - return type, the third argument is the domain, and the fourth - argument is a NULL terminated array of argument types. */ - -debug_type -debug_make_method_type (void *handle, debug_type return_type, - debug_type domain_type, debug_type *arg_types, - bfd_boolean varargs) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_method_type *m; - - if (return_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_METHOD, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - m = (struct debug_method_type *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->return_type = return_type; - m->domain_type = domain_type; - m->arg_types = arg_types; - m->varargs = varargs; - - t->u.kmethod = m; - - return t; -} - -/* Make a const qualified version of a given type. */ - -debug_type -debug_make_const_type (void *handle, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_CONST, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kconst = type; - - return t; -} - -/* Make a volatile qualified version of a given type. */ - -debug_type -debug_make_volatile_type (void *handle, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kvolatile = type; - - return t; -} - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -debug_type -debug_make_undefined_tagged_type (void *handle, const char *name, - enum debug_type_kind kind) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - - if (name == NULL) - return DEBUG_TYPE_NULL; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - case DEBUG_KIND_ENUM: - break; - - default: - debug_error (_("debug_make_undefined_type: unsupported kind")); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, kind, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - return debug_tag_type (handle, name, t); -} - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object (always 0 unless doing multiple inheritance). - The fourth argument is whether this is a virtual class. The fifth - argument is the visibility of the base class. */ - -debug_baseclass -debug_make_baseclass (void *handle ATTRIBUTE_UNUSED, debug_type type, - bfd_vma bitpos, bfd_boolean is_virtual, - enum debug_visibility visibility) -{ - struct debug_baseclass_s *b; - - b = (struct debug_baseclass_s *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->type = type; - b->bitpos = bitpos; - b->is_virtual = is_virtual; - b->visibility = visibility; - - return b; -} - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -debug_field -debug_make_field (void *handle ATTRIBUTE_UNUSED, const char *name, - debug_type type, bfd_vma bitpos, bfd_vma bitsize, - enum debug_visibility visibility) -{ - struct debug_field_s *f; - - f = (struct debug_field_s *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = FALSE; - f->u.f.bitpos = bitpos; - f->u.f.bitsize = bitsize; - f->visibility = visibility; - - return f; -} - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -debug_field -debug_make_static_member (void *handle ATTRIBUTE_UNUSED, const char *name, - debug_type type, const char *physname, - enum debug_visibility visibility) -{ - struct debug_field_s *f; - - f = (struct debug_field_s *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = TRUE; - f->u.s.physname = physname; - f->visibility = visibility; - - return f; -} - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. */ - -debug_method -debug_make_method (void *handle ATTRIBUTE_UNUSED, const char *name, - debug_method_variant *variants) -{ - struct debug_method_s *m; - - m = (struct debug_method_s *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->name = name; - m->variants = variants; - - return m; -} - -/* Make a method argument. The second argument is the real name of - the function. The third argument is the type of the function. The - fourth argument is the visibility. The fifth argument is whether - this is a const function. The sixth argument is whether this is a - volatile function. The seventh argument is the offset in the - virtual function table, if any. The eighth argument is the virtual - function context. FIXME: Are the const and volatile arguments - necessary? Could we just use debug_make_const_type? */ - -debug_method_variant -debug_make_method_variant (void *handle ATTRIBUTE_UNUSED, - const char *physname, debug_type type, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep, - bfd_vma voffset, debug_type context) -{ - struct debug_method_variant_s *m; - - m = (struct debug_method_variant_s *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = voffset; - m->context = context; - - return m; -} - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -debug_method_variant -debug_make_static_method_variant (void *handle ATTRIBUTE_UNUSED, - const char *physname, debug_type type, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep) -{ - struct debug_method_variant_s *m; - - m = (struct debug_method_variant_s *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = VOFFSET_STATIC_METHOD; - - return m; -} - -/* Name a type. */ - -debug_type -debug_name_type (void *handle, const char *name, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error (_("debug_name_type: no current file")); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, DEBUG_KIND_NAMED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We always add the name to the global namespace. This is probably - wrong in some cases, but it seems to be right for stabs. FIXME. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.type = t; - - n->name = nm; - - return t; -} - -/* Tag a type. */ - -debug_type -debug_tag_type (void *handle, const char *name, debug_type type) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type_s *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_file == NULL) - { - debug_error (_("debug_tag_type: no current file")); - return DEBUG_TYPE_NULL; - } - - if (type->kind == DEBUG_KIND_TAGGED) - { - if (strcmp (type->u.knamed->name->name, name) == 0) - return type; - debug_error (_("debug_tag_type: extra tag attempted")); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, DEBUG_KIND_TAGGED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We keep a global namespace of tags for each compilation unit. I - don't know if that is the right thing to do. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.tag = t; - - n->name = nm; - - return t; -} - -/* Record the size of a given type. */ - -bfd_boolean -debug_record_type_size (void *handle ATTRIBUTE_UNUSED, debug_type type, - unsigned int size) -{ - if (type->size != 0 && type->size != size) - fprintf (stderr, _("Warning: changing type size from %d to %d\n"), - type->size, size); - - type->size = size; - - return TRUE; -} - -/* Find a named type. */ - -debug_type -debug_find_named_type (void *handle, const char *name) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b; - struct debug_file *f; - - /* We only search the current compilation unit. I don't know if - this is right or not. */ - - if (info->current_unit == NULL) - { - debug_error (_("debug_find_named_type: no current compilation unit")); - return DEBUG_TYPE_NULL; - } - - for (b = info->current_block; b != NULL; b = b->parent) - { - if (b->locals != NULL) - { - struct debug_name *n; - - for (n = b->locals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (f->globals != NULL) - { - struct debug_name *n; - - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Find a tagged type. */ - -debug_type -debug_find_tagged_type (void *handle, const char *name, - enum debug_type_kind kind) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We search the globals of all the compilation units. I don't know - if this is correct or not. It would be easy to change. */ - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (f->globals != NULL) - { - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TAG - && (kind == DEBUG_KIND_ILLEGAL - || n->u.tag->kind == kind) - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.tag; - } - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Get a base type. We build a linked list on the stack to avoid - crashing if the type is defined circularly. */ - -static struct debug_type_s * -debug_get_real_type (void *handle, debug_type type, - struct debug_type_real_list *list) -{ - struct debug_type_real_list *l; - struct debug_type_real_list rl; - - switch (type->kind) - { - default: - return type; - - case DEBUG_KIND_INDIRECT: - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - break; - } - - for (l = list; l != NULL; l = l->next) - { - if (l->t == type || l == l->next) - { - fprintf (stderr, - _("debug_get_real_type: circular debug information for %s\n"), - debug_get_type_name (handle, type)); - return NULL; - } - } - - rl.next = list; - rl.t = type; - - switch (type->kind) - { - /* The default case is just here to avoid warnings. */ - default: - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_real_type (handle, *type->u.kindirect->slot, &rl); - return type; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_real_type (handle, type->u.knamed->type, &rl); - } - /*NOTREACHED*/ -} - -/* Get the kind of a type. */ - -enum debug_type_kind -debug_get_type_kind (void *handle, debug_type type) -{ - if (type == NULL) - return DEBUG_KIND_ILLEGAL; - type = debug_get_real_type (handle, type, NULL); - if (type == NULL) - return DEBUG_KIND_ILLEGAL; - return type->kind; -} - -/* Get the name of a type. */ - -const char * -debug_get_type_name (void *handle, debug_type type) -{ - if (type->kind == DEBUG_KIND_INDIRECT) - { - if (*type->u.kindirect->slot != NULL) - return debug_get_type_name (handle, *type->u.kindirect->slot); - return type->u.kindirect->tag; - } - if (type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - return type->u.knamed->name->name; - return NULL; -} - -/* Get the size of a type. */ - -bfd_vma -debug_get_type_size (void *handle, debug_type type) -{ - if (type == NULL) - return 0; - - /* We don't call debug_get_real_type, because somebody might have - called debug_record_type_size on a named or indirect type. */ - - if (type->size != 0) - return type->size; - - switch (type->kind) - { - default: - return 0; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_type_size (handle, *type->u.kindirect->slot); - return 0; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_type_size (handle, type->u.knamed->type); - } - /*NOTREACHED*/ -} - -/* Get the return type of a function or method type. */ - -debug_type -debug_get_return_type (void *handle, debug_type type) -{ - if (type == NULL) - return DEBUG_TYPE_NULL; - - type = debug_get_real_type (handle, type, NULL); - if (type == NULL) - return DEBUG_TYPE_NULL; - - switch (type->kind) - { - default: - return DEBUG_TYPE_NULL; - case DEBUG_KIND_FUNCTION: - return type->u.kfunction->return_type; - case DEBUG_KIND_METHOD: - return type->u.kmethod->return_type; - } - /*NOTREACHED*/ -} - -/* Get the parameter types of a function or method type (except that - we don't currently store the parameter types of a function). */ - -const debug_type * -debug_get_parameter_types (void *handle, debug_type type, - bfd_boolean *pvarargs) -{ - if (type == NULL) - return NULL; - - type = debug_get_real_type (handle, type, NULL); - if (type == NULL) - return NULL; - - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_FUNCTION: - *pvarargs = type->u.kfunction->varargs; - return type->u.kfunction->arg_types; - case DEBUG_KIND_METHOD: - *pvarargs = type->u.kmethod->varargs; - return type->u.kmethod->arg_types; - } - /*NOTREACHED*/ -} - -/* Get the target type of a type. */ - -debug_type -debug_get_target_type (void *handle, debug_type type) -{ - if (type == NULL) - return NULL; - - type = debug_get_real_type (handle, type, NULL); - if (type == NULL) - return NULL; - - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_POINTER: - return type->u.kpointer; - case DEBUG_KIND_REFERENCE: - return type->u.kreference; - case DEBUG_KIND_CONST: - return type->u.kconst; - case DEBUG_KIND_VOLATILE: - return type->u.kvolatile; - } - /*NOTREACHED*/ -} - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -const debug_field * -debug_get_fields (void *handle, debug_type type) -{ - if (type == NULL) - return NULL; - - type = debug_get_real_type (handle, type, NULL); - if (type == NULL) - return NULL; - - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return type->u.kclass->fields; - } - /*NOTREACHED*/ -} - -/* Get the type of a field. */ - -debug_type -debug_get_field_type (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL) - return NULL; - return field->type; -} - -/* Get the name of a field. */ - -const char * -debug_get_field_name (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL) - return NULL; - return field->name; -} - -/* Get the bit position of a field. */ - -bfd_vma -debug_get_field_bitpos (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitpos; -} - -/* Get the bit size of a field. */ - -bfd_vma -debug_get_field_bitsize (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitsize; -} - -/* Get the visibility of a field. */ - -enum debug_visibility -debug_get_field_visibility (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL) - return DEBUG_VISIBILITY_IGNORE; - return field->visibility; -} - -/* Get the physical name of a field. */ - -const char * -debug_get_field_physname (void *handle ATTRIBUTE_UNUSED, debug_field field) -{ - if (field == NULL || ! field->static_member) - return NULL; - return field->u.s.physname; -} - -/* Write out the debugging information. This is given a handle to - debugging information, and a set of function pointers to call. */ - -bfd_boolean -debug_write (void *handle, const struct debug_write_fns *fns, void *fhandle) -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We use a mark to tell whether we have already written out a - particular name. We use an integer, so that we don't have to - clear the mark fields if we happen to write out the same - information more than once. */ - ++info->mark; - - /* The base_id field holds an ID value which will never be used, so - that we can tell whether we have assigned an ID during this call - to debug_write. */ - info->base_id = info->class_id; - - /* We keep a linked list of classes for which was have assigned ID's - during this call to debug_write. */ - info->id_list = NULL; - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - bfd_boolean first_file; - - info->current_write_lineno = u->linenos; - info->current_write_lineno_index = 0; - - if (! (*fns->start_compilation_unit) (fhandle, u->files->filename)) - return FALSE; - - first_file = TRUE; - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (first_file) - first_file = FALSE; - else if (! (*fns->start_source) (fhandle, f->filename)) - return FALSE; - - if (f->globals != NULL) - for (n = f->globals->list; n != NULL; n = n->next) - if (! debug_write_name (info, fns, fhandle, n)) - return FALSE; - } - - /* Output any line number information which hasn't already been - handled. */ - if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1)) - return FALSE; - } - - return TRUE; -} - -/* Write out an element in a namespace. */ - -static bfd_boolean -debug_write_name (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - struct debug_name *n) -{ - switch (n->kind) - { - case DEBUG_OBJECT_TYPE: - if (! debug_write_type (info, fns, fhandle, n->u.type, n) - || ! (*fns->typdef) (fhandle, n->name)) - return FALSE; - return TRUE; - case DEBUG_OBJECT_TAG: - if (! debug_write_type (info, fns, fhandle, n->u.tag, n)) - return FALSE; - return (*fns->tag) (fhandle, n->name); - case DEBUG_OBJECT_VARIABLE: - if (! debug_write_type (info, fns, fhandle, n->u.variable->type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->variable) (fhandle, n->name, n->u.variable->kind, - n->u.variable->val); - case DEBUG_OBJECT_FUNCTION: - return debug_write_function (info, fns, fhandle, n->name, - n->linkage, n->u.function); - case DEBUG_OBJECT_INT_CONSTANT: - return (*fns->int_constant) (fhandle, n->name, n->u.int_constant); - case DEBUG_OBJECT_FLOAT_CONSTANT: - return (*fns->float_constant) (fhandle, n->name, n->u.float_constant); - case DEBUG_OBJECT_TYPED_CONSTANT: - if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->typed_constant) (fhandle, n->name, - n->u.typed_constant->val); - default: - abort (); - return FALSE; - } - /*NOTREACHED*/ -} - -/* Write out a type. If the type is DEBUG_KIND_NAMED or - DEBUG_KIND_TAGGED, then the name argument is the name for which we - are about to call typedef or tag. If the type is anything else, - then the name argument is a tag from a DEBUG_KIND_TAGGED type which - points to this one. */ - -static bfd_boolean -debug_write_type (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - struct debug_type_s *type, struct debug_name *name) -{ - unsigned int i; - int is; - const char *tag = NULL; - - /* If we have a name for this type, just output it. We only output - typedef names after they have been defined. We output type tags - whenever we are not actually defining them. */ - if ((type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - && (type->u.knamed->name->mark == info->mark - || (type->kind == DEBUG_KIND_TAGGED - && type->u.knamed->name != name))) - { - if (type->kind == DEBUG_KIND_NAMED) - return (*fns->typedef_type) (fhandle, type->u.knamed->name->name); - else - { - struct debug_type_s *real; - unsigned int id; - - real = debug_get_real_type ((void *) info, type, NULL); - if (real == NULL) - return (*fns->empty_type) (fhandle); - id = 0; - if ((real->kind == DEBUG_KIND_STRUCT - || real->kind == DEBUG_KIND_UNION - || real->kind == DEBUG_KIND_CLASS - || real->kind == DEBUG_KIND_UNION_CLASS) - && real->u.kclass != NULL) - { - if (real->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, - type->u.knamed->name->name, - real)) - return FALSE; - } - id = real->u.kclass->id; - } - - return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id, - real->kind); - } - } - - /* Mark the name after we have already looked for a known name, so - that we don't just define a type in terms of itself. We need to - mark the name here so that a struct containing a pointer to - itself will work. */ - if (name != NULL) - name->mark = info->mark; - - if (name != NULL - && type->kind != DEBUG_KIND_NAMED - && type->kind != DEBUG_KIND_TAGGED) - { - assert (name->kind == DEBUG_OBJECT_TAG); - tag = name->name; - } - - switch (type->kind) - { - case DEBUG_KIND_ILLEGAL: - debug_error (_("debug_write_type: illegal type encountered")); - return FALSE; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot == DEBUG_TYPE_NULL) - return (*fns->empty_type) (fhandle); - return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot, - name); - case DEBUG_KIND_VOID: - return (*fns->void_type) (fhandle); - case DEBUG_KIND_INT: - return (*fns->int_type) (fhandle, type->size, type->u.kint); - case DEBUG_KIND_FLOAT: - return (*fns->float_type) (fhandle, type->size); - case DEBUG_KIND_COMPLEX: - return (*fns->complex_type) (fhandle, type->size); - case DEBUG_KIND_BOOL: - return (*fns->bool_type) (fhandle, type->size); - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - if (type->u.kclass != NULL) - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return FALSE; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this struct, or we have - already output it. I don't know if this can happen, - but it can happen for a class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - } - - if (! (*fns->start_struct_type) (fhandle, tag, - (type->u.kclass != NULL - ? type->u.kclass->id - : 0), - type->kind == DEBUG_KIND_STRUCT, - type->size)) - return FALSE; - if (type->u.kclass != NULL - && type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field_s *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL) - || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return FALSE; - } - } - return (*fns->end_struct_type) (fhandle); - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return debug_write_class_type (info, fns, fhandle, type, tag); - case DEBUG_KIND_ENUM: - if (type->u.kenum == NULL) - return (*fns->enum_type) (fhandle, tag, (const char **) NULL, - (bfd_signed_vma *) NULL); - return (*fns->enum_type) (fhandle, tag, type->u.kenum->names, - type->u.kenum->values); - case DEBUG_KIND_POINTER: - if (! debug_write_type (info, fns, fhandle, type->u.kpointer, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->pointer_type) (fhandle); - case DEBUG_KIND_FUNCTION: - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->return_type, - (struct debug_name *) NULL)) - return FALSE; - if (type->u.kfunction->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->arg_types[is], - (struct debug_name *) NULL)) - return FALSE; - } - return (*fns->function_type) (fhandle, is, - type->u.kfunction->varargs); - case DEBUG_KIND_REFERENCE: - if (! debug_write_type (info, fns, fhandle, type->u.kreference, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->reference_type) (fhandle); - case DEBUG_KIND_RANGE: - if (! debug_write_type (info, fns, fhandle, type->u.krange->type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->range_type) (fhandle, type->u.krange->lower, - type->u.krange->upper); - case DEBUG_KIND_ARRAY: - if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.karray->range_type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->array_type) (fhandle, type->u.karray->lower, - type->u.karray->upper, - type->u.karray->stringp); - case DEBUG_KIND_SET: - if (! debug_write_type (info, fns, fhandle, type->u.kset->type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->set_type) (fhandle, type->u.kset->bitstringp); - case DEBUG_KIND_OFFSET: - if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.koffset->target_type, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->offset_type) (fhandle); - case DEBUG_KIND_METHOD: - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->return_type, - (struct debug_name *) NULL)) - return FALSE; - if (type->u.kmethod->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->arg_types[is], - (struct debug_name *) NULL)) - return FALSE; - } - if (type->u.kmethod->domain_type != NULL) - { - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->domain_type, - (struct debug_name *) NULL)) - return FALSE; - } - return (*fns->method_type) (fhandle, - type->u.kmethod->domain_type != NULL, - is, - type->u.kmethod->varargs); - case DEBUG_KIND_CONST: - if (! debug_write_type (info, fns, fhandle, type->u.kconst, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->const_type) (fhandle); - case DEBUG_KIND_VOLATILE: - if (! debug_write_type (info, fns, fhandle, type->u.kvolatile, - (struct debug_name *) NULL)) - return FALSE; - return (*fns->volatile_type) (fhandle); - case DEBUG_KIND_NAMED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - (struct debug_name *) NULL); - case DEBUG_KIND_TAGGED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - type->u.knamed->name); - default: - abort (); - return FALSE; - } -} - -/* Write out a class type. */ - -static bfd_boolean -debug_write_class_type (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - struct debug_type_s *type, const char *tag) -{ - unsigned int i; - unsigned int id; - struct debug_type_s *vptrbase; - - if (type->u.kclass == NULL) - { - id = 0; - vptrbase = NULL; - } - else - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return FALSE; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this class, or we have - already output it. This can happen when there are - methods for an anonymous class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - id = type->u.kclass->id; - - vptrbase = type->u.kclass->vptrbase; - if (vptrbase != NULL && vptrbase != type) - { - if (! debug_write_type (info, fns, fhandle, vptrbase, - (struct debug_name *) NULL)) - return FALSE; - } - } - - if (! (*fns->start_class_type) (fhandle, tag, id, - type->kind == DEBUG_KIND_CLASS, - type->size, - vptrbase != NULL, - vptrbase == type)) - return FALSE; - - if (type->u.kclass != NULL) - { - if (type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field_s *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL)) - return FALSE; - if (f->static_member) - { - if (! (*fns->class_static_member) (fhandle, f->name, - f->u.s.physname, - f->visibility)) - return FALSE; - } - else - { - if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return FALSE; - } - } - } - - if (type->u.kclass->baseclasses != NULL) - { - for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++) - { - struct debug_baseclass_s *b; - - b = type->u.kclass->baseclasses[i]; - if (! debug_write_type (info, fns, fhandle, b->type, - (struct debug_name *) NULL)) - return FALSE; - if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->is_virtual, - b->visibility)) - return FALSE; - } - } - - if (type->u.kclass->methods != NULL) - { - for (i = 0; type->u.kclass->methods[i] != NULL; i++) - { - struct debug_method_s *m; - unsigned int j; - - m = type->u.kclass->methods[i]; - if (! (*fns->class_start_method) (fhandle, m->name)) - return FALSE; - for (j = 0; m->variants[j] != NULL; j++) - { - struct debug_method_variant_s *v; - - v = m->variants[j]; - if (v->context != NULL) - { - if (! debug_write_type (info, fns, fhandle, v->context, - (struct debug_name *) NULL)) - return FALSE; - } - if (! debug_write_type (info, fns, fhandle, v->type, - (struct debug_name *) NULL)) - return FALSE; - if (v->voffset != VOFFSET_STATIC_METHOD) - { - if (! (*fns->class_method_variant) (fhandle, v->physname, - v->visibility, - v->constp, - v->volatilep, - v->voffset, - v->context != NULL)) - return FALSE; - } - else - { - if (! (*fns->class_static_method_variant) (fhandle, - v->physname, - v->visibility, - v->constp, - v->volatilep)) - return FALSE; - } - } - if (! (*fns->class_end_method) (fhandle)) - return FALSE; - } - } - } - - return (*fns->end_class_type) (fhandle); -} - -/* Write out information for a function. */ - -static bfd_boolean -debug_write_function (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - const char *name, enum debug_object_linkage linkage, - struct debug_function *function) -{ - struct debug_parameter *p; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, function->blocks->start)) - return FALSE; - - if (! debug_write_type (info, fns, fhandle, function->return_type, - (struct debug_name *) NULL)) - return FALSE; - - if (! (*fns->start_function) (fhandle, name, - linkage == DEBUG_LINKAGE_GLOBAL)) - return FALSE; - - for (p = function->parameters; p != NULL; p = p->next) - { - if (! debug_write_type (info, fns, fhandle, p->type, - (struct debug_name *) NULL) - || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val)) - return FALSE; - } - - for (b = function->blocks; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return FALSE; - } - - return (*fns->end_function) (fhandle); -} - -/* Write out information for a block. */ - -static bfd_boolean -debug_write_block (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - struct debug_block *block) -{ - struct debug_name *n; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, block->start)) - return FALSE; - - /* I can't see any point to writing out a block with no local - variables, so we don't bother, except for the top level block. */ - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->start_block) (fhandle, block->start)) - return FALSE; - } - - if (block->locals != NULL) - { - for (n = block->locals->list; n != NULL; n = n->next) - { - if (! debug_write_name (info, fns, fhandle, n)) - return FALSE; - } - } - - for (b = block->children; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return FALSE; - } - - if (! debug_write_linenos (info, fns, fhandle, block->end)) - return FALSE; - - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->end_block) (fhandle, block->end)) - return FALSE; - } - - return TRUE; -} - -/* Write out line number information up to ADDRESS. */ - -static bfd_boolean -debug_write_linenos (struct debug_handle *info, - const struct debug_write_fns *fns, void *fhandle, - bfd_vma address) -{ - while (info->current_write_lineno != NULL) - { - struct debug_lineno *l; - - l = info->current_write_lineno; - - while (info->current_write_lineno_index < DEBUG_LINENO_COUNT) - { - if (l->linenos[info->current_write_lineno_index] - == (unsigned long) -1) - break; - - if (l->addrs[info->current_write_lineno_index] >= address) - return TRUE; - - if (! (*fns->lineno) (fhandle, l->file->filename, - l->linenos[info->current_write_lineno_index], - l->addrs[info->current_write_lineno_index])) - return FALSE; - - ++info->current_write_lineno_index; - } - - info->current_write_lineno = l->next; - info->current_write_lineno_index = 0; - } - - return TRUE; -} - -/* Get the ID number for a class. If during the same call to - debug_write we find a struct with the same definition with the same - name, we use the same ID. This type of things happens because the - same struct will be defined by multiple compilation units. */ - -static bfd_boolean -debug_set_class_id (struct debug_handle *info, const char *tag, - struct debug_type_s *type) -{ - struct debug_class_type *c; - struct debug_class_id *l; - - assert (type->kind == DEBUG_KIND_STRUCT - || type->kind == DEBUG_KIND_UNION - || type->kind == DEBUG_KIND_CLASS - || type->kind == DEBUG_KIND_UNION_CLASS); - - c = type->u.kclass; - - if (c->id > info->base_id) - return TRUE; - - for (l = info->id_list; l != NULL; l = l->next) - { - if (l->type->kind != type->kind) - continue; - - if (tag == NULL) - { - if (l->tag != NULL) - continue; - } - else - { - if (l->tag == NULL - || l->tag[0] != tag[0] - || strcmp (l->tag, tag) != 0) - continue; - } - - if (debug_type_samep (info, l->type, type)) - { - c->id = l->type->u.kclass->id; - return TRUE; - } - } - - /* There are no identical types. Use a new ID, and add it to the - list. */ - ++info->class_id; - c->id = info->class_id; - - l = (struct debug_class_id *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->type = type; - l->tag = tag; - - l->next = info->id_list; - info->id_list = l; - - return TRUE; -} - -/* See if two types are the same. At this point, we don't care about - tags and the like. */ - -static bfd_boolean -debug_type_samep (struct debug_handle *info, struct debug_type_s *t1, - struct debug_type_s *t2) -{ - struct debug_type_compare_list *l; - struct debug_type_compare_list top; - bfd_boolean ret; - - if (t1 == NULL) - return t2 == NULL; - if (t2 == NULL) - return FALSE; - - while (t1->kind == DEBUG_KIND_INDIRECT) - { - t1 = *t1->u.kindirect->slot; - if (t1 == NULL) - return FALSE; - } - while (t2->kind == DEBUG_KIND_INDIRECT) - { - t2 = *t2->u.kindirect->slot; - if (t2 == NULL) - return FALSE; - } - - if (t1 == t2) - return TRUE; - - /* As a special case, permit a typedef to match a tag, since C++ - debugging output will sometimes add a typedef where C debugging - output will not. */ - if (t1->kind == DEBUG_KIND_NAMED - && t2->kind == DEBUG_KIND_TAGGED) - return debug_type_samep (info, t1->u.knamed->type, t2); - else if (t1->kind == DEBUG_KIND_TAGGED - && t2->kind == DEBUG_KIND_NAMED) - return debug_type_samep (info, t1, t2->u.knamed->type); - - if (t1->kind != t2->kind - || t1->size != t2->size) - return FALSE; - - /* Get rid of the trivial cases first. */ - switch (t1->kind) - { - default: - break; - case DEBUG_KIND_VOID: - case DEBUG_KIND_FLOAT: - case DEBUG_KIND_COMPLEX: - case DEBUG_KIND_BOOL: - return TRUE; - case DEBUG_KIND_INT: - return t1->u.kint == t2->u.kint; - } - - /* We have to avoid an infinite recursion. We do this by keeping a - list of types which we are comparing. We just keep the list on - the stack. If we encounter a pair of types we are currently - comparing, we just assume that they are equal. */ - for (l = info->compare_list; l != NULL; l = l->next) - { - if (l->t1 == t1 && l->t2 == t2) - return TRUE; - } - - top.t1 = t1; - top.t2 = t2; - top.next = info->compare_list; - info->compare_list = ⊤ - - switch (t1->kind) - { - default: - abort (); - ret = FALSE; - break; - - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - if (t1->u.kclass == NULL) - ret = t2->u.kclass == NULL; - else if (t2->u.kclass == NULL) - ret = FALSE; - else if (t1->u.kclass->id > info->base_id - && t1->u.kclass->id == t2->u.kclass->id) - ret = TRUE; - else - ret = debug_class_type_samep (info, t1, t2); - break; - - case DEBUG_KIND_ENUM: - if (t1->u.kenum == NULL) - ret = t2->u.kenum == NULL; - else if (t2->u.kenum == NULL) - ret = FALSE; - else - { - const char **pn1, **pn2; - bfd_signed_vma *pv1, *pv2; - - pn1 = t1->u.kenum->names; - pn2 = t2->u.kenum->names; - pv1 = t1->u.kenum->values; - pv2 = t2->u.kenum->values; - while (*pn1 != NULL && *pn2 != NULL) - { - if (**pn1 != **pn2 - || *pv1 != *pv2 - || strcmp (*pn1, *pn2) != 0) - break; - ++pn1; - ++pn2; - ++pv1; - ++pv2; - } - ret = *pn1 == NULL && *pn2 == NULL; - } - break; - - case DEBUG_KIND_POINTER: - ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer); - break; - - case DEBUG_KIND_FUNCTION: - if (t1->u.kfunction->varargs != t2->u.kfunction->varargs - || ! debug_type_samep (info, t1->u.kfunction->return_type, - t2->u.kfunction->return_type) - || ((t1->u.kfunction->arg_types == NULL) - != (t2->u.kfunction->arg_types == NULL))) - ret = FALSE; - else if (t1->u.kfunction->arg_types == NULL) - ret = TRUE; - else - { - struct debug_type_s **a1, **a2; - - a1 = t1->u.kfunction->arg_types; - a2 = t2->u.kfunction->arg_types; - while (*a1 != NULL && *a2 != NULL) - { - if (! debug_type_samep (info, *a1, *a2)) - break; - ++a1; - ++a2; - } - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_REFERENCE: - ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference); - break; - - case DEBUG_KIND_RANGE: - ret = (t1->u.krange->lower == t2->u.krange->lower - && t1->u.krange->upper == t2->u.krange->upper - && debug_type_samep (info, t1->u.krange->type, - t2->u.krange->type)); - - case DEBUG_KIND_ARRAY: - ret = (t1->u.karray->lower == t2->u.karray->lower - && t1->u.karray->upper == t2->u.karray->upper - && t1->u.karray->stringp == t2->u.karray->stringp - && debug_type_samep (info, t1->u.karray->element_type, - t2->u.karray->element_type)); - break; - - case DEBUG_KIND_SET: - ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp - && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type)); - break; - - case DEBUG_KIND_OFFSET: - ret = (debug_type_samep (info, t1->u.koffset->base_type, - t2->u.koffset->base_type) - && debug_type_samep (info, t1->u.koffset->target_type, - t2->u.koffset->target_type)); - break; - - case DEBUG_KIND_METHOD: - if (t1->u.kmethod->varargs != t2->u.kmethod->varargs - || ! debug_type_samep (info, t1->u.kmethod->return_type, - t2->u.kmethod->return_type) - || ! debug_type_samep (info, t1->u.kmethod->domain_type, - t2->u.kmethod->domain_type) - || ((t1->u.kmethod->arg_types == NULL) - != (t2->u.kmethod->arg_types == NULL))) - ret = FALSE; - else if (t1->u.kmethod->arg_types == NULL) - ret = TRUE; - else - { - struct debug_type_s **a1, **a2; - - a1 = t1->u.kmethod->arg_types; - a2 = t2->u.kmethod->arg_types; - while (*a1 != NULL && *a2 != NULL) - { - if (! debug_type_samep (info, *a1, *a2)) - break; - ++a1; - ++a2; - } - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_CONST: - ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst); - break; - - case DEBUG_KIND_VOLATILE: - ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile); - break; - - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0 - && debug_type_samep (info, t1->u.knamed->type, - t2->u.knamed->type)); - break; - } - - info->compare_list = top.next; - - return ret; -} - -/* See if two classes are the same. This is a subroutine of - debug_type_samep. */ - -static bfd_boolean -debug_class_type_samep (struct debug_handle *info, struct debug_type_s *t1, - struct debug_type_s *t2) -{ - struct debug_class_type *c1, *c2; - - c1 = t1->u.kclass; - c2 = t2->u.kclass; - - if ((c1->fields == NULL) != (c2->fields == NULL) - || (c1->baseclasses == NULL) != (c2->baseclasses == NULL) - || (c1->methods == NULL) != (c2->methods == NULL) - || (c1->vptrbase == NULL) != (c2->vptrbase == NULL)) - return FALSE; - - if (c1->fields != NULL) - { - struct debug_field_s **pf1, **pf2; - - for (pf1 = c1->fields, pf2 = c2->fields; - *pf1 != NULL && *pf2 != NULL; - pf1++, pf2++) - { - struct debug_field_s *f1, *f2; - - f1 = *pf1; - f2 = *pf2; - if (f1->name[0] != f2->name[0] - || f1->visibility != f2->visibility - || f1->static_member != f2->static_member) - return FALSE; - if (f1->static_member) - { - if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0) - return FALSE; - } - else - { - if (f1->u.f.bitpos != f2->u.f.bitpos - || f1->u.f.bitsize != f2->u.f.bitsize) - return FALSE; - } - /* We do the checks which require function calls last. We - don't require that the types of fields have the same - names, since that sometimes fails in the presence of - typedefs and we really don't care. */ - if (strcmp (f1->name, f2->name) != 0 - || ! debug_type_samep (info, - debug_get_real_type ((void *) info, - f1->type, NULL), - debug_get_real_type ((void *) info, - f2->type, NULL))) - return FALSE; - } - if (*pf1 != NULL || *pf2 != NULL) - return FALSE; - } - - if (c1->vptrbase != NULL) - { - if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase)) - return FALSE; - } - - if (c1->baseclasses != NULL) - { - struct debug_baseclass_s **pb1, **pb2; - - for (pb1 = c1->baseclasses, pb2 = c2->baseclasses; - *pb1 != NULL && *pb2 != NULL; - ++pb1, ++pb2) - { - struct debug_baseclass_s *b1, *b2; - - b1 = *pb1; - b2 = *pb2; - if (b1->bitpos != b2->bitpos - || b1->is_virtual != b2->is_virtual - || b1->visibility != b2->visibility - || ! debug_type_samep (info, b1->type, b2->type)) - return FALSE; - } - if (*pb1 != NULL || *pb2 != NULL) - return FALSE; - } - - if (c1->methods != NULL) - { - struct debug_method_s **pm1, **pm2; - - for (pm1 = c1->methods, pm2 = c2->methods; - *pm1 != NULL && *pm2 != NULL; - ++pm1, ++pm2) - { - struct debug_method_s *m1, *m2; - - m1 = *pm1; - m2 = *pm2; - if (m1->name[0] != m2->name[0] - || strcmp (m1->name, m2->name) != 0 - || (m1->variants == NULL) != (m2->variants == NULL)) - return FALSE; - if (m1->variants == NULL) - { - struct debug_method_variant_s **pv1, **pv2; - - for (pv1 = m1->variants, pv2 = m2->variants; - *pv1 != NULL && *pv2 != NULL; - ++pv1, ++pv2) - { - struct debug_method_variant_s *v1, *v2; - - v1 = *pv1; - v2 = *pv2; - if (v1->physname[0] != v2->physname[0] - || v1->visibility != v2->visibility - || v1->constp != v2->constp - || v1->volatilep != v2->volatilep - || v1->voffset != v2->voffset - || (v1->context == NULL) != (v2->context == NULL) - || strcmp (v1->physname, v2->physname) != 0 - || ! debug_type_samep (info, v1->type, v2->type)) - return FALSE; - if (v1->context != NULL) - { - if (! debug_type_samep (info, v1->context, - v2->context)) - return FALSE; - } - } - if (*pv1 != NULL || *pv2 != NULL) - return FALSE; - } - } - if (*pm1 != NULL || *pm2 != NULL) - return FALSE; - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/binutils/debug.h b/contrib/binutils-2.22/binutils/debug.h deleted file mode 100644 index 1846119b78..0000000000 --- a/contrib/binutils-2.22/binutils/debug.h +++ /dev/null @@ -1,793 +0,0 @@ -/* debug.h -- Describe generic debugging information. - Copyright 1995, 1996, 2002, 2003, 2005, 2007, 2009 - Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef DEBUG_H -#define DEBUG_H - -/* This header file describes a generic debugging information format. - We may eventually have readers which convert different formats into - this generic format, and writers which write it out. The initial - impetus for this was writing a converter from stabs to HP IEEE-695 - debugging format. */ - -/* Different kinds of types. */ - -enum debug_type_kind -{ - /* Not used. */ - DEBUG_KIND_ILLEGAL, - /* Indirect via a pointer. */ - DEBUG_KIND_INDIRECT, - /* Void. */ - DEBUG_KIND_VOID, - /* Integer. */ - DEBUG_KIND_INT, - /* Floating point. */ - DEBUG_KIND_FLOAT, - /* Complex. */ - DEBUG_KIND_COMPLEX, - /* Boolean. */ - DEBUG_KIND_BOOL, - /* Struct. */ - DEBUG_KIND_STRUCT, - /* Union. */ - DEBUG_KIND_UNION, - /* Class. */ - DEBUG_KIND_CLASS, - /* Union class (can this really happen?). */ - DEBUG_KIND_UNION_CLASS, - /* Enumeration type. */ - DEBUG_KIND_ENUM, - /* Pointer. */ - DEBUG_KIND_POINTER, - /* Function. */ - DEBUG_KIND_FUNCTION, - /* Reference. */ - DEBUG_KIND_REFERENCE, - /* Range. */ - DEBUG_KIND_RANGE, - /* Array. */ - DEBUG_KIND_ARRAY, - /* Set. */ - DEBUG_KIND_SET, - /* Based pointer. */ - DEBUG_KIND_OFFSET, - /* Method. */ - DEBUG_KIND_METHOD, - /* Const qualified type. */ - DEBUG_KIND_CONST, - /* Volatile qualified type. */ - DEBUG_KIND_VOLATILE, - /* Named type. */ - DEBUG_KIND_NAMED, - /* Tagged type. */ - DEBUG_KIND_TAGGED -}; - -/* Different kinds of variables. */ - -enum debug_var_kind -{ - /* Not used. */ - DEBUG_VAR_ILLEGAL, - /* A global variable. */ - DEBUG_GLOBAL, - /* A static variable. */ - DEBUG_STATIC, - /* A local static variable. */ - DEBUG_LOCAL_STATIC, - /* A local variable. */ - DEBUG_LOCAL, - /* A register variable. */ - DEBUG_REGISTER -}; - -/* Different kinds of function parameters. */ - -enum debug_parm_kind -{ - /* Not used. */ - DEBUG_PARM_ILLEGAL, - /* A stack based parameter. */ - DEBUG_PARM_STACK, - /* A register parameter. */ - DEBUG_PARM_REG, - /* A stack based reference parameter. */ - DEBUG_PARM_REFERENCE, - /* A register reference parameter. */ - DEBUG_PARM_REF_REG -}; - -/* Different kinds of visibility. */ - -enum debug_visibility -{ - /* A public field (e.g., a field in a C struct). */ - DEBUG_VISIBILITY_PUBLIC, - /* A protected field. */ - DEBUG_VISIBILITY_PROTECTED, - /* A private field. */ - DEBUG_VISIBILITY_PRIVATE, - /* A field which should be ignored. */ - DEBUG_VISIBILITY_IGNORE -}; - -/* A type. */ - -typedef struct debug_type_s *debug_type; - -#define DEBUG_TYPE_NULL ((debug_type) NULL) - -/* A field in a struct or union. */ - -typedef struct debug_field_s *debug_field; - -#define DEBUG_FIELD_NULL ((debug_field) NULL) - -/* A base class for an object. */ - -typedef struct debug_baseclass_s *debug_baseclass; - -#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL) - -/* A method of an object. */ - -typedef struct debug_method_s *debug_method; - -#define DEBUG_METHOD_NULL ((debug_method) NULL) - -/* The arguments to a method function of an object. These indicate - which method to run. */ - -typedef struct debug_method_variant_s *debug_method_variant; - -#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL) - -/* This structure is passed to debug_write. It holds function - pointers that debug_write will call based on the accumulated - debugging information. */ - -struct debug_write_fns -{ - /* This is called at the start of each new compilation unit with the - name of the main file in the new unit. */ - bfd_boolean (*start_compilation_unit) (void *, const char *); - - /* This is called at the start of each source file within a - compilation unit, before outputting any global information for - that file. The argument is the name of the file. */ - bfd_boolean (*start_source) (void *, const char *); - - /* Each writer must keep a stack of types. */ - - /* Push an empty type onto the type stack. This type can appear if - there is a reference to a type which is never defined. */ - bfd_boolean (*empty_type) (void *); - - /* Push a void type onto the type stack. */ - bfd_boolean (*void_type) (void *); - - /* Push an integer type onto the type stack, given the size and - whether it is unsigned. */ - bfd_boolean (*int_type) (void *, unsigned int, bfd_boolean); - - /* Push a floating type onto the type stack, given the size. */ - bfd_boolean (*float_type) (void *, unsigned int); - - /* Push a complex type onto the type stack, given the size. */ - bfd_boolean (*complex_type) (void *, unsigned int); - - /* Push a bfd_boolean type onto the type stack, given the size. */ - bfd_boolean (*bool_type) (void *, unsigned int); - - /* Push an enum type onto the type stack, given the tag, a NULL - terminated array of names and the associated values. If there is - no tag, the tag argument will be NULL. If this is an undefined - enum, the names and values arguments will be NULL. */ - bfd_boolean (*enum_type) - (void *, const char *, const char **, bfd_signed_vma *); - - /* Pop the top type on the type stack, and push a pointer to that - type onto the type stack. */ - bfd_boolean (*pointer_type) (void *); - - /* Push a function type onto the type stack. The second argument - indicates the number of argument types that have been pushed onto - the stack. If the number of argument types is passed as -1, then - the argument types of the function are unknown, and no types have - been pushed onto the stack. The third argument is TRUE if the - function takes a variable number of arguments. The return type - of the function is pushed onto the type stack below the argument - types, if any. */ - bfd_boolean (*function_type) (void *, int, bfd_boolean); - - /* Pop the top type on the type stack, and push a reference to that - type onto the type stack. */ - bfd_boolean (*reference_type) (void *); - - /* Pop the top type on the type stack, and push a range of that type - with the given lower and upper bounds onto the type stack. */ - bfd_boolean (*range_type) (void *, bfd_signed_vma, bfd_signed_vma); - - /* Push an array type onto the type stack. The top type on the type - stack is the range, and the next type on the type stack is the - element type. These should be popped before the array type is - pushed. The arguments are the lower bound, the upper bound, and - whether the array is a string. */ - bfd_boolean (*array_type) - (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); - - /* Pop the top type on the type stack, and push a set of that type - onto the type stack. The argument indicates whether this set is - a bitstring. */ - bfd_boolean (*set_type) (void *, bfd_boolean); - - /* Push an offset type onto the type stack. The top type on the - type stack is the target type, and the next type on the type - stack is the base type. These should be popped before the offset - type is pushed. */ - bfd_boolean (*offset_type) (void *); - - /* Push a method type onto the type stack. If the second argument - is TRUE, the top type on the stack is the class to which the - method belongs; otherwise, the class must be determined by the - class to which the method is attached. The third argument is the - number of argument types; these are pushed onto the type stack in - reverse order (the first type popped is the last argument to the - method). A value of -1 for the third argument means that no - argument information is available. The fourth argument is TRUE - if the function takes a variable number of arguments. The next - type on the type stack below the domain and the argument types is - the return type of the method. All these types must be popped, - and then the method type must be pushed. */ - bfd_boolean (*method_type) (void *, bfd_boolean, int, bfd_boolean); - - /* Pop the top type off the type stack, and push a const qualified - version of that type onto the type stack. */ - bfd_boolean (*const_type) (void *); - - /* Pop the top type off the type stack, and push a volatile - qualified version of that type onto the type stack. */ - bfd_boolean (*volatile_type) (void *); - - /* Start building a struct. This is followed by calls to the - struct_field function, and finished by a call to the - end_struct_type function. The second argument is the tag; this - will be NULL if there isn't one. If the second argument is NULL, - the third argument is a constant identifying this struct for use - with tag_type. The fourth argument is TRUE for a struct, FALSE - for a union. The fifth argument is the size. If this is an - undefined struct or union, the size will be 0 and struct_field - will not be called before end_struct_type is called. */ - bfd_boolean (*start_struct_type) - (void *, const char *, unsigned int, bfd_boolean, unsigned int); - - /* Add a field to the struct type currently being built. The type - of the field should be popped off the type stack. The arguments - are the name, the bit position, the bit size (may be zero if the - field is not packed), and the visibility. */ - bfd_boolean (*struct_field) - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); - - /* Finish building a struct, and push it onto the type stack. */ - bfd_boolean (*end_struct_type) (void *); - - /* Start building a class. This is followed by calls to several - functions: struct_field, class_static_member, class_baseclass, - class_start_method, class_method_variant, - class_static_method_variant, and class_end_method. The class is - finished by a call to end_class_type. The first five arguments - are the same as for start_struct_type. The sixth argument is - TRUE if there is a virtual function table; if there is, the - seventh argument is TRUE if the virtual function table can be - found in the type itself, and is FALSE if the type of the object - holding the virtual function table should be popped from the type - stack. */ - bfd_boolean (*start_class_type) - (void *, const char *, unsigned int, bfd_boolean, unsigned int, - bfd_boolean, bfd_boolean); - - /* Add a static member to the class currently being built. The - arguments are the field name, the physical name, and the - visibility. The type must be popped off the type stack. */ - bfd_boolean (*class_static_member) - (void *, const char *, const char *, enum debug_visibility); - - /* Add a baseclass to the class currently being built. The type of - the baseclass must be popped off the type stack. The arguments - are the bit position, whether the class is virtual, and the - visibility. */ - bfd_boolean (*class_baseclass) - (void *, bfd_vma, bfd_boolean, enum debug_visibility); - - /* Start adding a method to the class currently being built. This - is followed by calls to class_method_variant and - class_static_method_variant to describe different variants of the - method which take different arguments. The method is finished - with a call to class_end_method. The argument is the method - name. */ - bfd_boolean (*class_start_method) (void *, const char *); - - /* Describe a variant to the class method currently being built. - The type of the variant must be popped off the type stack. The - second argument is the physical name of the function. The - following arguments are the visibility, whether the variant is - const, whether the variant is volatile, the offset in the virtual - function table, and whether the context is on the type stack - (below the variant type). */ - bfd_boolean (*class_method_variant) - (void *, const char *, enum debug_visibility, bfd_boolean, - bfd_boolean, bfd_vma, bfd_boolean); - - /* Describe a static variant to the class method currently being - built. The arguments are the same as for class_method_variant, - except that the last two arguments are omitted. The type of the - variant must be popped off the type stack. */ - bfd_boolean (*class_static_method_variant) - (void *, const char *, enum debug_visibility, bfd_boolean, - bfd_boolean); - - /* Finish describing a class method. */ - bfd_boolean (*class_end_method) (void *); - - /* Finish describing a class, and push it onto the type stack. */ - bfd_boolean (*end_class_type) (void *); - - /* Push a type on the stack which was given a name by an earlier - call to typdef. */ - bfd_boolean (*typedef_type) (void *, const char *); - - /* Push a tagged type on the stack which was defined earlier. If - the second argument is not NULL, the type was defined by a call - to tag. If the second argument is NULL, the type was defined by - a call to start_struct_type or start_class_type with a tag of - NULL and the number of the third argument. Either way, the - fourth argument is the tag kind. Note that this may be called - for a struct (class) being defined, in between the call to - start_struct_type (start_class_type) and the call to - end_struct_type (end_class_type). */ - bfd_boolean (*tag_type) - (void *, const char *, unsigned int, enum debug_type_kind); - - /* Pop the type stack, and typedef it to the given name. */ - bfd_boolean (*typdef) (void *, const char *); - - /* Pop the type stack, and declare it as a tagged struct or union or - enum or whatever. The tag passed down here is redundant, since - was also passed when enum_type, start_struct_type, or - start_class_type was called. */ - bfd_boolean (*tag) (void *, const char *); - - /* This is called to record a named integer constant. */ - bfd_boolean (*int_constant) (void *, const char *, bfd_vma); - - /* This is called to record a named floating point constant. */ - bfd_boolean (*float_constant) (void *, const char *, double); - - /* This is called to record a typed integer constant. The type is - popped off the type stack. */ - bfd_boolean (*typed_constant) (void *, const char *, bfd_vma); - - /* This is called to record a variable. The type is popped off the - type stack. */ - bfd_boolean (*variable) - (void *, const char *, enum debug_var_kind, bfd_vma); - - /* Start writing out a function. The return type must be popped off - the stack. The bfd_boolean is TRUE if the function is global. This - is followed by calls to function_parameter, followed by block - information. */ - bfd_boolean (*start_function) (void *, const char *, bfd_boolean); - - /* Record a function parameter for the current function. The type - must be popped off the stack. */ - bfd_boolean (*function_parameter) - (void *, const char *, enum debug_parm_kind, bfd_vma); - - /* Start writing out a block. There is at least one top level block - per function. Blocks may be nested. The argument is the - starting address of the block. */ - bfd_boolean (*start_block) (void *, bfd_vma); - - /* Finish writing out a block. The argument is the ending address - of the block. */ - bfd_boolean (*end_block) (void *, bfd_vma); - - /* Finish writing out a function. */ - bfd_boolean (*end_function) (void *); - - /* Record line number information for the current compilation unit. */ - bfd_boolean (*lineno) (void *, const char *, unsigned long, bfd_vma); -}; - -/* Exported functions. */ - -/* The first argument to most of these functions is a handle. This - handle is returned by the debug_init function. The purpose of the - handle is to permit the debugging routines to not use static - variables, and hence to be reentrant. This would be useful for a - program which wanted to handle two executables simultaneously. */ - -/* Return a debugging handle. */ - -extern void *debug_init (void); - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -extern bfd_boolean debug_set_filename (void *, const char *); - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -extern bfd_boolean debug_start_source (void *, const char *); - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The bfd_boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. */ - -extern bfd_boolean debug_record_function - (void *, const char *, debug_type, bfd_boolean, bfd_vma); - -/* Record a parameter for the current function. */ - -extern bfd_boolean debug_record_parameter - (void *, const char *, debug_type, enum debug_parm_kind, bfd_vma); - -/* End a function definition. The argument is the address where the - function ends. */ - -extern bfd_boolean debug_end_function (void *, bfd_vma); - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The argument - is the address at which this block starts. */ - -extern bfd_boolean debug_start_block (void *, bfd_vma); - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -extern bfd_boolean debug_end_block (void *, bfd_vma); - -/* Associate a line number in the current source file with a given - address. */ - -extern bfd_boolean debug_record_line (void *, unsigned long, bfd_vma); - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -extern bfd_boolean debug_start_common_block (void *, const char *); - -/* End a named common block. */ - -extern bfd_boolean debug_end_common_block (void *, const char *); - -/* Record a named integer constant. */ - -extern bfd_boolean debug_record_int_const (void *, const char *, bfd_vma); - -/* Record a named floating point constant. */ - -extern bfd_boolean debug_record_float_const (void *, const char *, double); - -/* Record a typed constant with an integral value. */ - -extern bfd_boolean debug_record_typed_const - (void *, const char *, debug_type, bfd_vma); - -/* Record a label. */ - -extern bfd_boolean debug_record_label - (void *, const char *, debug_type, bfd_vma); - -/* Record a variable. */ - -extern bfd_boolean debug_record_variable - (void *, const char *, debug_type, enum debug_var_kind, bfd_vma); - -/* Make an indirect type. The first argument is a pointer to the - location where the real type will be placed. The second argument - is the type tag, if there is one; this may be NULL; the only - purpose of this argument is so that debug_get_type_name can return - something useful. This function may be used when a type is - referenced before it is defined. */ - -extern debug_type debug_make_indirect_type - (void *, debug_type *, const char *); - -/* Make a void type. */ - -extern debug_type debug_make_void_type (void *); - -/* Make an integer type of a given size. The bfd_boolean argument is TRUE - if the integer is unsigned. */ - -extern debug_type debug_make_int_type (void *, unsigned int, bfd_boolean); - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -extern debug_type debug_make_float_type (void *, unsigned int); - -/* Make a boolean type of a given size. */ - -extern debug_type debug_make_bool_type (void *, unsigned int); - -/* Make a complex type of a given size. */ - -extern debug_type debug_make_complex_type (void *, unsigned int); - -/* Make a structure type. The second argument is TRUE for a struct, - FALSE for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -extern debug_type debug_make_struct_type - (void *, bfd_boolean, bfd_vma, debug_field *); - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a bfd_boolean which is TRUE if this - object has its own virtual function table. */ - -extern debug_type debug_make_object_type - (void *, bfd_boolean, bfd_vma, debug_field *, debug_baseclass *, - debug_method *, debug_type, bfd_boolean); - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -extern debug_type debug_make_enum_type - (void *, const char **, bfd_signed_vma *); - -/* Make a pointer to a given type. */ - -extern debug_type debug_make_pointer_type (void *, debug_type); - -/* Make a function type. The second argument is the return type. The - third argument is a NULL terminated array of argument types. The - fourth argument is TRUE if the function takes a variable number of - arguments. If the third argument is NULL, then the argument types - are unknown. */ - -extern debug_type debug_make_function_type - (void *, debug_type, debug_type *, bfd_boolean); - -/* Make a reference to a given type. */ - -extern debug_type debug_make_reference_type (void *, debug_type); - -/* Make a range of a given type from a lower to an upper bound. */ - -extern debug_type debug_make_range_type - (void *, debug_type, bfd_signed_vma, bfd_signed_vma); - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively (if the bounds are not known, lower should be - 0 and upper should be -1). The sixth argument is TRUE if this - array is actually a string, as in C. */ - -extern debug_type debug_make_array_type - (void *, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma, - bfd_boolean); - -/* Make a set of a given type. For example, a Pascal set type. The - bfd_boolean argument is TRUE if this set is actually a bitstring, as in - CHILL. */ - -extern debug_type debug_make_set_type (void *, debug_type, bfd_boolean); - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -extern debug_type debug_make_offset_type (void *, debug_type, debug_type); - -/* Make a type for a method function. The second argument is the - return type. The third argument is the domain. The fourth - argument is a NULL terminated array of argument types. The fifth - argument is TRUE if the function takes a variable number of - arguments, in which case the array of argument types indicates the - types of the first arguments. The domain and the argument array - may be NULL, in which case this is a stub method and that - information is not available. Stabs debugging uses this, and gets - the argument types from the mangled name. */ - -extern debug_type debug_make_method_type - (void *, debug_type, debug_type, debug_type *, bfd_boolean); - -/* Make a const qualified version of a given type. */ - -extern debug_type debug_make_const_type (void *, debug_type); - -/* Make a volatile qualified version of a given type. */ - -extern debug_type debug_make_volatile_type (void *, debug_type); - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -extern debug_type debug_make_undefined_tagged_type - (void *, const char *, enum debug_type_kind); - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object. The fourth argument is whether this is a - virtual class. The fifth argument is the visibility of the base - class. */ - -extern debug_baseclass debug_make_baseclass - (void *, debug_type, bfd_vma, bfd_boolean, enum debug_visibility); - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -extern debug_field debug_make_field - (void *, const char *, debug_type, bfd_vma, bfd_vma, enum debug_visibility); - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -extern debug_field debug_make_static_member - (void *, const char *, debug_type, const char *, enum debug_visibility); - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. Each - method variant is a method with this name but with different - argument types. */ - -extern debug_method debug_make_method - (void *, const char *, debug_method_variant *); - -/* Make a method variant. The second argument is the physical name of - the function. The third argument is the type of the function, - probably constructed by debug_make_method_type. The fourth - argument is the visibility. The fifth argument is whether this is - a const function. The sixth argument is whether this is a volatile - function. The seventh argument is the index in the virtual - function table, if any. The eighth argument is the virtual - function context. */ - -extern debug_method_variant debug_make_method_variant - (void *, const char *, debug_type, enum debug_visibility, bfd_boolean, - bfd_boolean, bfd_vma, debug_type); - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -extern debug_method_variant debug_make_static_method_variant - (void *, const char *, debug_type, enum debug_visibility, bfd_boolean, - bfd_boolean); - -/* Name a type. This returns a new type with an attached name. */ - -extern debug_type debug_name_type (void *, const char *, debug_type); - -/* Give a tag to a type, such as a struct or union. This returns a - new type with an attached tag. */ - -extern debug_type debug_tag_type (void *, const char *, debug_type); - -/* Record the size of a given type. */ - -extern bfd_boolean debug_record_type_size (void *, debug_type, unsigned int); - -/* Find a named type. */ - -extern debug_type debug_find_named_type (void *, const char *); - -/* Find a tagged type. */ - -extern debug_type debug_find_tagged_type - (void *, const char *, enum debug_type_kind); - -/* Get the kind of a type. */ - -extern enum debug_type_kind debug_get_type_kind (void *, debug_type); - -/* Get the name of a type. */ - -extern const char *debug_get_type_name (void *, debug_type); - -/* Get the size of a type. */ - -extern bfd_vma debug_get_type_size (void *, debug_type); - -/* Get the return type of a function or method type. */ - -extern debug_type debug_get_return_type (void *, debug_type); - -/* Get the NULL terminated array of parameter types for a function or - method type (actually, parameter types are not currently stored for - function types). This may be used to determine whether a method - type is a stub method or not. The last argument points to a - bfd_boolean which is set to TRUE if the function takes a variable - number of arguments. */ - -extern const debug_type *debug_get_parameter_types - (void *, debug_type, bfd_boolean *); - -/* Get the target type of a pointer or reference or const or volatile - type. */ - -extern debug_type debug_get_target_type (void *, debug_type); - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -extern const debug_field *debug_get_fields (void *, debug_type); - -/* Get the type of a field. */ - -extern debug_type debug_get_field_type (void *, debug_field); - -/* Get the name of a field. */ - -extern const char *debug_get_field_name (void *, debug_field); - -/* Get the bit position of a field within the containing structure. - If the field is a static member, this will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitpos (void *, debug_field); - -/* Get the bit size of a field. If the field is a static member, this - will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitsize (void *, debug_field); - -/* Get the visibility of a field. */ - -extern enum debug_visibility debug_get_field_visibility (void *, debug_field); - -/* Get the physical name of a field, if it is a static member. If the - field is not a static member, this will return NULL. */ - -extern const char *debug_get_field_physname (void *, debug_field); - -/* Write out the recorded debugging information. This takes a set of - function pointers which are called to do the actual writing. The - first void * is the debugging handle. The second void * is a handle - which is passed to the functions. */ - -extern bfd_boolean debug_write - (void *, const struct debug_write_fns *, void *); - -#endif /* DEBUG_H */ diff --git a/contrib/binutils-2.22/binutils/doc/Makefile.am b/contrib/binutils-2.22/binutils/doc/Makefile.am deleted file mode 100644 index a2295ca270..0000000000 --- a/contrib/binutils-2.22/binutils/doc/Makefile.am +++ /dev/null @@ -1,184 +0,0 @@ -## Process this file with automake to generate Makefile.in - -AUTOMAKE_OPTIONS = cygnus - -# What version of the manual you want; "all" includes everything -CONFIG=all - -# Options to extract the man page from as.texinfo -MANCONF = -Dman - -TEXI2POD = perl $(top_srcdir)/../etc/texi2pod.pl $(AM_MAKEINFOFLAGS) - -POD2MAN = pod2man --center="GNU Development Tools" \ - --release="binutils-$(VERSION)" --section=1 - -# List of man pages generated from binutils.texi -man_MANS = \ - addr2line.1 \ - ar.1 \ - dlltool.1 \ - nlmconv.1 \ - nm.1 \ - objcopy.1 \ - objdump.1 \ - ranlib.1 \ - readelf.1 \ - size.1 \ - strings.1 \ - strip.1 \ - elfedit.1 \ - windres.1 \ - windmc.1 \ - $(DEMANGLER_NAME).1 - -info_TEXINFOS = binutils.texi -binutils_TEXI = $(srcdir)/binutils.texi - -AM_MAKEINFOFLAGS = -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc -TEXI2DVI = texi2dvi -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -# Man page generation from texinfo -addr2line.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Daddr2line < $(binutils_TEXI) > addr2line.pod - -($(POD2MAN) addr2line.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f addr2line.pod - -ar.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dar < $(binutils_TEXI) > ar.pod - -($(POD2MAN) ar.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f ar.pod - -dlltool.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Ddlltool < $(binutils_TEXI) > dlltool.pod - -($(POD2MAN) dlltool.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f dlltool.pod - -nlmconv.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dnlmconv < $(binutils_TEXI) > nlmconv.pod - -($(POD2MAN) nlmconv.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f nlmconv.pod - -nm.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dnm < $(binutils_TEXI) > nm.pod - -($(POD2MAN) nm.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f nm.pod - -objcopy.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dobjcopy < $(binutils_TEXI) > objcopy.pod - -($(POD2MAN) objcopy.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f objcopy.pod - -objdump.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dobjdump < $(binutils_TEXI) > objdump.pod - -($(POD2MAN) objdump.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f objdump.pod - -ranlib.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dranlib < $(binutils_TEXI) > ranlib.pod - -($(POD2MAN) ranlib.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f ranlib.pod - -readelf.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dreadelf < $(binutils_TEXI) > readelf.pod - -($(POD2MAN) readelf.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f readelf.pod - -size.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dsize < $(binutils_TEXI) > size.pod - -($(POD2MAN) size.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f size.pod - -strings.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dstrings < $(binutils_TEXI) > strings.pod - -($(POD2MAN) strings.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f strings.pod - -strip.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dstrip < $(binutils_TEXI) > strip.pod - -($(POD2MAN) strip.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f strip.pod - -elfedit.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Delfedit < $(binutils_TEXI) > elfedit.pod - -($(POD2MAN) elfedit.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f elfedit.pod - -windres.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dwindres < $(binutils_TEXI) > windres.pod - -($(POD2MAN) windres.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f windres.pod - -windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod - -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f windmc.pod - -cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod - -($(POD2MAN) $(DEMANGLER_NAME).pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f $(DEMANGLER_NAME).pod - -MOSTLYCLEANFILES = $(DEMANGLER_NAME).1 - -$(DEMANGLER_NAME).1: cxxfilt.man Makefile - if test -f cxxfilt.man; then \ - man=cxxfilt.man; \ - else \ - man=$(srcdir)/cxxfilt.man; \ - fi; \ - sed -e 's/@PROGRAM@/$(DEMANGLER_NAME)/' \ - -e 's/cxxfilt/$(DEMANGLER_NAME)/' < $$man \ - > $(DEMANGLER_NAME).1 - -# We want install to imply install-info as per GNU standards, despite the -# cygnus option. -install-data-local: install-info - -MAINTAINERCLEANFILES = binutils.info - -# Automake 1.9 will only build info files in the objdir if they are -# mentioned in DISTCLEANFILES. It doesn't have to be unconditional, -# though, so we use a bogus condition. -if GENINSRC_NEVER -DISTCLEANFILES = binutils.info -endif - -# Maintenance - -# We need it for the taz target in ../../Makefile.in. -info-local: $(MANS) diff --git a/contrib/binutils-2.22/binutils/doc/Makefile.in b/contrib/binutils-2.22/binutils/doc/Makefile.in deleted file mode 100644 index 3acf28a55b..0000000000 --- a/contrib/binutils-2.22/binutils/doc/Makefile.in +++ /dev/null @@ -1,869 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = doc -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ - $(top_srcdir)/../config/zlib.m4 \ - $(top_srcdir)/../bfd/warning.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/gettext-sister.m4 \ - $(top_srcdir)/../config/iconv.m4 \ - $(top_srcdir)/../config/largefile.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/lib-ld.m4 \ - $(top_srcdir)/../config/lib-link.m4 \ - $(top_srcdir)/../config/lib-prefix.m4 \ - $(top_srcdir)/../config/nls.m4 \ - $(top_srcdir)/../config/override.m4 \ - $(top_srcdir)/../config/plugins.m4 \ - $(top_srcdir)/../config/po.m4 \ - $(top_srcdir)/../config/progtest.m4 \ - $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ - $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ - $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -depcomp = -am__depfiles_maybe = -SOURCES = -INFO_DEPS = binutils.info -TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex -am__TEXINFO_TEX_DIR = $(top_srcdir)/../texinfo -DVIS = binutils.dvi -PDFS = binutils.pdf -PSS = binutils.ps -HTMLS = binutils.html -TEXINFOS = binutils.texi -TEXI2PDF = $(TEXI2DVI) --pdf --batch -MAKEINFOHTML = $(MAKEINFO) --html -AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) -DVIPS = dvips -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -man1dir = $(mandir)/man1 -am__installdirs = "$(DESTDIR)$(man1dir)" -NROFF = nroff -MANS = $(man_MANS) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BUILD_DLLTOOL = @BUILD_DLLTOOL@ -BUILD_DLLWRAP = @BUILD_DLLWRAP@ -BUILD_INSTALL_MISC = @BUILD_INSTALL_MISC@ -BUILD_MISC = @BUILD_MISC@ -BUILD_NLMCONV = @BUILD_NLMCONV@ -BUILD_SRCONV = @BUILD_SRCONV@ -BUILD_WINDMC = @BUILD_WINDMC@ -BUILD_WINDRES = @BUILD_WINDRES@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CC_FOR_BUILD = @CC_FOR_BUILD@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ -DEMANGLER_NAME = @DEMANGLER_NAME@ -DEPDIR = @DEPDIR@ -DLLTOOL_DEFS = @DLLTOOL_DEFS@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EMULATION = @EMULATION@ -EMULATION_VECTOR = @EMULATION_VECTOR@ -EXEEXT = @EXEEXT@ -EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ -FGREP = @FGREP@ -GENCAT = @GENCAT@ -GMSGFMT = @GMSGFMT@ -GREP = @GREP@ -HDEFINES = @HDEFINES@ -INCINTL = @INCINTL@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBINTL_DEP = @LIBINTL_DEP@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -MSGFMT = @MSGFMT@ -MSGMERGE = @MSGMERGE@ -NLMCONV_DEFS = @NLMCONV_DEFS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NO_WERROR = @NO_WERROR@ -OBJDUMP = @OBJDUMP@ -OBJDUMP_DEFS = @OBJDUMP_DEFS@ -OBJDUMP_PRIVATE_OFILES = @OBJDUMP_PRIVATE_OFILES@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARN_CFLAGS = @WARN_CFLAGS@ -XGETTEXT = @XGETTEXT@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = cygnus - -# What version of the manual you want; "all" includes everything -CONFIG = all - -# Options to extract the man page from as.texinfo -MANCONF = -Dman -TEXI2POD = perl $(top_srcdir)/../etc/texi2pod.pl $(AM_MAKEINFOFLAGS) -POD2MAN = pod2man --center="GNU Development Tools" \ - --release="binutils-$(VERSION)" --section=1 - - -# List of man pages generated from binutils.texi -man_MANS = \ - addr2line.1 \ - ar.1 \ - dlltool.1 \ - nlmconv.1 \ - nm.1 \ - objcopy.1 \ - objdump.1 \ - ranlib.1 \ - readelf.1 \ - size.1 \ - strings.1 \ - strip.1 \ - elfedit.1 \ - windres.1 \ - windmc.1 \ - $(DEMANGLER_NAME).1 - -info_TEXINFOS = binutils.texi -binutils_TEXI = $(srcdir)/binutils.texi -AM_MAKEINFOFLAGS = -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -TEXI2DVI = texi2dvi -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -MOSTLYCLEANFILES = $(DEMANGLER_NAME).1 -MAINTAINERCLEANFILES = binutils.info - -# Automake 1.9 will only build info files in the objdir if they are -# mentioned in DISTCLEANFILES. It doesn't have to be unconditional, -# though, so we use a bogus condition. -@GENINSRC_NEVER_TRUE@DISTCLEANFILES = binutils.info -all: all-am - -.SUFFIXES: -.SUFFIXES: .dvi .ps -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign doc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -binutils.info: binutils.texi - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ - rm -rf $$backupdir && mkdir $$backupdir && \ - if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ - for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ - if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ - done; \ - else :; fi && \ - if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ `test -f 'binutils.texi' || echo '$(srcdir)/'`binutils.texi; \ - then \ - rc=0; \ - else \ - rc=$$?; \ - $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ - fi; \ - rm -rf $$backupdir; exit $$rc - -binutils.dvi: binutils.texi - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) -o $@ `test -f 'binutils.texi' || echo '$(srcdir)/'`binutils.texi - -binutils.pdf: binutils.texi - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) -o $@ `test -f 'binutils.texi' || echo '$(srcdir)/'`binutils.texi - -binutils.html: binutils.texi - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) `test -f 'binutils.texi' || echo '$(srcdir)/'`binutils.texi; \ - then \ - rm -rf $@; \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ - else \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ - exit 1; \ - fi -.dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< - -uninstall-dvi-am: - @$(NORMAL_UNINSTALL) - @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ - rm -f "$(DESTDIR)$(dvidir)/$$f"; \ - done - -uninstall-html-am: - @$(NORMAL_UNINSTALL) - @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ - rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ - done - -uninstall-info-am: - @$(PRE_UNINSTALL) - @if test -d '$(DESTDIR)$(infodir)' && \ - (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ - if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ - then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ - done; \ - else :; fi - @$(NORMAL_UNINSTALL) - @list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ - (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ - echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ - rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ - else :; fi); \ - done - -uninstall-pdf-am: - @$(NORMAL_UNINSTALL) - @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ - rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ - done - -uninstall-ps-am: - @$(NORMAL_UNINSTALL) - @list='$(PSS)'; test -n "$(psdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ - rm -f "$(DESTDIR)$(psdir)/$$f"; \ - done - -dist-info: $(INFO_DEPS) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; \ - for base in $$list; do \ - case $$base in \ - $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$base; then d=.; else d=$(srcdir); fi; \ - base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ - for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ - if test -f $$file; then \ - relfile=`expr "$$file" : "$$d/\(.*\)"`; \ - test -f "$(distdir)/$$relfile" || \ - cp -p $$file "$(distdir)/$$relfile"; \ - else :; fi; \ - done; \ - done - -mostlyclean-aminfo: - -rm -rf binutils.aux binutils.cp binutils.cps binutils.fn binutils.fns \ - binutils.ky binutils.log binutils.pg binutils.pgs \ - binutils.tmp binutils.toc binutils.tp binutils.tps \ - binutils.vr binutils.vrs - -clean-aminfo: - -test -z "binutils.dvi binutils.pdf binutils.ps binutils.html" \ - || rm -rf binutils.dvi binutils.pdf binutils.ps binutils.html - -maintainer-clean-aminfo: - @list='$(INFO_DEPS)'; for i in $$list; do \ - i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ - echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ - rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ - done - -clean-info: mostlyclean-aminfo clean-aminfo -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list=''; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - -check-am: -check: check-am -all-am: Makefile $(MANS) -installdirs: - for dir in "$(DESTDIR)$(man1dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: $(DVIS) - -html: html-am - -html-am: $(HTMLS) - -info: info-am - -info-am: $(INFO_DEPS) info-local - -install-data-am: install-data-local install-man - -install-dvi: install-dvi-am - -install-dvi-am: $(DVIS) - @$(NORMAL_INSTALL) - test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" - @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ - done -install-exec-am: - -install-html: install-html-am - -install-html-am: $(HTMLS) - @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" - @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ - for p in $$list; do \ - if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ - $(am__strip_dir) \ - if test -d "$$d$$p"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ - $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ - else \ - list2="$$list2 $$d$$p"; \ - fi; \ - done; \ - test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ - done; } -install-info: install-info-am - -install-info-am: $(INFO_DEPS) - @$(NORMAL_INSTALL) - test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ - for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$file; then d=.; else d=$(srcdir); fi; \ - file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ - for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ - $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ - if test -f $$ifile; then \ - echo "$$ifile"; \ - else : ; fi; \ - done; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done - @$(POST_INSTALL) - @if (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ - install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ - done; \ - else : ; fi -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: $(PDFS) - @$(NORMAL_INSTALL) - test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" - @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done -install-ps: install-ps-am - -install-ps-am: $(PSS) - @$(NORMAL_INSTALL) - test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" - @list='$(PSS)'; test -n "$(psdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-aminfo \ - maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: $(PDFS) - -ps: ps-am - -ps-am: $(PSS) - -uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ - uninstall-man uninstall-pdf-am uninstall-ps-am - -uninstall-man: uninstall-man1 - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ - clean-info clean-libtool dist-info distclean distclean-generic \ - distclean-libtool dvi dvi-am html html-am info info-am \ - info-local install install-am install-data install-data-am \ - install-data-local install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man1 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ - mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \ - pdf-am ps ps-am uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-man \ - uninstall-man1 uninstall-pdf-am uninstall-ps-am - - -# Man page generation from texinfo -addr2line.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Daddr2line < $(binutils_TEXI) > addr2line.pod - -($(POD2MAN) addr2line.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f addr2line.pod - -ar.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dar < $(binutils_TEXI) > ar.pod - -($(POD2MAN) ar.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f ar.pod - -dlltool.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Ddlltool < $(binutils_TEXI) > dlltool.pod - -($(POD2MAN) dlltool.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f dlltool.pod - -nlmconv.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dnlmconv < $(binutils_TEXI) > nlmconv.pod - -($(POD2MAN) nlmconv.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f nlmconv.pod - -nm.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dnm < $(binutils_TEXI) > nm.pod - -($(POD2MAN) nm.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f nm.pod - -objcopy.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dobjcopy < $(binutils_TEXI) > objcopy.pod - -($(POD2MAN) objcopy.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f objcopy.pod - -objdump.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dobjdump < $(binutils_TEXI) > objdump.pod - -($(POD2MAN) objdump.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f objdump.pod - -ranlib.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dranlib < $(binutils_TEXI) > ranlib.pod - -($(POD2MAN) ranlib.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f ranlib.pod - -readelf.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dreadelf < $(binutils_TEXI) > readelf.pod - -($(POD2MAN) readelf.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f readelf.pod - -size.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dsize < $(binutils_TEXI) > size.pod - -($(POD2MAN) size.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f size.pod - -strings.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dstrings < $(binutils_TEXI) > strings.pod - -($(POD2MAN) strings.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f strings.pod - -strip.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dstrip < $(binutils_TEXI) > strip.pod - -($(POD2MAN) strip.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f strip.pod - -elfedit.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Delfedit < $(binutils_TEXI) > elfedit.pod - -($(POD2MAN) elfedit.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f elfedit.pod - -windres.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dwindres < $(binutils_TEXI) > windres.pod - -($(POD2MAN) windres.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f windres.pod - -windmc.1: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dwindmc < $(binutils_TEXI) > windmc.pod - -($(POD2MAN) windmc.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f windmc.pod - -cxxfilt.man: $(binutils_TEXI) $(binutils_TEXINFOS) - touch $@ - -$(TEXI2POD) $(MANCONF) -Dcxxfilt < $(binutils_TEXI) > $(DEMANGLER_NAME).pod - -($(POD2MAN) $(DEMANGLER_NAME).pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1) - rm -f $(DEMANGLER_NAME).pod - -$(DEMANGLER_NAME).1: cxxfilt.man Makefile - if test -f cxxfilt.man; then \ - man=cxxfilt.man; \ - else \ - man=$(srcdir)/cxxfilt.man; \ - fi; \ - sed -e 's/@PROGRAM@/$(DEMANGLER_NAME)/' \ - -e 's/cxxfilt/$(DEMANGLER_NAME)/' < $$man \ - > $(DEMANGLER_NAME).1 - -# We want install to imply install-info as per GNU standards, despite the -# cygnus option. -install-data-local: install-info - -# Maintenance - -# We need it for the taz target in ../../Makefile.in. -info-local: $(MANS) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/binutils-2.22/binutils/doc/addr2line.1 b/contrib/binutils-2.22/binutils/doc/addr2line.1 deleted file mode 100644 index a89767b5a5..0000000000 --- a/contrib/binutils-2.22/binutils/doc/addr2line.1 +++ /dev/null @@ -1,287 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "ADDR2LINE 1" -.TH ADDR2LINE 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -addr2line \- convert addresses into file names and line numbers. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -addr2line [\fB\-a\fR|\fB\-\-addresses\fR] - [\fB\-b\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] - [\fB\-e\fR \fIfilename\fR|\fB\-\-exe=\fR\fIfilename\fR] - [\fB\-f\fR|\fB\-\-functions\fR] [\fB\-s\fR|\fB\-\-basename\fR] - [\fB\-i\fR|\fB\-\-inlines\fR] - [\fB\-p\fR|\fB\-\-pretty\-print\fR] - [\fB\-j\fR|\fB\-\-section=\fR\fIname\fR] - [\fB\-H\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] - [addr addr ...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBaddr2line\fR translates addresses into file names and line numbers. -Given an address in an executable or an offset in a section of a relocatable -object, it uses the debugging information to figure out which file name and -line number are associated with it. -.PP -The executable or relocatable object to use is specified with the \fB\-e\fR -option. The default is the file \fIa.out\fR. The section in the relocatable -object to use is specified with the \fB\-j\fR option. -.PP -\&\fBaddr2line\fR has two modes of operation. -.PP -In the first, hexadecimal addresses are specified on the command line, -and \fBaddr2line\fR displays the file name and line number for each -address. -.PP -In the second, \fBaddr2line\fR reads hexadecimal addresses from -standard input, and prints the file name and line number for each -address on standard output. In this mode, \fBaddr2line\fR may be used -in a pipe to convert dynamically chosen addresses. -.PP -The format of the output is \fB\s-1FILENAME:LINENO\s0\fR. The file name and -line number for each address is printed on a separate line. If the -\&\fB\-f\fR option is used, then each \fB\s-1FILENAME:LINENO\s0\fR line is -preceded by a \fB\s-1FUNCTIONNAME\s0\fR line which is the name of the function -containing the address. If the \fB\-a\fR option is used, then the -address read is first printed. -.PP -If the file name or function name can not be determined, -\&\fBaddr2line\fR will print two question marks in their place. If the -line number can not be determined, \fBaddr2line\fR will print 0. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-addresses\fR" 4 -.IX Item "--addresses" -.PD -Display address before function names or file and line number -information. The address is printed with a \fB0x\fR prefix to easily -identify it. -.IP "\fB\-b\fR \fIbfdname\fR" 4 -.IX Item "-b bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Specify that the object-code format for the object files is -\&\fIbfdname\fR. -.IP "\fB\-C\fR" 4 -.IX Item "-C" -.PD 0 -.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 -.IX Item "--demangle[=style]" -.PD -Decode (\fIdemangle\fR) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes \*(C+ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. -.IP "\fB\-e\fR \fIfilename\fR" 4 -.IX Item "-e filename" -.PD 0 -.IP "\fB\-\-exe=\fR\fIfilename\fR" 4 -.IX Item "--exe=filename" -.PD -Specify the name of the executable for which addresses should be -translated. The default file is \fIa.out\fR. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -.PD 0 -.IP "\fB\-\-functions\fR" 4 -.IX Item "--functions" -.PD -Display function names as well as file and line number information. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-basenames\fR" 4 -.IX Item "--basenames" -.PD -Display only the base of each file name. -.IP "\fB\-i\fR" 4 -.IX Item "-i" -.PD 0 -.IP "\fB\-\-inlines\fR" 4 -.IX Item "--inlines" -.PD -If the address belongs to a function that was inlined, the source -information for all enclosing scopes back to the first non-inlined -function will also be printed. For example, if \f(CW\*(C`main\*(C'\fR inlines -\&\f(CW\*(C`callee1\*(C'\fR which inlines \f(CW\*(C`callee2\*(C'\fR, and address is from -\&\f(CW\*(C`callee2\*(C'\fR, the source information for \f(CW\*(C`callee1\*(C'\fR and \f(CW\*(C`main\*(C'\fR -will also be printed. -.IP "\fB\-j\fR" 4 -.IX Item "-j" -.PD 0 -.IP "\fB\-\-section\fR" 4 -.IX Item "--section" -.PD -Read offsets relative to the specified section instead of absolute addresses. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-pretty\-print\fR" 4 -.IX Item "--pretty-print" -.PD -Make the output more human friendly: each location are printed on one line. -If option \fB\-i\fR is specified, lines for all enclosing scopes are -prefixed with \fB(inlined by)\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/ar.1 b/contrib/binutils-2.22/binutils/doc/ar.1 deleted file mode 100644 index 70f190405e..0000000000 --- a/contrib/binutils-2.22/binutils/doc/ar.1 +++ /dev/null @@ -1,439 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "AR 1" -.TH AR 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -ar \- create, modify, and extract from archives -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -ar [\fB\-\-plugin\fR \fIname\fR] [\fB\-X32_64\fR] [\fB\-\fR]\fIp\fR[\fImod\fR [\fIrelpos\fR] [\fIcount\fR]] [\fB\-\-target\fR \fIbfdname\fR] \fIarchive\fR [\fImember\fR...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -The \s-1GNU\s0 \fBar\fR program creates, modifies, and extracts from -archives. An \fIarchive\fR is a single file holding a collection of -other files in a structure that makes it possible to retrieve -the original individual files (called \fImembers\fR of the archive). -.PP -The original files' contents, mode (permissions), timestamp, owner, and -group are preserved in the archive, and can be restored on -extraction. -.PP -\&\s-1GNU\s0 \fBar\fR can maintain archives whose members have names of any -length; however, depending on how \fBar\fR is configured on your -system, a limit on member-name length may be imposed for compatibility -with archive formats maintained with other tools. If it exists, the -limit is often 15 characters (typical of formats related to a.out) or 16 -characters (typical of formats related to coff). -.PP -\&\fBar\fR is considered a binary utility because archives of this sort -are most often used as \fIlibraries\fR holding commonly needed -subroutines. -.PP -\&\fBar\fR creates an index to the symbols defined in relocatable -object modules in the archive when you specify the modifier \fBs\fR. -Once created, this index is updated in the archive whenever \fBar\fR -makes a change to its contents (save for the \fBq\fR update operation). -An archive with such an index speeds up linking to the library, and -allows routines in the library to call each other without regard to -their placement in the archive. -.PP -You may use \fBnm \-s\fR or \fBnm \-\-print\-armap\fR to list this index -table. If an archive lacks the table, another form of \fBar\fR called -\&\fBranlib\fR can be used to add just the table. -.PP -\&\s-1GNU\s0 \fBar\fR can optionally create a \fIthin\fR archive, -which contains a symbol index and references to the original copies -of the member files of the archives. Such an archive is useful -for building libraries for use within a local build, where the -relocatable objects are expected to remain available, and copying the -contents of each object would only waste time and space. Thin archives -are also \fIflattened\fR, so that adding one or more archives to a -thin archive will add the elements of the nested archive individually. -The paths to the elements of the archive are stored relative to the -archive itself. -.PP -\&\s-1GNU\s0 \fBar\fR is designed to be compatible with two different -facilities. You can control its activity using command-line options, -like the different varieties of \fBar\fR on Unix systems; or, if you -specify the single command-line option \fB\-M\fR, you can control it -with a script supplied via standard input, like the \s-1MRI\s0 \*(L"librarian\*(R" -program. -.SH "OPTIONS" -.IX Header "OPTIONS" -\&\s-1GNU\s0 \fBar\fR allows you to mix the operation code \fIp\fR and modifier -flags \fImod\fR in any order, within the first command-line argument. -.PP -If you wish, you may begin the first command-line argument with a -dash. -.PP -The \fIp\fR keyletter specifies what operation to execute; it may be -any of the following, but you must specify only one of them: -.IP "\fBd\fR" 4 -.IX Item "d" -\&\fIDelete\fR modules from the archive. Specify the names of modules to -be deleted as \fImember\fR...; the archive is untouched if you -specify no files to delete. -.Sp -If you specify the \fBv\fR modifier, \fBar\fR lists each module -as it is deleted. -.IP "\fBm\fR" 4 -.IX Item "m" -Use this operation to \fImove\fR members in an archive. -.Sp -The ordering of members in an archive can make a difference in how -programs are linked using the library, if a symbol is defined in more -than one member. -.Sp -If no modifiers are used with \f(CW\*(C`m\*(C'\fR, any members you name in the -\&\fImember\fR arguments are moved to the \fIend\fR of the archive; -you can use the \fBa\fR, \fBb\fR, or \fBi\fR modifiers to move them to a -specified place instead. -.IP "\fBp\fR" 4 -.IX Item "p" -\&\fIPrint\fR the specified members of the archive, to the standard -output file. If the \fBv\fR modifier is specified, show the member -name before copying its contents to standard output. -.Sp -If you specify no \fImember\fR arguments, all the files in the archive are -printed. -.IP "\fBq\fR" 4 -.IX Item "q" -\&\fIQuick append\fR; Historically, add the files \fImember\fR... to the end of -\&\fIarchive\fR, without checking for replacement. -.Sp -The modifiers \fBa\fR, \fBb\fR, and \fBi\fR do \fInot\fR affect this -operation; new members are always placed at the end of the archive. -.Sp -The modifier \fBv\fR makes \fBar\fR list each file as it is appended. -.Sp -Since the point of this operation is speed, the archive's symbol table -index is not updated, even if it already existed; you can use \fBar s\fR or -\&\fBranlib\fR explicitly to update the symbol table index. -.Sp -However, too many different systems assume quick append rebuilds the -index, so \s-1GNU\s0 \fBar\fR implements \fBq\fR as a synonym for \fBr\fR. -.IP "\fBr\fR" 4 -.IX Item "r" -Insert the files \fImember\fR... into \fIarchive\fR (with -\&\fIreplacement\fR). This operation differs from \fBq\fR in that any -previously existing members are deleted if their names match those being -added. -.Sp -If one of the files named in \fImember\fR... does not exist, \fBar\fR -displays an error message, and leaves undisturbed any existing members -of the archive matching that name. -.Sp -By default, new members are added at the end of the file; but you may -use one of the modifiers \fBa\fR, \fBb\fR, or \fBi\fR to request -placement relative to some existing member. -.Sp -The modifier \fBv\fR used with this operation elicits a line of -output for each file inserted, along with one of the letters \fBa\fR or -\&\fBr\fR to indicate whether the file was appended (no old member -deleted) or replaced. -.IP "\fBs\fR" 4 -.IX Item "s" -Add an index to the archive, or update it if it already exists. Note -this command is an exception to the rule that there can only be one -command letter, as it is possible to use it as either a command or a -modifier. In either case it does the same thing. -.IP "\fBt\fR" 4 -.IX Item "t" -Display a \fItable\fR listing the contents of \fIarchive\fR, or those -of the files listed in \fImember\fR... that are present in the -archive. Normally only the member name is shown; if you also want to -see the modes (permissions), timestamp, owner, group, and size, you can -request that by also specifying the \fBv\fR modifier. -.Sp -If you do not specify a \fImember\fR, all files in the archive -are listed. -.Sp -If there is more than one file with the same name (say, \fBfie\fR) in -an archive (say \fBb.a\fR), \fBar t b.a fie\fR lists only the -first instance; to see them all, you must ask for a complete -listing\-\-\-in our example, \fBar t b.a\fR. -.IP "\fBx\fR" 4 -.IX Item "x" -\&\fIExtract\fR members (named \fImember\fR) from the archive. You can -use the \fBv\fR modifier with this operation, to request that -\&\fBar\fR list each name as it extracts it. -.Sp -If you do not specify a \fImember\fR, all files in the archive -are extracted. -.Sp -Files cannot be extracted from a thin archive. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Displays the list of command line options supported by \fBar\fR -and then exits. -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -Displays the version information of \fBar\fR and then exits. -.PP -A number of modifiers (\fImod\fR) may immediately follow the \fIp\fR -keyletter, to specify variations on an operation's behavior: -.IP "\fBa\fR" 4 -.IX Item "a" -Add new files \fIafter\fR an existing member of the -archive. If you use the modifier \fBa\fR, the name of an existing archive -member must be present as the \fIrelpos\fR argument, before the -\&\fIarchive\fR specification. -.IP "\fBb\fR" 4 -.IX Item "b" -Add new files \fIbefore\fR an existing member of the -archive. If you use the modifier \fBb\fR, the name of an existing archive -member must be present as the \fIrelpos\fR argument, before the -\&\fIarchive\fR specification. (same as \fBi\fR). -.IP "\fBc\fR" 4 -.IX Item "c" -\&\fICreate\fR the archive. The specified \fIarchive\fR is always -created if it did not exist, when you request an update. But a warning is -issued unless you specify in advance that you expect to create it, by -using this modifier. -.IP "\fBD\fR" 4 -.IX Item "D" -Operate in \fIdeterministic\fR mode. When adding files and the archive -index use zero for UIDs, GIDs, timestamps, and use consistent file modes -for all files. When this option is used, if \fBar\fR is used with -identical options and identical input files, multiple runs will create -identical output files regardless of the input files' owners, groups, -file modes, or modification times. -.IP "\fBf\fR" 4 -.IX Item "f" -Truncate names in the archive. \s-1GNU\s0 \fBar\fR will normally permit file -names of any length. This will cause it to create archives which are -not compatible with the native \fBar\fR program on some systems. If -this is a concern, the \fBf\fR modifier may be used to truncate file -names when putting them in the archive. -.IP "\fBi\fR" 4 -.IX Item "i" -Insert new files \fIbefore\fR an existing member of the -archive. If you use the modifier \fBi\fR, the name of an existing archive -member must be present as the \fIrelpos\fR argument, before the -\&\fIarchive\fR specification. (same as \fBb\fR). -.IP "\fBl\fR" 4 -.IX Item "l" -This modifier is accepted but not used. -.IP "\fBN\fR" 4 -.IX Item "N" -Uses the \fIcount\fR parameter. This is used if there are multiple -entries in the archive with the same name. Extract or delete instance -\&\fIcount\fR of the given name from the archive. -.IP "\fBo\fR" 4 -.IX Item "o" -Preserve the \fIoriginal\fR dates of members when extracting them. If -you do not specify this modifier, files extracted from the archive -are stamped with the time of extraction. -.IP "\fBP\fR" 4 -.IX Item "P" -Use the full path name when matching names in the archive. \s-1GNU\s0 -\&\fBar\fR can not create an archive with a full path name (such archives -are not \s-1POSIX\s0 complaint), but other archive creators can. This option -will cause \s-1GNU\s0 \fBar\fR to match file names using a complete path -name, which can be convenient when extracting a single file from an -archive created by another tool. -.IP "\fBs\fR" 4 -.IX Item "s" -Write an object-file index into the archive, or update an existing one, -even if no other change is made to the archive. You may use this modifier -flag either with any operation, or alone. Running \fBar s\fR on an -archive is equivalent to running \fBranlib\fR on it. -.IP "\fBS\fR" 4 -.IX Item "S" -Do not generate an archive symbol table. This can speed up building a -large library in several steps. The resulting archive can not be used -with the linker. In order to build a symbol table, you must omit the -\&\fBS\fR modifier on the last execution of \fBar\fR, or you must run -\&\fBranlib\fR on the archive. -.IP "\fBT\fR" 4 -.IX Item "T" -Make the specified \fIarchive\fR a \fIthin\fR archive. If it already -exists and is a regular archive, the existing members must be present -in the same directory as \fIarchive\fR. -.IP "\fBu\fR" 4 -.IX Item "u" -Normally, \fBar r\fR... inserts all files -listed into the archive. If you would like to insert \fIonly\fR those -of the files you list that are newer than existing members of the same -names, use this modifier. The \fBu\fR modifier is allowed only for the -operation \fBr\fR (replace). In particular, the combination \fBqu\fR is -not allowed, since checking the timestamps would lose any speed -advantage from the operation \fBq\fR. -.IP "\fBv\fR" 4 -.IX Item "v" -This modifier requests the \fIverbose\fR version of an operation. Many -operations display additional information, such as filenames processed, -when the modifier \fBv\fR is appended. -.IP "\fBV\fR" 4 -.IX Item "V" -This modifier shows the version number of \fBar\fR. -.PP -\&\fBar\fR ignores an initial option spelt \fB\-X32_64\fR, for -compatibility with \s-1AIX\s0. The behaviour produced by this option is the -default for \s-1GNU\s0 \fBar\fR. \fBar\fR does not support any of the other -\&\fB\-X\fR options; in particular, it does not support \fB\-X32\fR -which is the default for \s-1AIX\s0 \fBar\fR. -.PP -The optional command line switch \fB\-\-plugin\fR \fIname\fR causes -\&\fBar\fR to load the plugin called \fIname\fR which adds support -for more file formats. This option is only available if the toolchain -has been built with plugin support enabled. -.PP -The optional command line switch \fB\-\-target\fR \fIbfdname\fR -specifies that the archive members are in an object code format -different from your system's default format. See -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fInm\fR\|(1), \fIranlib\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/binutils.texi b/contrib/binutils-2.22/binutils/doc/binutils.texi deleted file mode 100644 index 35ccb87a10..0000000000 --- a/contrib/binutils-2.22/binutils/doc/binutils.texi +++ /dev/null @@ -1,4713 +0,0 @@ -\input texinfo @c -*- Texinfo -*- -@setfilename binutils.info -@settitle @sc{gnu} Binary Utilities -@finalout -@synindex ky cp - -@c man begin INCLUDE -@include bfdver.texi -@c man end - -@copying -@c man begin COPYRIGHT -Copyright @copyright{} 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled ``GNU Free Documentation License''. - -@c man end -@end copying - -@dircategory Software development -@direntry -* Binutils: (binutils). The GNU binary utilities. -@end direntry - -@dircategory Individual utilities -@direntry -* addr2line: (binutils)addr2line. Convert addresses to file and line. -* ar: (binutils)ar. Create, modify, and extract from archives. -* c++filt: (binutils)c++filt. Filter to demangle encoded C++ symbols. -* cxxfilt: (binutils)c++filt. MS-DOS name for c++filt. -* dlltool: (binutils)dlltool. Create files needed to build and use DLLs. -* nlmconv: (binutils)nlmconv. Converts object code into an NLM. -* nm: (binutils)nm. List symbols from object files. -* objcopy: (binutils)objcopy. Copy and translate object files. -* objdump: (binutils)objdump. Display information from object files. -* ranlib: (binutils)ranlib. Generate index to archive contents. -* readelf: (binutils)readelf. Display the contents of ELF format files. -* size: (binutils)size. List section sizes and total size. -* strings: (binutils)strings. List printable strings from files. -* strip: (binutils)strip. Discard symbols. -* elfedit: (binutils)elfedit. Update the ELF header of ELF files. -* windmc: (binutils)windmc. Generator for Windows message resources. -* windres: (binutils)windres. Manipulate Windows resources. -@end direntry - -@titlepage -@title The @sc{gnu} Binary Utilities -@ifset VERSION_PACKAGE -@subtitle @value{VERSION_PACKAGE} -@end ifset -@subtitle Version @value{VERSION} -@sp 1 -@subtitle @value{UPDATED} -@author Roland H. Pesch -@author Jeffrey M. Osier -@author Cygnus Support -@page - -@tex -{\parskip=0pt \hfill Cygnus Support\par \hfill -Texinfo \texinfoversion\par } -@end tex - -@vskip 0pt plus 1filll -@insertcopying -@end titlepage -@contents - -@node Top -@top Introduction - -@cindex version -This brief manual contains documentation for the @sc{gnu} binary -utilities -@ifset VERSION_PACKAGE -@value{VERSION_PACKAGE} -@end ifset -version @value{VERSION}: - -@iftex -@table @code -@item ar -Create, modify, and extract from archives - -@item nm -List symbols from object files - -@item objcopy -Copy and translate object files - -@item objdump -Display information from object files - -@item ranlib -Generate index to archive contents - -@item readelf -Display the contents of ELF format files. - -@item size -List file section sizes and total size - -@item strings -List printable strings from files - -@item strip -Discard symbols - -@item elfedit -Update the ELF header of ELF files. - -@item c++filt -Demangle encoded C++ symbols (on MS-DOS, this program is named -@code{cxxfilt}) - -@item addr2line -Convert addresses into file names and line numbers - -@item nlmconv -Convert object code into a Netware Loadable Module - -@item windres -Manipulate Windows resources - -@item windmc -Genertor for Windows message resources - -@item dlltool -Create the files needed to build and use Dynamic Link Libraries -@end table -@end iftex - -This document is distributed under the terms of the GNU Free -Documentation License version 1.3. A copy of the license is included -in the section entitled ``GNU Free Documentation License''. - -@menu -* ar:: Create, modify, and extract from archives -* nm:: List symbols from object files -* objcopy:: Copy and translate object files -* objdump:: Display information from object files -* ranlib:: Generate index to archive contents -* readelf:: Display the contents of ELF format files -* size:: List section sizes and total size -* strings:: List printable strings from files -* strip:: Discard symbols -* elfedit:: Update the ELF header of ELF files -* c++filt:: Filter to demangle encoded C++ symbols -* cxxfilt: c++filt. MS-DOS name for c++filt -* addr2line:: Convert addresses to file and line -* nlmconv:: Converts object code into an NLM -* windres:: Manipulate Windows resources -* windmc:: Generator for Windows message resources -* dlltool:: Create files needed to build and use DLLs -* Common Options:: Command-line options for all utilities -* Selecting the Target System:: How these utilities determine the target -* Reporting Bugs:: Reporting Bugs -* GNU Free Documentation License:: GNU Free Documentation License -* Binutils Index:: Binutils Index -@end menu - -@node ar -@chapter ar - -@kindex ar -@cindex archives -@cindex collections of files - -@c man title ar create, modify, and extract from archives - -@smallexample -ar [@option{--plugin} @var{name}] [-]@var{p}[@var{mod} [@var{relpos}] [@var{count}]] [@option{--target} @var{bfdname}] @var{archive} [@var{member}@dots{}] -ar -M [ }), and continues executing even after -errors. If you redirect standard input to a script file, no prompts are -issued, and @command{ar} abandons execution (with a nonzero exit code) -on any error. - -The @command{ar} command language is @emph{not} designed to be equivalent -to the command-line options; in fact, it provides somewhat less control -over archives. The only purpose of the command language is to ease the -transition to @sc{gnu} @command{ar} for developers who already have scripts -written for the MRI ``librarian'' program. - -The syntax for the @command{ar} command language is straightforward: -@itemize @bullet -@item -commands are recognized in upper or lower case; for example, @code{LIST} -is the same as @code{list}. In the following descriptions, commands are -shown in upper case for clarity. - -@item -a single command may appear on each line; it is the first word on the -line. - -@item -empty lines are allowed, and have no effect. - -@item -comments are allowed; text after either of the characters @samp{*} -or @samp{;} is ignored. - -@item -Whenever you use a list of names as part of the argument to an @command{ar} -command, you can separate the individual names with either commas or -blanks. Commas are shown in the explanations below, for clarity. - -@item -@samp{+} is used as a line continuation character; if @samp{+} appears -at the end of a line, the text on the following line is considered part -of the current command. -@end itemize - -Here are the commands you can use in @command{ar} scripts, or when using -@command{ar} interactively. Three of them have special significance: - -@code{OPEN} or @code{CREATE} specify a @dfn{current archive}, which is -a temporary file required for most of the other commands. - -@code{SAVE} commits the changes so far specified by the script. Prior -to @code{SAVE}, commands affect only the temporary copy of the current -archive. - -@table @code -@item ADDLIB @var{archive} -@itemx ADDLIB @var{archive} (@var{module}, @var{module}, @dots{} @var{module}) -Add all the contents of @var{archive} (or, if specified, each named -@var{module} from @var{archive}) to the current archive. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@item ADDMOD @var{member}, @var{member}, @dots{} @var{member} -@c FIXME! w/Replacement?? If so, like "ar r @var{archive} @var{names}" -@c else like "ar q..." -Add each named @var{member} as a module in the current archive. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@item CLEAR -Discard the contents of the current archive, canceling the effect of -any operations since the last @code{SAVE}. May be executed (with no -effect) even if no current archive is specified. - -@item CREATE @var{archive} -Creates an archive, and makes it the current archive (required for many -other commands). The new archive is created with a temporary name; it -is not actually saved as @var{archive} until you use @code{SAVE}. -You can overwrite existing archives; similarly, the contents of any -existing file named @var{archive} will not be destroyed until @code{SAVE}. - -@item DELETE @var{module}, @var{module}, @dots{} @var{module} -Delete each listed @var{module} from the current archive; equivalent to -@samp{ar -d @var{archive} @var{module} @dots{} @var{module}}. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@item DIRECTORY @var{archive} (@var{module}, @dots{} @var{module}) -@itemx DIRECTORY @var{archive} (@var{module}, @dots{} @var{module}) @var{outputfile} -List each named @var{module} present in @var{archive}. The separate -command @code{VERBOSE} specifies the form of the output: when verbose -output is off, output is like that of @samp{ar -t @var{archive} -@var{module}@dots{}}. When verbose output is on, the listing is like -@samp{ar -tv @var{archive} @var{module}@dots{}}. - -Output normally goes to the standard output stream; however, if you -specify @var{outputfile} as a final argument, @command{ar} directs the -output to that file. - -@item END -Exit from @command{ar}, with a @code{0} exit code to indicate successful -completion. This command does not save the output file; if you have -changed the current archive since the last @code{SAVE} command, those -changes are lost. - -@item EXTRACT @var{module}, @var{module}, @dots{} @var{module} -Extract each named @var{module} from the current archive, writing them -into the current directory as separate files. Equivalent to @samp{ar -x -@var{archive} @var{module}@dots{}}. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@ignore -@c FIXME Tokens but no commands??? -@item FULLDIR - -@item HELP -@end ignore - -@item LIST -Display full contents of the current archive, in ``verbose'' style -regardless of the state of @code{VERBOSE}. The effect is like @samp{ar -tv @var{archive}}. (This single command is a @sc{gnu} @command{ar} -enhancement, rather than present for MRI compatibility.) - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@item OPEN @var{archive} -Opens an existing archive for use as the current archive (required for -many other commands). Any changes as the result of subsequent commands -will not actually affect @var{archive} until you next use @code{SAVE}. - -@item REPLACE @var{module}, @var{module}, @dots{} @var{module} -In the current archive, replace each existing @var{module} (named in -the @code{REPLACE} arguments) from files in the current working directory. -To execute this command without errors, both the file, and the module in -the current archive, must exist. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@item VERBOSE -Toggle an internal flag governing the output from @code{DIRECTORY}. -When the flag is on, @code{DIRECTORY} output matches output from -@samp{ar -tv }@dots{}. - -@item SAVE -Commit your changes to the current archive, and actually save it as a -file with the name specified in the last @code{CREATE} or @code{OPEN} -command. - -Requires prior use of @code{OPEN} or @code{CREATE}. - -@end table - -@iftex -@node ld -@chapter ld -@cindex linker -@kindex ld -The @sc{gnu} linker @command{ld} is now described in a separate manual. -@xref{Top,, Overview,, Using LD: the @sc{gnu} linker}. -@end iftex - -@node nm -@chapter nm -@cindex symbols -@kindex nm - -@c man title nm list symbols from object files - -@smallexample -@c man begin SYNOPSIS nm -nm [@option{-a}|@option{--debug-syms}] - [@option{-g}|@option{--extern-only}][@option{--plugin} @var{name}] - [@option{-B}] [@option{-C}|@option{--demangle}[=@var{style}]] [@option{-D}|@option{--dynamic}] - [@option{-S}|@option{--print-size}] [@option{-s}|@option{--print-armap}] - [@option{-A}|@option{-o}|@option{--print-file-name}][@option{--special-syms}] - [@option{-n}|@option{-v}|@option{--numeric-sort}] [@option{-p}|@option{--no-sort}] - [@option{-r}|@option{--reverse-sort}] [@option{--size-sort}] [@option{-u}|@option{--undefined-only}] - [@option{-t} @var{radix}|@option{--radix=}@var{radix}] [@option{-P}|@option{--portability}] - [@option{--target=}@var{bfdname}] [@option{-f}@var{format}|@option{--format=}@var{format}] - [@option{--defined-only}] [@option{-l}|@option{--line-numbers}] [@option{--no-demangle}] - [@option{-V}|@option{--version}] [@option{-X 32_64}] [@option{--help}] [@var{objfile}@dots{}] -@c man end -@end smallexample - -@c man begin DESCRIPTION nm -@sc{gnu} @command{nm} lists the symbols from object files @var{objfile}@dots{}. -If no object files are listed as arguments, @command{nm} assumes the file -@file{a.out}. - -For each symbol, @command{nm} shows: - -@itemize @bullet -@item -The symbol value, in the radix selected by options (see below), or -hexadecimal by default. - -@item -The symbol type. At least the following types are used; others are, as -well, depending on the object file format. If lowercase, the symbol is -usually local; if uppercase, the symbol is global (external). There -are however a few lowercase symbols that are shown for special global -symbols (@code{u}, @code{v} and @code{w}). - -@c Some more detail on exactly what these symbol types are used for -@c would be nice. -@table @code -@item A -The symbol's value is absolute, and will not be changed by further -linking. - -@item B -@itemx b -The symbol is in the uninitialized data section (known as BSS). - -@item C -The symbol is common. Common symbols are uninitialized data. When -linking, multiple common symbols may appear with the same name. If the -symbol is defined anywhere, the common symbols are treated as undefined -references. -@ifclear man -For more details on common symbols, see the discussion of ---warn-common in @ref{Options,,Linker options,ld.info,The GNU linker}. -@end ifclear - -@item D -@itemx d -The symbol is in the initialized data section. - -@item G -@itemx g -The symbol is in an initialized data section for small objects. Some -object file formats permit more efficient access to small data objects, -such as a global int variable as opposed to a large global array. - -@item i -For PE format files this indicates that the symbol is in a section -specific to the implementation of DLLs. For ELF format files this -indicates that the symbol is an indirect function. This is a GNU -extension to the standard set of ELF symbol types. It indicates a -symbol which if referenced by a relocation does not evaluate to its -address, but instead must be invoked at runtime. The runtime -execution will then return the value to be used in the relocation. - -@item N -The symbol is a debugging symbol. - -@item p -The symbols is in a stack unwind section. - -@item R -@itemx r -The symbol is in a read only data section. - -@item S -@itemx s -The symbol is in an uninitialized data section for small objects. - -@item T -@itemx t -The symbol is in the text (code) section. - -@item U -The symbol is undefined. - -@item u -The symbol is a unique global symbol. This is a GNU extension to the -standard set of ELF symbol bindings. For such a symbol the dynamic linker -will make sure that in the entire process there is just one symbol with -this name and type in use. - -@item V -@itemx v -The symbol is a weak object. When a weak defined symbol is linked with -a normal defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the weak symbol becomes zero with no error. On some -systems, uppercase indicates that a default value has been specified. - -@item W -@itemx w -The symbol is a weak symbol that has not been specifically tagged as a -weak object symbol. When a weak defined symbol is linked with a normal -defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the symbol is determined in a system-specific manner without -error. On some systems, uppercase indicates that a default value has been -specified. - -@item - -The symbol is a stabs symbol in an a.out object file. In this case, the -next values printed are the stabs other field, the stabs desc field, and -the stab type. Stabs symbols are used to hold debugging information. -@ifclear man -For more information, see @ref{Top,Stabs,Stabs Overview,stabs.info, The -``stabs'' debug format}. -@end ifclear - -@item ? -The symbol type is unknown, or object file format specific. -@end table - -@item -The symbol name. -@end itemize - -@c man end - -@c man begin OPTIONS nm -The long and short forms of options, shown here as alternatives, are -equivalent. - -@table @env -@item -A -@itemx -o -@itemx --print-file-name -@cindex input file name -@cindex file name -@cindex source file name -Precede each symbol by the name of the input file (or archive member) -in which it was found, rather than identifying the input file once only, -before all of its symbols. - -@item -a -@itemx --debug-syms -@cindex debugging symbols -Display all symbols, even debugger-only symbols; normally these are not -listed. - -@item -B -@cindex @command{nm} format -@cindex @command{nm} compatibility -The same as @option{--format=bsd} (for compatibility with the MIPS @command{nm}). - -@item -C -@itemx --demangle[=@var{style}] -@cindex demangling in nm -Decode (@dfn{demangle}) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes C++ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. @xref{c++filt}, -for more information on demangling. - -@item --no-demangle -Do not demangle low-level symbol names. This is the default. - -@item -D -@itemx --dynamic -@cindex dynamic symbols -Display the dynamic symbols rather than the normal symbols. This is -only meaningful for dynamic objects, such as certain types of shared -libraries. - -@item -f @var{format} -@itemx --format=@var{format} -@cindex @command{nm} format -@cindex @command{nm} compatibility -Use the output format @var{format}, which can be @code{bsd}, -@code{sysv}, or @code{posix}. The default is @code{bsd}. -Only the first character of @var{format} is significant; it can be -either upper or lower case. - -@item -g -@itemx --extern-only -@cindex external symbols -Display only external symbols. - -@item --plugin @var{name} -@cindex load plugin -Load the plugin called @var{name} to add support for extra target -types. This option is only available if the toolchain has been built -with plugin support enabled. - -@item -l -@itemx --line-numbers -@cindex symbol line numbers -For each symbol, use debugging information to try to find a filename and -line number. For a defined symbol, look for the line number of the -address of the symbol. For an undefined symbol, look for the line -number of a relocation entry which refers to the symbol. If line number -information can be found, print it after the other symbol information. - -@item -n -@itemx -v -@itemx --numeric-sort -Sort symbols numerically by their addresses, rather than alphabetically -by their names. - -@item -p -@itemx --no-sort -@cindex sorting symbols -Do not bother to sort the symbols in any order; print them in the order -encountered. - -@item -P -@itemx --portability -Use the POSIX.2 standard output format instead of the default format. -Equivalent to @samp{-f posix}. - -@item -S -@itemx --print-size -Print both value and size of defined symbols for the @code{bsd} output style. -This option has no effect for object formats that do not record symbol -sizes, unless @samp{--size-sort} is also used in which case a -calculated size is displayed. - -@item -s -@itemx --print-armap -@cindex symbol index, listing -When listing symbols from archive members, include the index: a mapping -(stored in the archive by @command{ar} or @command{ranlib}) of which modules -contain definitions for which names. - -@item -r -@itemx --reverse-sort -Reverse the order of the sort (whether numeric or alphabetic); let the -last come first. - -@item --size-sort -Sort symbols by size. The size is computed as the difference between -the value of the symbol and the value of the symbol with the next higher -value. If the @code{bsd} output format is used the size of the symbol -is printed, rather than the value, and @samp{-S} must be used in order -both size and value to be printed. - -@item --special-syms -Display symbols which have a target-specific special meaning. These -symbols are usually used by the target for some special processing and -are not normally helpful when included included in the normal symbol -lists. For example for ARM targets this option would skip the mapping -symbols used to mark transitions between ARM code, THUMB code and -data. - -@item -t @var{radix} -@itemx --radix=@var{radix} -Use @var{radix} as the radix for printing the symbol values. It must be -@samp{d} for decimal, @samp{o} for octal, or @samp{x} for hexadecimal. - -@item --target=@var{bfdname} -@cindex object code format -Specify an object code format other than your system's default format. -@xref{Target Selection}, for more information. - -@item -u -@itemx --undefined-only -@cindex external symbols -@cindex undefined symbols -Display only undefined symbols (those external to each object file). - -@item --defined-only -@cindex external symbols -@cindex undefined symbols -Display only defined symbols for each object file. - -@item -V -@itemx --version -Show the version number of @command{nm} and exit. - -@item -X -This option is ignored for compatibility with the AIX version of -@command{nm}. It takes one parameter which must be the string -@option{32_64}. The default mode of AIX @command{nm} corresponds -to @option{-X 32}, which is not supported by @sc{gnu} @command{nm}. - -@item --help -Show a summary of the options to @command{nm} and exit. -@end table - -@c man end - -@ignore -@c man begin SEEALSO nm -ar(1), objdump(1), ranlib(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node objcopy -@chapter objcopy - -@c man title objcopy copy and translate object files - -@smallexample -@c man begin SYNOPSIS objcopy -objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}] - [@option{-I} @var{bfdname}|@option{--input-target=}@var{bfdname}] - [@option{-O} @var{bfdname}|@option{--output-target=}@var{bfdname}] - [@option{-B} @var{bfdarch}|@option{--binary-architecture=}@var{bfdarch}] - [@option{-S}|@option{--strip-all}] - [@option{-g}|@option{--strip-debug}] - [@option{-K} @var{symbolname}|@option{--keep-symbol=}@var{symbolname}] - [@option{-N} @var{symbolname}|@option{--strip-symbol=}@var{symbolname}] - [@option{--strip-unneeded-symbol=}@var{symbolname}] - [@option{-G} @var{symbolname}|@option{--keep-global-symbol=}@var{symbolname}] - [@option{--localize-hidden}] - [@option{-L} @var{symbolname}|@option{--localize-symbol=}@var{symbolname}] - [@option{--globalize-symbol=}@var{symbolname}] - [@option{-W} @var{symbolname}|@option{--weaken-symbol=}@var{symbolname}] - [@option{-w}|@option{--wildcard}] - [@option{-x}|@option{--discard-all}] - [@option{-X}|@option{--discard-locals}] - [@option{-b} @var{byte}|@option{--byte=}@var{byte}] - [@option{-i} [@var{breadth}]|@option{--interleave}[=@var{breadth}]] - [@option{--interleave-width=}@var{width}] - [@option{-j} @var{sectionname}|@option{--only-section=}@var{sectionname}] - [@option{-R} @var{sectionname}|@option{--remove-section=}@var{sectionname}] - [@option{-p}|@option{--preserve-dates}] - [@option{--debugging}] - [@option{--gap-fill=}@var{val}] - [@option{--pad-to=}@var{address}] - [@option{--set-start=}@var{val}] - [@option{--adjust-start=}@var{incr}] - [@option{--change-addresses=}@var{incr}] - [@option{--change-section-address} @var{section}@{=,+,-@}@var{val}] - [@option{--change-section-lma} @var{section}@{=,+,-@}@var{val}] - [@option{--change-section-vma} @var{section}@{=,+,-@}@var{val}] - [@option{--change-warnings}] [@option{--no-change-warnings}] - [@option{--set-section-flags} @var{section}=@var{flags}] - [@option{--add-section} @var{sectionname}=@var{filename}] - [@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]] - [@option{--long-section-names} @{enable,disable,keep@}] - [@option{--change-leading-char}] [@option{--remove-leading-char}] - [@option{--reverse-bytes=}@var{num}] - [@option{--srec-len=}@var{ival}] [@option{--srec-forceS3}] - [@option{--redefine-sym} @var{old}=@var{new}] - [@option{--redefine-syms=}@var{filename}] - [@option{--weaken}] - [@option{--keep-symbols=}@var{filename}] - [@option{--strip-symbols=}@var{filename}] - [@option{--strip-unneeded-symbols=}@var{filename}] - [@option{--keep-global-symbols=}@var{filename}] - [@option{--localize-symbols=}@var{filename}] - [@option{--globalize-symbols=}@var{filename}] - [@option{--weaken-symbols=}@var{filename}] - [@option{--alt-machine-code=}@var{index}] - [@option{--prefix-symbols=}@var{string}] - [@option{--prefix-sections=}@var{string}] - [@option{--prefix-alloc-sections=}@var{string}] - [@option{--add-gnu-debuglink=}@var{path-to-file}] - [@option{--keep-file-symbols}] - [@option{--only-keep-debug}] - [@option{--extract-symbol}] - [@option{--writable-text}] - [@option{--readonly-text}] - [@option{--pure}] - [@option{--impure}] - [@option{--file-alignment=}@var{num}] - [@option{--heap=}@var{size}] - [@option{--image-base=}@var{address}] - [@option{--section-alignment=}@var{num}] - [@option{--stack=}@var{size}] - [@option{--subsystem=}@var{which}:@var{major}.@var{minor}] - [@option{--compress-debug-sections}] - [@option{--decompress-debug-sections}] - [@option{--dwarf-depth=@var{n}}] - [@option{--dwarf-start=@var{n}}] - [@option{-v}|@option{--verbose}] - [@option{-V}|@option{--version}] - [@option{--help}] [@option{--info}] - @var{infile} [@var{outfile}] -@c man end -@end smallexample - -@c man begin DESCRIPTION objcopy -The @sc{gnu} @command{objcopy} utility copies the contents of an object -file to another. @command{objcopy} uses the @sc{gnu} @sc{bfd} Library to -read and write the object files. It can write the destination object -file in a format different from that of the source object file. The -exact behavior of @command{objcopy} is controlled by command-line options. -Note that @command{objcopy} should be able to copy a fully linked file -between any two formats. However, copying a relocatable object file -between any two formats may not work as expected. - -@command{objcopy} creates temporary files to do its translations and -deletes them afterward. @command{objcopy} uses @sc{bfd} to do all its -translation work; it has access to all the formats described in @sc{bfd} -and thus is able to recognize most formats without being told -explicitly. @xref{BFD,,BFD,ld.info,Using LD}. - -@command{objcopy} can be used to generate S-records by using an output -target of @samp{srec} (e.g., use @samp{-O srec}). - -@command{objcopy} can be used to generate a raw binary file by using an -output target of @samp{binary} (e.g., use @option{-O binary}). When -@command{objcopy} generates a raw binary file, it will essentially produce -a memory dump of the contents of the input object file. All symbols and -relocation information will be discarded. The memory dump will start at -the load address of the lowest section copied into the output file. - -When generating an S-record or a raw binary file, it may be helpful to -use @option{-S} to remove sections containing debugging information. In -some cases @option{-R} will be useful to remove sections which contain -information that is not needed by the binary file. - -Note---@command{objcopy} is not able to change the endianness of its input -files. If the input format has an endianness (some formats do not), -@command{objcopy} can only copy the inputs into file formats that have the -same endianness or which have no endianness (e.g., @samp{srec}). -(However, see the @option{--reverse-bytes} option.) - -@c man end - -@c man begin OPTIONS objcopy - -@table @env -@item @var{infile} -@itemx @var{outfile} -The input and output files, respectively. -If you do not specify @var{outfile}, @command{objcopy} creates a -temporary file and destructively renames the result with -the name of @var{infile}. - -@item -I @var{bfdname} -@itemx --input-target=@var{bfdname} -Consider the source file's object format to be @var{bfdname}, rather than -attempting to deduce it. @xref{Target Selection}, for more information. - -@item -O @var{bfdname} -@itemx --output-target=@var{bfdname} -Write the output file using the object format @var{bfdname}. -@xref{Target Selection}, for more information. - -@item -F @var{bfdname} -@itemx --target=@var{bfdname} -Use @var{bfdname} as the object format for both the input and the output -file; i.e., simply transfer data from source to destination with no -translation. @xref{Target Selection}, for more information. - -@item -B @var{bfdarch} -@itemx --binary-architecture=@var{bfdarch} -Useful when transforming a architecture-less input file into an object file. -In this case the output architecture can be set to @var{bfdarch}. This -option will be ignored if the input file has a known @var{bfdarch}. You -can access this binary data inside a program by referencing the special -symbols that are created by the conversion process. These symbols are -called _binary_@var{objfile}_start, _binary_@var{objfile}_end and -_binary_@var{objfile}_size. e.g. you can transform a picture file into -an object file and then access it in your code using these symbols. - -@item -j @var{sectionname} -@itemx --only-section=@var{sectionname} -Copy only the named section from the input file to the output file. -This option may be given more than once. Note that using this option -inappropriately may make the output file unusable. - -@item -R @var{sectionname} -@itemx --remove-section=@var{sectionname} -Remove any section named @var{sectionname} from the output file. This -option may be given more than once. Note that using this option -inappropriately may make the output file unusable. - -@item -S -@itemx --strip-all -Do not copy relocation and symbol information from the source file. - -@item -g -@itemx --strip-debug -Do not copy debugging symbols or sections from the source file. - -@item --strip-unneeded -Strip all symbols that are not needed for relocation processing. - -@item -K @var{symbolname} -@itemx --keep-symbol=@var{symbolname} -When stripping symbols, keep symbol @var{symbolname} even if it would -normally be stripped. This option may be given more than once. - -@item -N @var{symbolname} -@itemx --strip-symbol=@var{symbolname} -Do not copy symbol @var{symbolname} from the source file. This option -may be given more than once. - -@item --strip-unneeded-symbol=@var{symbolname} -Do not copy symbol @var{symbolname} from the source file unless it is needed -by a relocation. This option may be given more than once. - -@item -G @var{symbolname} -@itemx --keep-global-symbol=@var{symbolname} -Keep only symbol @var{symbolname} global. Make all other symbols local -to the file, so that they are not visible externally. This option may -be given more than once. - -@item --localize-hidden -In an ELF object, mark all symbols that have hidden or internal visibility -as local. This option applies on top of symbol-specific localization options -such as @option{-L}. - -@item -L @var{symbolname} -@itemx --localize-symbol=@var{symbolname} -Make symbol @var{symbolname} local to the file, so that it is not -visible externally. This option may be given more than once. - -@item -W @var{symbolname} -@itemx --weaken-symbol=@var{symbolname} -Make symbol @var{symbolname} weak. This option may be given more than once. - -@item --globalize-symbol=@var{symbolname} -Give symbol @var{symbolname} global scoping so that it is visible -outside of the file in which it is defined. This option may be given -more than once. - -@item -w -@itemx --wildcard -Permit regular expressions in @var{symbolname}s used in other command -line options. The question mark (?), asterisk (*), backslash (\) and -square brackets ([]) operators can be used anywhere in the symbol -name. If the first character of the symbol name is the exclamation -point (!) then the sense of the switch is reversed for that symbol. -For example: - -@smallexample - -w -W !foo -W fo* -@end smallexample - -would cause objcopy to weaken all symbols that start with ``fo'' -except for the symbol ``foo''. - -@item -x -@itemx --discard-all -Do not copy non-global symbols from the source file. -@c FIXME any reason to prefer "non-global" to "local" here? - -@item -X -@itemx --discard-locals -Do not copy compiler-generated local symbols. -(These usually start with @samp{L} or @samp{.}.) - -@item -b @var{byte} -@itemx --byte=@var{byte} -If interleaving has been enabled via the @option{--interleave} option -then start the range of bytes to keep at the @var{byte}th byte. -@var{byte} can be in the range from 0 to @var{breadth}-1, where -@var{breadth} is the value given by the @option{--interleave} option. - -@item -i [@var{breadth}] -@itemx --interleave[=@var{breadth}] -Only copy a range out of every @var{breadth} bytes. (Header data is -not affected). Select which byte in the range begins the copy with -the @option{--byte} option. Select the width of the range with the -@option{--interleave-width} option. - -This option is useful for creating files to program @sc{rom}. It is -typically used with an @code{srec} output target. Note that -@command{objcopy} will complain if you do not specify the -@option{--byte} option as well. - -The default interleave breadth is 4, so with @option{--byte} set to 0, -@command{objcopy} would copy the first byte out of every four bytes -from the input to the output. - -@item --interleave-width=@var{width} -When used with the @option{--interleave} option, copy @var{width} -bytes at a time. The start of the range of bytes to be copied is set -by the @option{--byte} option, and the extent of the range is set with -the @option{--interleave} option. - -The default value for this option is 1. The value of @var{width} plus -the @var{byte} value set by the @option{--byte} option must not exceed -the interleave breadth set by the @option{--interleave} option. - -This option can be used to create images for two 16-bit flashes interleaved -in a 32-bit bus by passing @option{-b 0 -i 4 --interleave-width=2} -and @option{-b 2 -i 4 --interleave-width=2} to two @command{objcopy} -commands. If the input was '12345678' then the outputs would be -'1256' and '3478' respectively. - -@item -p -@itemx --preserve-dates -Set the access and modification dates of the output file to be the same -as those of the input file. - -@item --debugging -Convert debugging information, if possible. This is not the default -because only certain debugging formats are supported, and the -conversion process can be time consuming. - -@item --gap-fill @var{val} -Fill gaps between sections with @var{val}. This operation applies to -the @emph{load address} (LMA) of the sections. It is done by increasing -the size of the section with the lower address, and filling in the extra -space created with @var{val}. - -@item --pad-to @var{address} -Pad the output file up to the load address @var{address}. This is -done by increasing the size of the last section. The extra space is -filled in with the value specified by @option{--gap-fill} (default zero). - -@item --set-start @var{val} -Set the start address of the new file to @var{val}. Not all object file -formats support setting the start address. - -@item --change-start @var{incr} -@itemx --adjust-start @var{incr} -@cindex changing start address -Change the start address by adding @var{incr}. Not all object file -formats support setting the start address. - -@item --change-addresses @var{incr} -@itemx --adjust-vma @var{incr} -@cindex changing object addresses -Change the VMA and LMA addresses of all sections, as well as the start -address, by adding @var{incr}. Some object file formats do not permit -section addresses to be changed arbitrarily. Note that this does not -relocate the sections; if the program expects sections to be loaded at a -certain address, and this option is used to change the sections such -that they are loaded at a different address, the program may fail. - -@item --change-section-address @var{section}@{=,+,-@}@var{val} -@itemx --adjust-section-vma @var{section}@{=,+,-@}@var{val} -@cindex changing section address -Set or change both the VMA address and the LMA address of the named -@var{section}. If @samp{=} is used, the section address is set to -@var{val}. Otherwise, @var{val} is added to or subtracted from the -section address. See the comments under @option{--change-addresses}, -above. If @var{section} does not exist in the input file, a warning will -be issued, unless @option{--no-change-warnings} is used. - -@item --change-section-lma @var{section}@{=,+,-@}@var{val} -@cindex changing section LMA -Set or change the LMA address of the named @var{section}. The LMA -address is the address where the section will be loaded into memory at -program load time. Normally this is the same as the VMA address, which -is the address of the section at program run time, but on some systems, -especially those where a program is held in ROM, the two can be -different. If @samp{=} is used, the section address is set to -@var{val}. Otherwise, @var{val} is added to or subtracted from the -section address. See the comments under @option{--change-addresses}, -above. If @var{section} does not exist in the input file, a warning -will be issued, unless @option{--no-change-warnings} is used. - -@item --change-section-vma @var{section}@{=,+,-@}@var{val} -@cindex changing section VMA -Set or change the VMA address of the named @var{section}. The VMA -address is the address where the section will be located once the -program has started executing. Normally this is the same as the LMA -address, which is the address where the section will be loaded into -memory, but on some systems, especially those where a program is held in -ROM, the two can be different. If @samp{=} is used, the section address -is set to @var{val}. Otherwise, @var{val} is added to or subtracted -from the section address. See the comments under -@option{--change-addresses}, above. If @var{section} does not exist in -the input file, a warning will be issued, unless -@option{--no-change-warnings} is used. - -@item --change-warnings -@itemx --adjust-warnings -If @option{--change-section-address} or @option{--change-section-lma} or -@option{--change-section-vma} is used, and the named section does not -exist, issue a warning. This is the default. - -@item --no-change-warnings -@itemx --no-adjust-warnings -Do not issue a warning if @option{--change-section-address} or -@option{--adjust-section-lma} or @option{--adjust-section-vma} is used, even -if the named section does not exist. - -@item --set-section-flags @var{section}=@var{flags} -Set the flags for the named section. The @var{flags} argument is a -comma separated string of flag names. The recognized names are -@samp{alloc}, @samp{contents}, @samp{load}, @samp{noload}, -@samp{readonly}, @samp{code}, @samp{data}, @samp{rom}, @samp{share}, and -@samp{debug}. You can set the @samp{contents} flag for a section which -does not have contents, but it is not meaningful to clear the -@samp{contents} flag of a section which does have contents--just remove -the section instead. Not all flags are meaningful for all object file -formats. - -@item --add-section @var{sectionname}=@var{filename} -Add a new section named @var{sectionname} while copying the file. The -contents of the new section are taken from the file @var{filename}. The -size of the section will be the size of the file. This option only -works on file formats which can support sections with arbitrary names. - -@item --rename-section @var{oldname}=@var{newname}[,@var{flags}] -Rename a section from @var{oldname} to @var{newname}, optionally -changing the section's flags to @var{flags} in the process. This has -the advantage over usng a linker script to perform the rename in that -the output stays as an object file and does not become a linked -executable. - -This option is particularly helpful when the input format is binary, -since this will always create a section called .data. If for example, -you wanted instead to create a section called .rodata containing binary -data you could use the following command line to achieve it: - -@smallexample - objcopy -I binary -O -B \ - --rename-section .data=.rodata,alloc,load,readonly,data,contents \ - -@end smallexample - -@item --long-section-names @{enable,disable,keep@} -Controls the handling of long section names when processing @code{COFF} -and @code{PE-COFF} object formats. The default behaviour, @samp{keep}, -is to preserve long section names if any are present in the input file. -The @samp{enable} and @samp{disable} options forcibly enable or disable -the use of long section names in the output object; when @samp{disable} -is in effect, any long section names in the input object will be truncated. -The @samp{enable} option will only emit long section names if any are -present in the inputs; this is mostly the same as @samp{keep}, but it -is left undefined whether the @samp{enable} option might force the -creation of an empty string table in the output file. - -@item --change-leading-char -Some object file formats use special characters at the start of -symbols. The most common such character is underscore, which compilers -often add before every symbol. This option tells @command{objcopy} to -change the leading character of every symbol when it converts between -object file formats. If the object file formats use the same leading -character, this option has no effect. Otherwise, it will add a -character, or remove a character, or change a character, as -appropriate. - -@item --remove-leading-char -If the first character of a global symbol is a special symbol leading -character used by the object file format, remove the character. The -most common symbol leading character is underscore. This option will -remove a leading underscore from all global symbols. This can be useful -if you want to link together objects of different file formats with -different conventions for symbol names. This is different from -@option{--change-leading-char} because it always changes the symbol name -when appropriate, regardless of the object file format of the output -file. - -@item --reverse-bytes=@var{num} -Reverse the bytes in a section with output contents. A section length must -be evenly divisible by the value given in order for the swap to be able to -take place. Reversing takes place before the interleaving is performed. - -This option is used typically in generating ROM images for problematic -target systems. For example, on some target boards, the 32-bit words -fetched from 8-bit ROMs are re-assembled in little-endian byte order -regardless of the CPU byte order. Depending on the programming model, the -endianness of the ROM may need to be modified. - -Consider a simple file with a section containing the following eight -bytes: @code{12345678}. - -Using @samp{--reverse-bytes=2} for the above example, the bytes in the -output file would be ordered @code{21436587}. - -Using @samp{--reverse-bytes=4} for the above example, the bytes in the -output file would be ordered @code{43218765}. - -By using @samp{--reverse-bytes=2} for the above example, followed by -@samp{--reverse-bytes=4} on the output file, the bytes in the second -output file would be ordered @code{34127856}. - -@item --srec-len=@var{ival} -Meaningful only for srec output. Set the maximum length of the Srecords -being produced to @var{ival}. This length covers both address, data and -crc fields. - -@item --srec-forceS3 -Meaningful only for srec output. Avoid generation of S1/S2 records, -creating S3-only record format. - -@item --redefine-sym @var{old}=@var{new} -Change the name of a symbol @var{old}, to @var{new}. This can be useful -when one is trying link two things together for which you have no -source, and there are name collisions. - -@item --redefine-syms=@var{filename} -Apply @option{--redefine-sym} to each symbol pair "@var{old} @var{new}" -listed in the file @var{filename}. @var{filename} is simply a flat file, -with one symbol pair per line. Line comments may be introduced by the hash -character. This option may be given more than once. - -@item --weaken -Change all global symbols in the file to be weak. This can be useful -when building an object which will be linked against other objects using -the @option{-R} option to the linker. This option is only effective when -using an object file format which supports weak symbols. - -@item --keep-symbols=@var{filename} -Apply @option{--keep-symbol} option to each symbol listed in the file -@var{filename}. @var{filename} is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. - -@item --strip-symbols=@var{filename} -Apply @option{--strip-symbol} option to each symbol listed in the file -@var{filename}. @var{filename} is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. - -@item --strip-unneeded-symbols=@var{filename} -Apply @option{--strip-unneeded-symbol} option to each symbol listed in -the file @var{filename}. @var{filename} is simply a flat file, with one -symbol name per line. Line comments may be introduced by the hash -character. This option may be given more than once. - -@item --keep-global-symbols=@var{filename} -Apply @option{--keep-global-symbol} option to each symbol listed in the -file @var{filename}. @var{filename} is simply a flat file, with one -symbol name per line. Line comments may be introduced by the hash -character. This option may be given more than once. - -@item --localize-symbols=@var{filename} -Apply @option{--localize-symbol} option to each symbol listed in the file -@var{filename}. @var{filename} is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. - -@item --globalize-symbols=@var{filename} -Apply @option{--globalize-symbol} option to each symbol listed in the file -@var{filename}. @var{filename} is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. - -@item --weaken-symbols=@var{filename} -Apply @option{--weaken-symbol} option to each symbol listed in the file -@var{filename}. @var{filename} is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. - -@item --alt-machine-code=@var{index} -If the output architecture has alternate machine codes, use the -@var{index}th code instead of the default one. This is useful in case -a machine is assigned an official code and the tool-chain adopts the -new code, but other applications still depend on the original code -being used. For ELF based architectures if the @var{index} -alternative does not exist then the value is treated as an absolute -number to be stored in the e_machine field of the ELF header. - -@item --writable-text -Mark the output text as writable. This option isn't meaningful for all -object file formats. - -@item --readonly-text -Make the output text write protected. This option isn't meaningful for all -object file formats. - -@item --pure -Mark the output file as demand paged. This option isn't meaningful for all -object file formats. - -@item --impure -Mark the output file as impure. This option isn't meaningful for all -object file formats. - -@item --prefix-symbols=@var{string} -Prefix all symbols in the output file with @var{string}. - -@item --prefix-sections=@var{string} -Prefix all section names in the output file with @var{string}. - -@item --prefix-alloc-sections=@var{string} -Prefix all the names of all allocated sections in the output file with -@var{string}. - -@item --add-gnu-debuglink=@var{path-to-file} -Creates a .gnu_debuglink section which contains a reference to @var{path-to-file} -and adds it to the output file. - -@item --keep-file-symbols -When stripping a file, perhaps with @option{--strip-debug} or -@option{--strip-unneeded}, retain any symbols specifying source file names, -which would otherwise get stripped. - -@item --only-keep-debug -Strip a file, removing contents of any sections that would not be -stripped by @option{--strip-debug} and leaving the debugging sections -intact. In ELF files, this preserves all note sections in the output. - -The intention is that this option will be used in conjunction with -@option{--add-gnu-debuglink} to create a two part executable. One a -stripped binary which will occupy less space in RAM and in a -distribution and the second a debugging information file which is only -needed if debugging abilities are required. The suggested procedure -to create these files is as follows: - -@enumerate -@item Link the executable as normal. Assuming that is is called -@code{foo} then... -@item Run @code{objcopy --only-keep-debug foo foo.dbg} to -create a file containing the debugging info. -@item Run @code{objcopy --strip-debug foo} to create a -stripped executable. -@item Run @code{objcopy --add-gnu-debuglink=foo.dbg foo} -to add a link to the debugging info into the stripped executable. -@end enumerate - -Note---the choice of @code{.dbg} as an extension for the debug info -file is arbitrary. Also the @code{--only-keep-debug} step is -optional. You could instead do this: - -@enumerate -@item Link the executable as normal. -@item Copy @code{foo} to @code{foo.full} -@item Run @code{objcopy --strip-debug foo} -@item Run @code{objcopy --add-gnu-debuglink=foo.full foo} -@end enumerate - -i.e., the file pointed to by the @option{--add-gnu-debuglink} can be the -full executable. It does not have to be a file created by the -@option{--only-keep-debug} switch. - -Note---this switch is only intended for use on fully linked files. It -does not make sense to use it on object files where the debugging -information may be incomplete. Besides the gnu_debuglink feature -currently only supports the presence of one filename containing -debugging information, not multiple filenames on a one-per-object-file -basis. - -@item --file-alignment @var{num} -Specify the file alignment. Sections in the file will always begin at -file offsets which are multiples of this number. This defaults to -512. -[This option is specific to PE targets.] - -@item --heap @var{reserve} -@itemx --heap @var{reserve},@var{commit} -Specify the number of bytes of memory to reserve (and optionally commit) -to be used as heap for this program. -[This option is specific to PE targets.] - -@item --image-base @var{value} -Use @var{value} as the base address of your program or dll. This is -the lowest memory location that will be used when your program or dll -is loaded. To reduce the need to relocate and improve performance of -your dlls, each should have a unique base address and not overlap any -other dlls. The default is 0x400000 for executables, and 0x10000000 -for dlls. -[This option is specific to PE targets.] - -@item --section-alignment @var{num} -Sets the section alignment. Sections in memory will always begin at -addresses which are a multiple of this number. Defaults to 0x1000. -[This option is specific to PE targets.] - -@item --stack @var{reserve} -@itemx --stack @var{reserve},@var{commit} -Specify the number of bytes of memory to reserve (and optionally commit) -to be used as stack for this program. -[This option is specific to PE targets.] - -@item --subsystem @var{which} -@itemx --subsystem @var{which}:@var{major} -@itemx --subsystem @var{which}:@var{major}.@var{minor} -Specifies the subsystem under which your program will execute. The -legal values for @var{which} are @code{native}, @code{windows}, -@code{console}, @code{posix}, @code{efi-app}, @code{efi-bsd}, -@code{efi-rtd}, @code{sal-rtd}, and @code{xbox}. You may optionally set -the subsystem version also. Numeric values are also accepted for -@var{which}. -[This option is specific to PE targets.] - -@item --extract-symbol -Keep the file's section flags and symbols but remove all section data. -Specifically, the option: - -@itemize -@item removes the contents of all sections; -@item sets the size of every section to zero; and -@item sets the file's start address to zero. -@end itemize - -This option is used to build a @file{.sym} file for a VxWorks kernel. -It can also be a useful way of reducing the size of a @option{--just-symbols} -linker input file. - -@item --compress-debug-sections -Compress DWARF debug sections using zlib. - -@item --decompress-debug-sections -Decompress DWARF debug sections using zlib. - -@item -V -@itemx --version -Show the version number of @command{objcopy}. - -@item -v -@itemx --verbose -Verbose output: list all object files modified. In the case of -archives, @samp{objcopy -V} lists all members of the archive. - -@item --help -Show a summary of the options to @command{objcopy}. - -@item --info -Display a list showing all architectures and object formats available. -@end table - -@c man end - -@ignore -@c man begin SEEALSO objcopy -ld(1), objdump(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node objdump -@chapter objdump - -@cindex object file information -@kindex objdump - -@c man title objdump display information from object files. - -@smallexample -@c man begin SYNOPSIS objdump -objdump [@option{-a}|@option{--archive-headers}] - [@option{-b} @var{bfdname}|@option{--target=@var{bfdname}}] - [@option{-C}|@option{--demangle}[=@var{style}] ] - [@option{-d}|@option{--disassemble}] - [@option{-D}|@option{--disassemble-all}] - [@option{-z}|@option{--disassemble-zeroes}] - [@option{-EB}|@option{-EL}|@option{--endian=}@{big | little @}] - [@option{-f}|@option{--file-headers}] - [@option{-F}|@option{--file-offsets}] - [@option{--file-start-context}] - [@option{-g}|@option{--debugging}] - [@option{-e}|@option{--debugging-tags}] - [@option{-h}|@option{--section-headers}|@option{--headers}] - [@option{-i}|@option{--info}] - [@option{-j} @var{section}|@option{--section=}@var{section}] - [@option{-l}|@option{--line-numbers}] - [@option{-S}|@option{--source}] - [@option{-m} @var{machine}|@option{--architecture=}@var{machine}] - [@option{-M} @var{options}|@option{--disassembler-options=}@var{options}] - [@option{-p}|@option{--private-headers}] - [@option{-P} @var{options}|@option{--private=}@var{options}] - [@option{-r}|@option{--reloc}] - [@option{-R}|@option{--dynamic-reloc}] - [@option{-s}|@option{--full-contents}] - [@option{-W[lLiaprmfFsoRt]}| - @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] - [@option{-G}|@option{--stabs}] - [@option{-t}|@option{--syms}] - [@option{-T}|@option{--dynamic-syms}] - [@option{-x}|@option{--all-headers}] - [@option{-w}|@option{--wide}] - [@option{--start-address=}@var{address}] - [@option{--stop-address=}@var{address}] - [@option{--prefix-addresses}] - [@option{--[no-]show-raw-insn}] - [@option{--adjust-vma=}@var{offset}] - [@option{--special-syms}] - [@option{--prefix=}@var{prefix}] - [@option{--prefix-strip=}@var{level}] - [@option{--insn-width=}@var{width}] - [@option{-V}|@option{--version}] - [@option{-H}|@option{--help}] - @var{objfile}@dots{} -@c man end -@end smallexample - -@c man begin DESCRIPTION objdump - -@command{objdump} displays information about one or more object files. -The options control what particular information to display. This -information is mostly useful to programmers who are working on the -compilation tools, as opposed to programmers who just want their -program to compile and work. - -@var{objfile}@dots{} are the object files to be examined. When you -specify archives, @command{objdump} shows information on each of the member -object files. - -@c man end - -@c man begin OPTIONS objdump - -The long and short forms of options, shown here as alternatives, are -equivalent. At least one option from the list -@option{-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-P,-r,-R,-s,-S,-t,-T,-V,-x} must be given. - -@table @env -@item -a -@itemx --archive-header -@cindex archive headers -If any of the @var{objfile} files are archives, display the archive -header information (in a format similar to @samp{ls -l}). Besides the -information you could list with @samp{ar tv}, @samp{objdump -a} shows -the object file format of each archive member. - -@item --adjust-vma=@var{offset} -@cindex section addresses in objdump -@cindex VMA in objdump -When dumping information, first add @var{offset} to all the section -addresses. This is useful if the section addresses do not correspond to -the symbol table, which can happen when putting sections at particular -addresses when using a format which can not represent section addresses, -such as a.out. - -@item -b @var{bfdname} -@itemx --target=@var{bfdname} -@cindex object code format -Specify that the object-code format for the object files is -@var{bfdname}. This option may not be necessary; @var{objdump} can -automatically recognize many formats. - -For example, -@example -objdump -b oasys -m vax -h fu.o -@end example -@noindent -displays summary information from the section headers (@option{-h}) of -@file{fu.o}, which is explicitly identified (@option{-m}) as a VAX object -file in the format produced by Oasys compilers. You can list the -formats available with the @option{-i} option. -@xref{Target Selection}, for more information. - -@item -C -@itemx --demangle[=@var{style}] -@cindex demangling in objdump -Decode (@dfn{demangle}) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes C++ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. @xref{c++filt}, -for more information on demangling. - -@item -g -@itemx --debugging -Display debugging information. This attempts to parse STABS and IEEE -debugging format information stored in the file and print it out using -a C like syntax. If neither of these formats are found this option -falls back on the @option{-W} option to print any DWARF information in -the file. - -@item -e -@itemx --debugging-tags -Like @option{-g}, but the information is generated in a format compatible -with ctags tool. - -@item -d -@itemx --disassemble -@cindex disassembling object code -@cindex machine instructions -Display the assembler mnemonics for the machine instructions from -@var{objfile}. This option only disassembles those sections which are -expected to contain instructions. - -@item -D -@itemx --disassemble-all -Like @option{-d}, but disassemble the contents of all sections, not just -those expected to contain instructions. - -If the target is an ARM architecture this switch also has the effect -of forcing the disassembler to decode pieces of data found in code -sections as if they were instructions. - -@item --prefix-addresses -When disassembling, print the complete address on each line. This is -the older disassembly format. - -@item -EB -@itemx -EL -@itemx --endian=@{big|little@} -@cindex endianness -@cindex disassembly endianness -Specify the endianness of the object files. This only affects -disassembly. This can be useful when disassembling a file format which -does not describe endianness information, such as S-records. - -@item -f -@itemx --file-headers -@cindex object file header -Display summary information from the overall header of -each of the @var{objfile} files. - -@item -F -@itemx --file-offsets -@cindex object file offsets -When disassembling sections, whenever a symbol is displayed, also -display the file offset of the region of data that is about to be -dumped. If zeroes are being skipped, then when disassembly resumes, -tell the user how many zeroes were skipped and the file offset of the -location from where the disassembly resumes. When dumping sections, -display the file offset of the location from where the dump starts. - -@item --file-start-context -@cindex source code context -Specify that when displaying interlisted source code/disassembly -(assumes @option{-S}) from a file that has not yet been displayed, extend the -context to the start of the file. - -@item -h -@itemx --section-headers -@itemx --headers -@cindex section headers -Display summary information from the section headers of the -object file. - -File segments may be relocated to nonstandard addresses, for example by -using the @option{-Ttext}, @option{-Tdata}, or @option{-Tbss} options to -@command{ld}. However, some object file formats, such as a.out, do not -store the starting address of the file segments. In those situations, -although @command{ld} relocates the sections correctly, using @samp{objdump --h} to list the file section headers cannot show the correct addresses. -Instead, it shows the usual addresses, which are implicit for the -target. - -@item -H -@itemx --help -Print a summary of the options to @command{objdump} and exit. - -@item -i -@itemx --info -@cindex architectures available -@cindex object formats available -Display a list showing all architectures and object formats available -for specification with @option{-b} or @option{-m}. - -@item -j @var{name} -@itemx --section=@var{name} -@cindex section information -Display information only for section @var{name}. - -@item -l -@itemx --line-numbers -@cindex source filenames for object files -Label the display (using debugging information) with the filename and -source line numbers corresponding to the object code or relocs shown. -Only useful with @option{-d}, @option{-D}, or @option{-r}. - -@item -m @var{machine} -@itemx --architecture=@var{machine} -@cindex architecture -@cindex disassembly architecture -Specify the architecture to use when disassembling object files. This -can be useful when disassembling object files which do not describe -architecture information, such as S-records. You can list the available -architectures with the @option{-i} option. - -If the target is an ARM architecture then this switch has an -additional effect. It restricts the disassembly to only those -instructions supported by the architecture specified by @var{machine}. -If it is necessary to use this switch because the input file does not -contain any architecture information, but it is also desired to -disassemble all the instructions use @option{-marm}. - -@item -M @var{options} -@itemx --disassembler-options=@var{options} -Pass target specific information to the disassembler. Only supported on -some targets. If it is necessary to specify more than one -disassembler option then multiple @option{-M} options can be used or -can be placed together into a comma separated list. - -If the target is an ARM architecture then this switch can be used to -select which register name set is used during disassembler. Specifying -@option{-M reg-names-std} (the default) will select the register names as -used in ARM's instruction set documentation, but with register 13 called -'sp', register 14 called 'lr' and register 15 called 'pc'. Specifying -@option{-M reg-names-apcs} will select the name set used by the ARM -Procedure Call Standard, whilst specifying @option{-M reg-names-raw} will -just use @samp{r} followed by the register number. - -There are also two variants on the APCS register naming scheme enabled -by @option{-M reg-names-atpcs} and @option{-M reg-names-special-atpcs} which -use the ARM/Thumb Procedure Call Standard naming conventions. (Either -with the normal register names or the special register names). - -This option can also be used for ARM architectures to force the -disassembler to interpret all instructions as Thumb instructions by -using the switch @option{--disassembler-options=force-thumb}. This can be -useful when attempting to disassemble thumb code produced by other -compilers. - -For the x86, some of the options duplicate functions of the @option{-m} -switch, but allow finer grained control. Multiple selections from the -following may be specified as a comma separated string. -@option{x86-64}, @option{i386} and @option{i8086} select disassembly for -the given architecture. @option{intel} and @option{att} select between -intel syntax mode and AT&T syntax mode. -@option{intel-mnemonic} and @option{att-mnemonic} select between -intel mnemonic mode and AT&T mnemonic mode. @option{intel-mnemonic} -implies @option{intel} and @option{att-mnemonic} implies @option{att}. -@option{addr64}, @option{addr32}, -@option{addr16}, @option{data32} and @option{data16} specify the default -address size and operand size. These four options will be overridden if -@option{x86-64}, @option{i386} or @option{i8086} appear later in the -option string. Lastly, @option{suffix}, when in AT&T mode, -instructs the disassembler to print a mnemonic suffix even when the -suffix could be inferred by the operands. - -For PowerPC, @option{booke} controls the disassembly of BookE -instructions. @option{32} and @option{64} select PowerPC and -PowerPC64 disassembly, respectively. @option{e300} selects -disassembly for the e300 family. @option{440} selects disassembly for -the PowerPC 440. @option{ppcps} selects disassembly for the paired -single instructions of the PPC750CL. - -For MIPS, this option controls the printing of instruction mnemonic -names and register names in disassembled instructions. Multiple -selections from the following may be specified as a comma separated -string, and invalid options are ignored: - -@table @code -@item no-aliases -Print the 'raw' instruction mnemonic instead of some pseudo -instruction mnemonic. I.e., print 'daddu' or 'or' instead of 'move', -'sll' instead of 'nop', etc. - -@item gpr-names=@var{ABI} -Print GPR (general-purpose register) names as appropriate -for the specified ABI. By default, GPR names are selected according to -the ABI of the binary being disassembled. - -@item fpr-names=@var{ABI} -Print FPR (floating-point register) names as -appropriate for the specified ABI. By default, FPR numbers are printed -rather than names. - -@item cp0-names=@var{ARCH} -Print CP0 (system control coprocessor; coprocessor 0) register names -as appropriate for the CPU or architecture specified by -@var{ARCH}. By default, CP0 register names are selected according to -the architecture and CPU of the binary being disassembled. - -@item hwr-names=@var{ARCH} -Print HWR (hardware register, used by the @code{rdhwr} instruction) names -as appropriate for the CPU or architecture specified by -@var{ARCH}. By default, HWR names are selected according to -the architecture and CPU of the binary being disassembled. - -@item reg-names=@var{ABI} -Print GPR and FPR names as appropriate for the selected ABI. - -@item reg-names=@var{ARCH} -Print CPU-specific register names (CP0 register and HWR names) -as appropriate for the selected CPU or architecture. -@end table - -For any of the options listed above, @var{ABI} or -@var{ARCH} may be specified as @samp{numeric} to have numbers printed -rather than names, for the selected types of registers. -You can list the available values of @var{ABI} and @var{ARCH} using -the @option{--help} option. - -For VAX, you can specify function entry addresses with @option{-M -entry:0xf00ba}. You can use this multiple times to properly -disassemble VAX binary files that don't contain symbol tables (like -ROM dumps). In these cases, the function entry mask would otherwise -be decoded as VAX instructions, which would probably lead the rest -of the function being wrongly disassembled. - -@item -p -@itemx --private-headers -Print information that is specific to the object file format. The exact -information printed depends upon the object file format. For some -object file formats, no additional information is printed. - -@item -P @var{options} -@itemx --private=@var{options} -Print information that is specific to the object file format. The -argument @var{options} is a comma separated list that depends on the -format (the lists of options is displayed with the help). - -For XCOFF, the available options are: @option{header}, @option{aout}, -@option{sections}, @option{syms}, @option{relocs}, @option{lineno}, -@option{loader}, @option{except}, @option{typchk}, @option{traceback} -and @option{toc}. - -@item -r -@itemx --reloc -@cindex relocation entries, in object file -Print the relocation entries of the file. If used with @option{-d} or -@option{-D}, the relocations are printed interspersed with the -disassembly. - -@item -R -@itemx --dynamic-reloc -@cindex dynamic relocation entries, in object file -Print the dynamic relocation entries of the file. This is only -meaningful for dynamic objects, such as certain types of shared -libraries. As for @option{-r}, if used with @option{-d} or -@option{-D}, the relocations are printed interspersed with the -disassembly. - -@item -s -@itemx --full-contents -@cindex sections, full contents -@cindex object file sections -Display the full contents of any sections requested. By default all -non-empty sections are displayed. - -@item -S -@itemx --source -@cindex source disassembly -@cindex disassembly, with source -Display source code intermixed with disassembly, if possible. Implies -@option{-d}. - -@item --prefix=@var{prefix} -@cindex Add prefix to absolute paths -Specify @var{prefix} to add to the absolute paths when used with -@option{-S}. - -@item --prefix-strip=@var{level} -@cindex Strip absolute paths -Indicate how many initial directory names to strip off the hardwired -absolute paths. It has no effect without @option{--prefix=}@var{prefix}. - -@item --show-raw-insn -When disassembling instructions, print the instruction in hex as well as -in symbolic form. This is the default except when -@option{--prefix-addresses} is used. - -@item --no-show-raw-insn -When disassembling instructions, do not print the instruction bytes. -This is the default when @option{--prefix-addresses} is used. - -@item --insn-width=@var{width} -@cindex Instruction width -Display @var{width} bytes on a single line when disassembling -instructions. - -@item -W[lLiaprmfFsoRt] -@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index] -@cindex DWARF -@cindex debug symbols -Displays the contents of the debug sections in the file, if any are -present. If one of the optional letters or words follows the switch -then only data found in those specific sections will be dumped. - -Note that there is no single letter option to display the content of -trace sections or .gdb_index. - -Note: the output from the @option{=info} option can also be affected -by the options @option{--dwarf-depth} and @option{--dwarf-start}. - -@item --dwarf-depth=@var{n} -Limit the dump of the @code{.debug_info} section to @var{n} children. -This is only useful with @option{--dwarf=info}. The default is -to print all DIEs; the special value 0 for @var{n} will also have this -effect. - -With a non-zero value for @var{n}, DIEs at or deeper than @var{n} -levels will not be printed. The range for @var{n} is zero-based. - -@item --dwarf-start=@var{n} -Print only DIEs beginning with the DIE numbered @var{n}. This is only -useful with @option{--dwarf=info}. - -If specified, this option will suppress printing of any header -information and all DIEs before the DIE numbered @var{n}. Only -siblings and children of the specified DIE will be printed. - -This can be used in conjunction with @option{--dwarf-depth}. - -@item -G -@itemx --stabs -@cindex stab -@cindex .stab -@cindex debug symbols -@cindex ELF object file format -Display the full contents of any sections requested. Display the -contents of the .stab and .stab.index and .stab.excl sections from an -ELF file. This is only useful on systems (such as Solaris 2.0) in which -@code{.stab} debugging symbol-table entries are carried in an ELF -section. In most other file formats, debugging symbol-table entries are -interleaved with linkage symbols, and are visible in the @option{--syms} -output. -@ifclear man -For more information on stabs symbols, see @ref{Top,Stabs,Stabs -Overview,stabs.info, The ``stabs'' debug format}. -@end ifclear - -@item --start-address=@var{address} -@cindex start-address -Start displaying data at the specified address. This affects the output -of the @option{-d}, @option{-r} and @option{-s} options. - -@item --stop-address=@var{address} -@cindex stop-address -Stop displaying data at the specified address. This affects the output -of the @option{-d}, @option{-r} and @option{-s} options. - -@item -t -@itemx --syms -@cindex symbol table entries, printing -Print the symbol table entries of the file. -This is similar to the information provided by the @samp{nm} program, -although the display format is different. The format of the output -depends upon the format of the file being dumped, but there are two main -types. One looks like this: - -@smallexample -[ 4](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss -[ 6](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 fred -@end smallexample - -where the number inside the square brackets is the number of the entry -in the symbol table, the @var{sec} number is the section number, the -@var{fl} value are the symbol's flag bits, the @var{ty} number is the -symbol's type, the @var{scl} number is the symbol's storage class and -the @var{nx} value is the number of auxilary entries associated with -the symbol. The last two fields are the symbol's value and its name. - -The other common output format, usually seen with ELF based files, -looks like this: - -@smallexample -00000000 l d .bss 00000000 .bss -00000000 g .text 00000000 fred -@end smallexample - -Here the first number is the symbol's value (sometimes refered to as -its address). The next field is actually a set of characters and -spaces indicating the flag bits that are set on the symbol. These -characters are described below. Next is the section with which the -symbol is associated or @emph{*ABS*} if the section is absolute (ie -not connected with any section), or @emph{*UND*} if the section is -referenced in the file being dumped, but not defined there. - -After the section name comes another field, a number, which for common -symbols is the alignment and for other symbol is the size. Finally -the symbol's name is displayed. - -The flag characters are divided into 7 groups as follows: -@table @code -@item l -@itemx g -@itemx u -@itemx ! -The symbol is a local (l), global (g), unique global (u), neither -global nor local (a space) or both global and local (!). A -symbol can be neither local or global for a variety of reasons, e.g., -because it is used for debugging, but it is probably an indication of -a bug if it is ever both local and global. Unique global symbols are -a GNU extension to the standard set of ELF symbol bindings. For such -a symbol the dynamic linker will make sure that in the entire process -there is just one symbol with this name and type in use. - -@item w -The symbol is weak (w) or strong (a space). - -@item C -The symbol denotes a constructor (C) or an ordinary symbol (a space). - -@item W -The symbol is a warning (W) or a normal symbol (a space). A warning -symbol's name is a message to be displayed if the symbol following the -warning symbol is ever referenced. - -@item I -@item i -The symbol is an indirect reference to another symbol (I), a function -to be evaluated during reloc processing (i) or a normal symbol (a -space). - -@item d -@itemx D -The symbol is a debugging symbol (d) or a dynamic symbol (D) or a -normal symbol (a space). - -@item F -@item f -@item O -The symbol is the name of a function (F) or a file (f) or an object -(O) or just a normal symbol (a space). -@end table - -@item -T -@itemx --dynamic-syms -@cindex dynamic symbol table entries, printing -Print the dynamic symbol table entries of the file. This is only -meaningful for dynamic objects, such as certain types of shared -libraries. This is similar to the information provided by the @samp{nm} -program when given the @option{-D} (@option{--dynamic}) option. - -@item --special-syms -When displaying symbols include those which the target considers to be -special in some way and which would not normally be of interest to the -user. - -@item -V -@itemx --version -Print the version number of @command{objdump} and exit. - -@item -x -@itemx --all-headers -@cindex all header information, object file -@cindex header information, all -Display all available header information, including the symbol table and -relocation entries. Using @option{-x} is equivalent to specifying all of -@option{-a -f -h -p -r -t}. - -@item -w -@itemx --wide -@cindex wide output, printing -Format some lines for output devices that have more than 80 columns. -Also do not truncate symbol names when they are displayed. - -@item -z -@itemx --disassemble-zeroes -Normally the disassembly output will skip blocks of zeroes. This -option directs the disassembler to disassemble those blocks, just like -any other data. -@end table - -@c man end - -@ignore -@c man begin SEEALSO objdump -nm(1), readelf(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node ranlib -@chapter ranlib - -@kindex ranlib -@cindex archive contents -@cindex symbol index - -@c man title ranlib generate index to archive. - -@smallexample -@c man begin SYNOPSIS ranlib -ranlib [@option{-vVt}] @var{archive} -@c man end -@end smallexample - -@c man begin DESCRIPTION ranlib - -@command{ranlib} generates an index to the contents of an archive and -stores it in the archive. The index lists each symbol defined by a -member of an archive that is a relocatable object file. - -You may use @samp{nm -s} or @samp{nm --print-armap} to list this index. - -An archive with such an index speeds up linking to the library and -allows routines in the library to call each other without regard to -their placement in the archive. - -The @sc{gnu} @command{ranlib} program is another form of @sc{gnu} @command{ar}; running -@command{ranlib} is completely equivalent to executing @samp{ar -s}. -@xref{ar}. - -@c man end - -@c man begin OPTIONS ranlib - -@table @env -@item -v -@itemx -V -@itemx --version -Show the version number of @command{ranlib}. - -@item -t -Update the timestamp of the symbol map of an archive. -@end table - -@c man end - -@ignore -@c man begin SEEALSO ranlib -ar(1), nm(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node size -@chapter size - -@kindex size -@cindex section sizes - -@c man title size list section sizes and total size. - -@smallexample -@c man begin SYNOPSIS size -size [@option{-A}|@option{-B}|@option{--format=}@var{compatibility}] - [@option{--help}] - [@option{-d}|@option{-o}|@option{-x}|@option{--radix=}@var{number}] - [@option{--common}] - [@option{-t}|@option{--totals}] - [@option{--target=}@var{bfdname}] [@option{-V}|@option{--version}] - [@var{objfile}@dots{}] -@c man end -@end smallexample - -@c man begin DESCRIPTION size - -The @sc{gnu} @command{size} utility lists the section sizes---and the total -size---for each of the object or archive files @var{objfile} in its -argument list. By default, one line of output is generated for each -object file or each module in an archive. - -@var{objfile}@dots{} are the object files to be examined. -If none are specified, the file @code{a.out} will be used. - -@c man end - -@c man begin OPTIONS size - -The command line options have the following meanings: - -@table @env -@item -A -@itemx -B -@itemx --format=@var{compatibility} -@cindex @command{size} display format -Using one of these options, you can choose whether the output from @sc{gnu} -@command{size} resembles output from System V @command{size} (using @option{-A}, -or @option{--format=sysv}), or Berkeley @command{size} (using @option{-B}, or -@option{--format=berkeley}). The default is the one-line format similar to -Berkeley's. -@c Bonus for doc-source readers: you can also say --format=strange (or -@c anything else that starts with 's') for sysv, and --format=boring (or -@c anything else that starts with 'b') for Berkeley. - -Here is an example of the Berkeley (default) format of output from -@command{size}: -@smallexample -$ size --format=Berkeley ranlib size -text data bss dec hex filename -294880 81920 11592 388392 5ed28 ranlib -294880 81920 11888 388688 5ee50 size -@end smallexample - -@noindent -This is the same data, but displayed closer to System V conventions: - -@smallexample -$ size --format=SysV ranlib size -ranlib : -section size addr -.text 294880 8192 -.data 81920 303104 -.bss 11592 385024 -Total 388392 - - -size : -section size addr -.text 294880 8192 -.data 81920 303104 -.bss 11888 385024 -Total 388688 -@end smallexample - -@item --help -Show a summary of acceptable arguments and options. - -@item -d -@itemx -o -@itemx -x -@itemx --radix=@var{number} -@cindex @command{size} number format -@cindex radix for section sizes -Using one of these options, you can control whether the size of each -section is given in decimal (@option{-d}, or @option{--radix=10}); octal -(@option{-o}, or @option{--radix=8}); or hexadecimal (@option{-x}, or -@option{--radix=16}). In @option{--radix=@var{number}}, only the three -values (8, 10, 16) are supported. The total size is always given in two -radices; decimal and hexadecimal for @option{-d} or @option{-x} output, or -octal and hexadecimal if you're using @option{-o}. - -@item --common -Print total size of common symbols in each file. When using Berkeley -format these are included in the bss size. - -@item -t -@itemx --totals -Show totals of all objects listed (Berkeley format listing mode only). - -@item --target=@var{bfdname} -@cindex object code format -Specify that the object-code format for @var{objfile} is -@var{bfdname}. This option may not be necessary; @command{size} can -automatically recognize many formats. -@xref{Target Selection}, for more information. - -@item -V -@itemx --version -Display the version number of @command{size}. -@end table - -@c man end - -@ignore -@c man begin SEEALSO size -ar(1), objdump(1), readelf(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node strings -@chapter strings -@kindex strings -@cindex listings strings -@cindex printing strings -@cindex strings, printing - -@c man title strings print the strings of printable characters in files. - -@smallexample -@c man begin SYNOPSIS strings -strings [@option{-afovV}] [@option{-}@var{min-len}] - [@option{-n} @var{min-len}] [@option{--bytes=}@var{min-len}] - [@option{-t} @var{radix}] [@option{--radix=}@var{radix}] - [@option{-e} @var{encoding}] [@option{--encoding=}@var{encoding}] - [@option{-}] [@option{--all}] [@option{--print-file-name}] - [@option{-T} @var{bfdname}] [@option{--target=}@var{bfdname}] - [@option{--help}] [@option{--version}] @var{file}@dots{} -@c man end -@end smallexample - -@c man begin DESCRIPTION strings - -For each @var{file} given, @sc{gnu} @command{strings} prints the printable -character sequences that are at least 4 characters long (or the number -given with the options below) and are followed by an unprintable -character. By default, it only prints the strings from the initialized -and loaded sections of object files; for other types of files, it prints -the strings from the whole file. - -@command{strings} is mainly useful for determining the contents of non-text -files. - -@c man end - -@c man begin OPTIONS strings - -@table @env -@item -a -@itemx --all -@itemx - -Do not scan only the initialized and loaded sections of object files; -scan the whole files. - -@item -f -@itemx --print-file-name -Print the name of the file before each string. - -@item --help -Print a summary of the program usage on the standard output and exit. - -@item -@var{min-len} -@itemx -n @var{min-len} -@itemx --bytes=@var{min-len} -Print sequences of characters that are at least @var{min-len} characters -long, instead of the default 4. - -@item -o -Like @samp{-t o}. Some other versions of @command{strings} have @option{-o} -act like @samp{-t d} instead. Since we can not be compatible with both -ways, we simply chose one. - -@item -t @var{radix} -@itemx --radix=@var{radix} -Print the offset within the file before each string. The single -character argument specifies the radix of the offset---@samp{o} for -octal, @samp{x} for hexadecimal, or @samp{d} for decimal. - -@item -e @var{encoding} -@itemx --encoding=@var{encoding} -Select the character encoding of the strings that are to be found. -Possible values for @var{encoding} are: @samp{s} = single-7-bit-byte -characters (ASCII, ISO 8859, etc., default), @samp{S} = -single-8-bit-byte characters, @samp{b} = 16-bit bigendian, @samp{l} = -16-bit littleendian, @samp{B} = 32-bit bigendian, @samp{L} = 32-bit -littleendian. Useful for finding wide character strings. (@samp{l} -and @samp{b} apply to, for example, Unicode UTF-16/UCS-2 encodings). - -@item -T @var{bfdname} -@itemx --target=@var{bfdname} -@cindex object code format -Specify an object code format other than your system's default format. -@xref{Target Selection}, for more information. - -@item -v -@itemx -V -@itemx --version -Print the program version number on the standard output and exit. -@end table - -@c man end - -@ignore -@c man begin SEEALSO strings -ar(1), nm(1), objdump(1), ranlib(1), readelf(1) -and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node strip -@chapter strip - -@kindex strip -@cindex removing symbols -@cindex discarding symbols -@cindex symbols, discarding - -@c man title strip Discard symbols from object files. - -@smallexample -@c man begin SYNOPSIS strip -strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}] - [@option{-I} @var{bfdname} |@option{--input-target=}@var{bfdname}] - [@option{-O} @var{bfdname} |@option{--output-target=}@var{bfdname}] - [@option{-s}|@option{--strip-all}] - [@option{-S}|@option{-g}|@option{-d}|@option{--strip-debug}] - [@option{-K} @var{symbolname} |@option{--keep-symbol=}@var{symbolname}] - [@option{-N} @var{symbolname} |@option{--strip-symbol=}@var{symbolname}] - [@option{-w}|@option{--wildcard}] - [@option{-x}|@option{--discard-all}] [@option{-X} |@option{--discard-locals}] - [@option{-R} @var{sectionname} |@option{--remove-section=}@var{sectionname}] - [@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}] - [@option{--keep-file-symbols}] - [@option{--only-keep-debug}] - [@option{-v} |@option{--verbose}] [@option{-V}|@option{--version}] - [@option{--help}] [@option{--info}] - @var{objfile}@dots{} -@c man end -@end smallexample - -@c man begin DESCRIPTION strip - -@sc{gnu} @command{strip} discards all symbols from object files -@var{objfile}. The list of object files may include archives. -At least one object file must be given. - -@command{strip} modifies the files named in its argument, -rather than writing modified copies under different names. - -@c man end - -@c man begin OPTIONS strip - -@table @env -@item -F @var{bfdname} -@itemx --target=@var{bfdname} -Treat the original @var{objfile} as a file with the object -code format @var{bfdname}, and rewrite it in the same format. -@xref{Target Selection}, for more information. - -@item --help -Show a summary of the options to @command{strip} and exit. - -@item --info -Display a list showing all architectures and object formats available. - -@item -I @var{bfdname} -@itemx --input-target=@var{bfdname} -Treat the original @var{objfile} as a file with the object -code format @var{bfdname}. -@xref{Target Selection}, for more information. - -@item -O @var{bfdname} -@itemx --output-target=@var{bfdname} -Replace @var{objfile} with a file in the output format @var{bfdname}. -@xref{Target Selection}, for more information. - -@item -R @var{sectionname} -@itemx --remove-section=@var{sectionname} -Remove any section named @var{sectionname} from the output file. This -option may be given more than once. Note that using this option -inappropriately may make the output file unusable. - -@item -s -@itemx --strip-all -Remove all symbols. - -@item -g -@itemx -S -@itemx -d -@itemx --strip-debug -Remove debugging symbols only. - -@item --strip-unneeded -Remove all symbols that are not needed for relocation processing. - -@item -K @var{symbolname} -@itemx --keep-symbol=@var{symbolname} -When stripping symbols, keep symbol @var{symbolname} even if it would -normally be stripped. This option may be given more than once. - -@item -N @var{symbolname} -@itemx --strip-symbol=@var{symbolname} -Remove symbol @var{symbolname} from the source file. This option may be -given more than once, and may be combined with strip options other than -@option{-K}. - -@item -o @var{file} -Put the stripped output in @var{file}, rather than replacing the -existing file. When this argument is used, only one @var{objfile} -argument may be specified. - -@item -p -@itemx --preserve-dates -Preserve the access and modification dates of the file. - -@item -w -@itemx --wildcard -Permit regular expressions in @var{symbolname}s used in other command -line options. The question mark (?), asterisk (*), backslash (\) and -square brackets ([]) operators can be used anywhere in the symbol -name. If the first character of the symbol name is the exclamation -point (!) then the sense of the switch is reversed for that symbol. -For example: - -@smallexample - -w -K !foo -K fo* -@end smallexample - -would cause strip to only keep symbols that start with the letters -``fo'', but to discard the symbol ``foo''. - -@item -x -@itemx --discard-all -Remove non-global symbols. - -@item -X -@itemx --discard-locals -Remove compiler-generated local symbols. -(These usually start with @samp{L} or @samp{.}.) - -@item --keep-file-symbols -When stripping a file, perhaps with @option{--strip-debug} or -@option{--strip-unneeded}, retain any symbols specifying source file names, -which would otherwise get stripped. - -@item --only-keep-debug -Strip a file, removing contents of any sections that would not be -stripped by @option{--strip-debug} and leaving the debugging sections -intact. In ELF files, this preserves all note sections in the output. - -The intention is that this option will be used in conjunction with -@option{--add-gnu-debuglink} to create a two part executable. One a -stripped binary which will occupy less space in RAM and in a -distribution and the second a debugging information file which is only -needed if debugging abilities are required. The suggested procedure -to create these files is as follows: - -@enumerate -@item Link the executable as normal. Assuming that is is called -@code{foo} then... -@item Run @code{objcopy --only-keep-debug foo foo.dbg} to -create a file containing the debugging info. -@item Run @code{objcopy --strip-debug foo} to create a -stripped executable. -@item Run @code{objcopy --add-gnu-debuglink=foo.dbg foo} -to add a link to the debugging info into the stripped executable. -@end enumerate - -Note---the choice of @code{.dbg} as an extension for the debug info -file is arbitrary. Also the @code{--only-keep-debug} step is -optional. You could instead do this: - -@enumerate -@item Link the executable as normal. -@item Copy @code{foo} to @code{foo.full} -@item Run @code{strip --strip-debug foo} -@item Run @code{objcopy --add-gnu-debuglink=foo.full foo} -@end enumerate - -i.e., the file pointed to by the @option{--add-gnu-debuglink} can be the -full executable. It does not have to be a file created by the -@option{--only-keep-debug} switch. - -Note---this switch is only intended for use on fully linked files. It -does not make sense to use it on object files where the debugging -information may be incomplete. Besides the gnu_debuglink feature -currently only supports the presence of one filename containing -debugging information, not multiple filenames on a one-per-object-file -basis. - -@item -V -@itemx --version -Show the version number for @command{strip}. - -@item -v -@itemx --verbose -Verbose output: list all object files modified. In the case of -archives, @samp{strip -v} lists all members of the archive. -@end table - -@c man end - -@ignore -@c man begin SEEALSO strip -the Info entries for @file{binutils}. -@c man end -@end ignore - -@node c++filt, addr2line, elfedit, Top -@chapter c++filt - -@kindex c++filt -@cindex demangling C++ symbols - -@c man title cxxfilt Demangle C++ and Java symbols. - -@smallexample -@c man begin SYNOPSIS cxxfilt -c++filt [@option{-_}|@option{--strip-underscores}] - [@option{-n}|@option{--no-strip-underscores}] - [@option{-p}|@option{--no-params}] - [@option{-t}|@option{--types}] - [@option{-i}|@option{--no-verbose}] - [@option{-s} @var{format}|@option{--format=}@var{format}] - [@option{--help}] [@option{--version}] [@var{symbol}@dots{}] -@c man end -@end smallexample - -@c man begin DESCRIPTION cxxfilt - -@kindex cxxfilt -The C++ and Java languages provide function overloading, which means -that you can write many functions with the same name, providing that -each function takes parameters of different types. In order to be -able to distinguish these similarly named functions C++ and Java -encode them into a low-level assembler name which uniquely identifies -each different version. This process is known as @dfn{mangling}. The -@command{c++filt} -@footnote{MS-DOS does not allow @kbd{+} characters in file names, so on -MS-DOS this program is named @command{CXXFILT}.} -program does the inverse mapping: it decodes (@dfn{demangles}) low-level -names into user-level names so that they can be read. - -Every alphanumeric word (consisting of letters, digits, underscores, -dollars, or periods) seen in the input is a potential mangled name. -If the name decodes into a C++ name, the C++ name replaces the -low-level name in the output, otherwise the original word is output. -In this way you can pass an entire assembler source file, containing -mangled names, through @command{c++filt} and see the same source file -containing demangled names. - -You can also use @command{c++filt} to decipher individual symbols by -passing them on the command line: - -@example -c++filt @var{symbol} -@end example - -If no @var{symbol} arguments are given, @command{c++filt} reads symbol -names from the standard input instead. All the results are printed on -the standard output. The difference between reading names from the -command line versus reading names from the standard input is that -command line arguments are expected to be just mangled names and no -checking is performed to separate them from surrounding text. Thus -for example: - -@smallexample -c++filt -n _Z1fv -@end smallexample - -will work and demangle the name to ``f()'' whereas: - -@smallexample -c++filt -n _Z1fv, -@end smallexample - -will not work. (Note the extra comma at the end of the mangled -name which makes it invalid). This command however will work: - -@smallexample -echo _Z1fv, | c++filt -n -@end smallexample - -and will display ``f(),'', i.e., the demangled name followed by a -trailing comma. This behaviour is because when the names are read -from the standard input it is expected that they might be part of an -assembler source file where there might be extra, extraneous -characters trailing after a mangled name. For example: - -@smallexample - .type _Z1fv, @@function -@end smallexample - -@c man end - -@c man begin OPTIONS cxxfilt - -@table @env -@item -_ -@itemx --strip-underscores -On some systems, both the C and C++ compilers put an underscore in front -of every name. For example, the C name @code{foo} gets the low-level -name @code{_foo}. This option removes the initial underscore. Whether -@command{c++filt} removes the underscore by default is target dependent. - -@item -n -@itemx --no-strip-underscores -Do not remove the initial underscore. - -@item -p -@itemx --no-params -When demangling the name of a function, do not display the types of -the function's parameters. - -@item -t -@itemx --types -Attempt to demangle types as well as function names. This is disabled -by default since mangled types are normally only used internally in -the compiler, and they can be confused with non-mangled names. For example, -a function called ``a'' treated as a mangled type name would be -demangled to ``signed char''. - -@item -i -@itemx --no-verbose -Do not include implementation details (if any) in the demangled -output. - -@item -s @var{format} -@itemx --format=@var{format} -@command{c++filt} can decode various methods of mangling, used by -different compilers. The argument to this option selects which -method it uses: - -@table @code -@item auto -Automatic selection based on executable (the default method) -@item gnu -the one used by the @sc{gnu} C++ compiler (g++) -@item lucid -the one used by the Lucid compiler (lcc) -@item arm -the one specified by the C++ Annotated Reference Manual -@item hp -the one used by the HP compiler (aCC) -@item edg -the one used by the EDG compiler -@item gnu-v3 -the one used by the @sc{gnu} C++ compiler (g++) with the V3 ABI. -@item java -the one used by the @sc{gnu} Java compiler (gcj) -@item gnat -the one used by the @sc{gnu} Ada compiler (GNAT). -@end table - -@item --help -Print a summary of the options to @command{c++filt} and exit. - -@item --version -Print the version number of @command{c++filt} and exit. -@end table - -@c man end - -@ignore -@c man begin SEEALSO cxxfilt -the Info entries for @file{binutils}. -@c man end -@end ignore - -@quotation -@emph{Warning:} @command{c++filt} is a new utility, and the details of its -user interface are subject to change in future releases. In particular, -a command-line option may be required in the future to decode a name -passed as an argument on the command line; in other words, - -@example -c++filt @var{symbol} -@end example - -@noindent -may in a future release become - -@example -c++filt @var{option} @var{symbol} -@end example -@end quotation - -@node addr2line -@chapter addr2line - -@kindex addr2line -@cindex address to file name and line number - -@c man title addr2line convert addresses into file names and line numbers. - -@smallexample -@c man begin SYNOPSIS addr2line -addr2line [@option{-a}|@option{--addresses}] - [@option{-b} @var{bfdname}|@option{--target=}@var{bfdname}] - [@option{-C}|@option{--demangle}[=@var{style}]] - [@option{-e} @var{filename}|@option{--exe=}@var{filename}] - [@option{-f}|@option{--functions}] [@option{-s}|@option{--basename}] - [@option{-i}|@option{--inlines}] - [@option{-p}|@option{--pretty-print}] - [@option{-j}|@option{--section=}@var{name}] - [@option{-H}|@option{--help}] [@option{-V}|@option{--version}] - [addr addr @dots{}] -@c man end -@end smallexample - -@c man begin DESCRIPTION addr2line - -@command{addr2line} translates addresses into file names and line numbers. -Given an address in an executable or an offset in a section of a relocatable -object, it uses the debugging information to figure out which file name and -line number are associated with it. - -The executable or relocatable object to use is specified with the @option{-e} -option. The default is the file @file{a.out}. The section in the relocatable -object to use is specified with the @option{-j} option. - -@command{addr2line} has two modes of operation. - -In the first, hexadecimal addresses are specified on the command line, -and @command{addr2line} displays the file name and line number for each -address. - -In the second, @command{addr2line} reads hexadecimal addresses from -standard input, and prints the file name and line number for each -address on standard output. In this mode, @command{addr2line} may be used -in a pipe to convert dynamically chosen addresses. - -The format of the output is @samp{FILENAME:LINENO}. The file name and -line number for each address is printed on a separate line. If the -@command{-f} option is used, then each @samp{FILENAME:LINENO} line is -preceded by a @samp{FUNCTIONNAME} line which is the name of the function -containing the address. If the @command{-a} option is used, then the -address read is first printed. - -If the file name or function name can not be determined, -@command{addr2line} will print two question marks in their place. If the -line number can not be determined, @command{addr2line} will print 0. - -@c man end - -@c man begin OPTIONS addr2line - -The long and short forms of options, shown here as alternatives, are -equivalent. - -@table @env -@item -a -@itemx --addresses -Display address before function names or file and line number -information. The address is printed with a @samp{0x} prefix to easily -identify it. - -@item -b @var{bfdname} -@itemx --target=@var{bfdname} -@cindex object code format -Specify that the object-code format for the object files is -@var{bfdname}. - -@item -C -@itemx --demangle[=@var{style}] -@cindex demangling in objdump -Decode (@dfn{demangle}) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes C++ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. @xref{c++filt}, -for more information on demangling. - -@item -e @var{filename} -@itemx --exe=@var{filename} -Specify the name of the executable for which addresses should be -translated. The default file is @file{a.out}. - -@item -f -@itemx --functions -Display function names as well as file and line number information. - -@item -s -@itemx --basenames -Display only the base of each file name. - -@item -i -@itemx --inlines -If the address belongs to a function that was inlined, the source -information for all enclosing scopes back to the first non-inlined -function will also be printed. For example, if @code{main} inlines -@code{callee1} which inlines @code{callee2}, and address is from -@code{callee2}, the source information for @code{callee1} and @code{main} -will also be printed. - -@item -j -@itemx --section -Read offsets relative to the specified section instead of absolute addresses. - -@item -p -@itemx --pretty-print -Make the output more human friendly: each location are printed on one line. -If option @option{-i} is specified, lines for all enclosing scopes are -prefixed with @samp{(inlined by)}. -@end table - -@c man end - -@ignore -@c man begin SEEALSO addr2line -Info entries for @file{binutils}. -@c man end -@end ignore - -@node nlmconv -@chapter nlmconv - -@command{nlmconv} converts a relocatable object file into a NetWare -Loadable Module. - -@ignore -@command{nlmconv} currently works with @samp{i386} object -files in @code{coff}, @sc{elf}, or @code{a.out} format, and @sc{SPARC} -object files in @sc{elf}, or @code{a.out} format@footnote{ -@command{nlmconv} should work with any @samp{i386} or @sc{sparc} object -format in the Binary File Descriptor library. It has only been tested -with the above formats.}. -@end ignore - -@quotation -@emph{Warning:} @command{nlmconv} is not always built as part of the binary -utilities, since it is only useful for NLM targets. -@end quotation - -@c man title nlmconv converts object code into an NLM. - -@smallexample -@c man begin SYNOPSIS nlmconv -nlmconv [@option{-I} @var{bfdname}|@option{--input-target=}@var{bfdname}] - [@option{-O} @var{bfdname}|@option{--output-target=}@var{bfdname}] - [@option{-T} @var{headerfile}|@option{--header-file=}@var{headerfile}] - [@option{-d}|@option{--debug}] [@option{-l} @var{linker}|@option{--linker=}@var{linker}] - [@option{-h}|@option{--help}] [@option{-V}|@option{--version}] - @var{infile} @var{outfile} -@c man end -@end smallexample - -@c man begin DESCRIPTION nlmconv - -@command{nlmconv} converts the relocatable @samp{i386} object file -@var{infile} into the NetWare Loadable Module @var{outfile}, optionally -reading @var{headerfile} for NLM header information. For instructions -on writing the NLM command file language used in header files, see the -@samp{linkers} section, @samp{NLMLINK} in particular, of the @cite{NLM -Development and Tools Overview}, which is part of the NLM Software -Developer's Kit (``NLM SDK''), available from Novell, Inc. -@command{nlmconv} uses the @sc{gnu} Binary File Descriptor library to read -@var{infile}; -@ifclear man -see @ref{BFD,,BFD,ld.info,Using LD}, for more information. -@end ifclear - -@command{nlmconv} can perform a link step. In other words, you can list -more than one object file for input if you list them in the definitions -file (rather than simply specifying one input file on the command line). -In this case, @command{nlmconv} calls the linker for you. - -@c man end - -@c man begin OPTIONS nlmconv - -@table @env -@item -I @var{bfdname} -@itemx --input-target=@var{bfdname} -Object format of the input file. @command{nlmconv} can usually determine -the format of a given file (so no default is necessary). -@xref{Target Selection}, for more information. - -@item -O @var{bfdname} -@itemx --output-target=@var{bfdname} -Object format of the output file. @command{nlmconv} infers the output -format based on the input format, e.g. for a @samp{i386} input file the -output format is @samp{nlm32-i386}. -@xref{Target Selection}, for more information. - -@item -T @var{headerfile} -@itemx --header-file=@var{headerfile} -Reads @var{headerfile} for NLM header information. For instructions on -writing the NLM command file language used in header files, see@ see the -@samp{linkers} section, of the @cite{NLM Development and Tools -Overview}, which is part of the NLM Software Developer's Kit, available -from Novell, Inc. - -@item -d -@itemx --debug -Displays (on standard error) the linker command line used by @command{nlmconv}. - -@item -l @var{linker} -@itemx --linker=@var{linker} -Use @var{linker} for any linking. @var{linker} can be an absolute or a -relative pathname. - -@item -h -@itemx --help -Prints a usage summary. - -@item -V -@itemx --version -Prints the version number for @command{nlmconv}. -@end table - -@c man end - -@ignore -@c man begin SEEALSO nlmconv -the Info entries for @file{binutils}. -@c man end -@end ignore - -@node windmc -@chapter windmc - -@command{windmc} may be used to generator Windows message resources. - -@quotation -@emph{Warning:} @command{windmc} is not always built as part of the binary -utilities, since it is only useful for Windows targets. -@end quotation - -@c man title windmc generates Windows message resources. - -@smallexample -@c man begin SYNOPSIS windmc -windmc [options] input-file -@c man end -@end smallexample - -@c man begin DESCRIPTION windmc - -@command{windmc} reads message definitions from an input file (.mc) and -translate them into a set of output files. The output files may be of -four kinds: - -@table @code -@item h -A C header file containing the message definitions. - -@item rc -A resource file compilable by the @command{windres} tool. - -@item bin -One or more binary files containing the resource data for a specific -message language. - -@item dbg -A C include file that maps message id's to their symbolic name. -@end table - -The exact description of these different formats is available in -documentation from Microsoft. - -When @command{windmc} converts from the @code{mc} format to the @code{bin} -format, @code{rc}, @code{h}, and optional @code{dbg} it is acting like the -Windows Message Compiler. - -@c man end - -@c man begin OPTIONS windmc - -@table @env -@item -a -@itemx --ascii_in -Specifies that the input file specified is ASCII. This is the default -behaviour. - -@item -A -@itemx --ascii_out -Specifies that messages in the output @code{bin} files should be in ASCII -format. - -@item -b -@itemx --binprefix -Specifies that @code{bin} filenames should have to be prefixed by the -basename of the source file. - -@item -c -@itemx --customflag -Sets the customer bit in all message id's. - -@item -C @var{codepage} -@itemx --codepage_in @var{codepage} -Sets the default codepage to be used to convert input file to UTF16. The -default is ocdepage 1252. - -@item -d -@itemx --decimal_values -Outputs the constants in the header file in decimal. Default is using -hexadecimal output. - -@item -e @var{ext} -@itemx --extension @var{ext} -The extension for the header file. The default is .h extension. - -@item -F @var{target} -@itemx --target @var{target} -Specify the BFD format to use for a bin file as output. This -is a BFD target name; you can use the @option{--help} option to see a list -of supported targets. Normally @command{windmc} will use the default -format, which is the first one listed by the @option{--help} option. -@ifclear man -@ref{Target Selection}. -@end ifclear - -@item -h @var{path} -@itemx --headerdir @var{path} -The target directory of the generated header file. The default is the -current directory. - -@item -H -@itemx --help -Displays a list of command line options and then exits. - -@item -m @var{characters} -@itemx --maxlength @var{characters} -Instructs @command{windmc} to generate a warning if the length -of any message exceeds the number specified. - -@item -n -@itemx --nullterminate -Terminate message text in @code{bin} files by zero. By default they are -terminated by CR/LF. - -@item -o -@itemx --hresult_use -Not yet implemented. Instructs @code{windmc} to generate an OLE2 header -file, using HRESULT definitions. Status codes are used if the flag is not -specified. - -@item -O @var{codepage} -@itemx --codepage_out @var{codepage} -Sets the default codepage to be used to output text files. The default -is ocdepage 1252. - -@item -r @var{path} -@itemx --rcdir @var{path} -The target directory for the generated @code{rc} script and the generated -@code{bin} files that the resource compiler script includes. The default -is the current directory. - -@item -u -@itemx --unicode_in -Specifies that the input file is UTF16. - -@item -U -@itemx --unicode_out -Specifies that messages in the output @code{bin} file should be in UTF16 -format. This is the default behaviour. - -@item -v -@item --verbose -Enable verbose mode. - -@item -V -@item --version -Prints the version number for @command{windmc}. - -@item -x @var{path} -@itemx --xdgb @var{path} -The path of the @code{dbg} C include file that maps message id's to the -symbolic name. No such file is generated without specifying the switch. -@end table - -@c man end - -@ignore -@c man begin SEEALSO windmc -the Info entries for @file{binutils}. -@c man end -@end ignore - -@node windres -@chapter windres - -@command{windres} may be used to manipulate Windows resources. - -@quotation -@emph{Warning:} @command{windres} is not always built as part of the binary -utilities, since it is only useful for Windows targets. -@end quotation - -@c man title windres manipulate Windows resources. - -@smallexample -@c man begin SYNOPSIS windres -windres [options] [input-file] [output-file] -@c man end -@end smallexample - -@c man begin DESCRIPTION windres - -@command{windres} reads resources from an input file and copies them into -an output file. Either file may be in one of three formats: - -@table @code -@item rc -A text format read by the Resource Compiler. - -@item res -A binary format generated by the Resource Compiler. - -@item coff -A COFF object or executable. -@end table - -The exact description of these different formats is available in -documentation from Microsoft. - -When @command{windres} converts from the @code{rc} format to the @code{res} -format, it is acting like the Windows Resource Compiler. When -@command{windres} converts from the @code{res} format to the @code{coff} -format, it is acting like the Windows @code{CVTRES} program. - -When @command{windres} generates an @code{rc} file, the output is similar -but not identical to the format expected for the input. When an input -@code{rc} file refers to an external filename, an output @code{rc} file -will instead include the file contents. - -If the input or output format is not specified, @command{windres} will -guess based on the file name, or, for the input file, the file contents. -A file with an extension of @file{.rc} will be treated as an @code{rc} -file, a file with an extension of @file{.res} will be treated as a -@code{res} file, and a file with an extension of @file{.o} or -@file{.exe} will be treated as a @code{coff} file. - -If no output file is specified, @command{windres} will print the resources -in @code{rc} format to standard output. - -The normal use is for you to write an @code{rc} file, use @command{windres} -to convert it to a COFF object file, and then link the COFF file into -your application. This will make the resources described in the -@code{rc} file available to Windows. - -@c man end - -@c man begin OPTIONS windres - -@table @env -@item -i @var{filename} -@itemx --input @var{filename} -The name of the input file. If this option is not used, then -@command{windres} will use the first non-option argument as the input file -name. If there are no non-option arguments, then @command{windres} will -read from standard input. @command{windres} can not read a COFF file from -standard input. - -@item -o @var{filename} -@itemx --output @var{filename} -The name of the output file. If this option is not used, then -@command{windres} will use the first non-option argument, after any used -for the input file name, as the output file name. If there is no -non-option argument, then @command{windres} will write to standard output. -@command{windres} can not write a COFF file to standard output. Note, -for compatibility with @command{rc} the option @option{-fo} is also -accepted, but its use is not recommended. - -@item -J @var{format} -@itemx --input-format @var{format} -The input format to read. @var{format} may be @samp{res}, @samp{rc}, or -@samp{coff}. If no input format is specified, @command{windres} will -guess, as described above. - -@item -O @var{format} -@itemx --output-format @var{format} -The output format to generate. @var{format} may be @samp{res}, -@samp{rc}, or @samp{coff}. If no output format is specified, -@command{windres} will guess, as described above. - -@item -F @var{target} -@itemx --target @var{target} -Specify the BFD format to use for a COFF file as input or output. This -is a BFD target name; you can use the @option{--help} option to see a list -of supported targets. Normally @command{windres} will use the default -format, which is the first one listed by the @option{--help} option. -@ifclear man -@ref{Target Selection}. -@end ifclear - -@item --preprocessor @var{program} -When @command{windres} reads an @code{rc} file, it runs it through the C -preprocessor first. This option may be used to specify the preprocessor -to use, including any leading arguments. The default preprocessor -argument is @code{gcc -E -xc-header -DRC_INVOKED}. - -@item --preprocessor-arg @var{option} -When @command{windres} reads an @code{rc} file, it runs it through -the C preprocessor first. This option may be used to specify additional -text to be passed to preprocessor on its command line. -This option can be used multiple times to add multiple options to the -preprocessor command line. - -@item -I @var{directory} -@itemx --include-dir @var{directory} -Specify an include directory to use when reading an @code{rc} file. -@command{windres} will pass this to the preprocessor as an @option{-I} -option. @command{windres} will also search this directory when looking for -files named in the @code{rc} file. If the argument passed to this command -matches any of the supported @var{formats} (as described in the @option{-J} -option), it will issue a deprecation warning, and behave just like the -@option{-J} option. New programs should not use this behaviour. If a -directory happens to match a @var{format}, simple prefix it with @samp{./} -to disable the backward compatibility. - -@item -D @var{target} -@itemx --define @var{sym}[=@var{val}] -Specify a @option{-D} option to pass to the preprocessor when reading an -@code{rc} file. - -@item -U @var{target} -@itemx --undefine @var{sym} -Specify a @option{-U} option to pass to the preprocessor when reading an -@code{rc} file. - -@item -r -Ignored for compatibility with rc. - -@item -v -Enable verbose mode. This tells you what the preprocessor is if you -didn't specify one. - -@item -c @var{val} -@item --codepage @var{val} -Specify the default codepage to use when reading an @code{rc} file. -@var{val} should be a hexadecimal prefixed by @samp{0x} or decimal -codepage code. The valid range is from zero up to 0xffff, but the -validity of the codepage is host and configuration dependent. - -@item -l @var{val} -@item --language @var{val} -Specify the default language to use when reading an @code{rc} file. -@var{val} should be a hexadecimal language code. The low eight bits are -the language, and the high eight bits are the sublanguage. - -@item --use-temp-file -Use a temporary file to instead of using popen to read the output of -the preprocessor. Use this option if the popen implementation is buggy -on the host (eg., certain non-English language versions of Windows 95 and -Windows 98 are known to have buggy popen where the output will instead -go the console). - -@item --no-use-temp-file -Use popen, not a temporary file, to read the output of the preprocessor. -This is the default behaviour. - -@item -h -@item --help -Prints a usage summary. - -@item -V -@item --version -Prints the version number for @command{windres}. - -@item --yydebug -If @command{windres} is compiled with @code{YYDEBUG} defined as @code{1}, -this will turn on parser debugging. -@end table - -@c man end - -@ignore -@c man begin SEEALSO windres -the Info entries for @file{binutils}. -@c man end -@end ignore - -@node dlltool -@chapter dlltool -@cindex DLL -@kindex dlltool - -@command{dlltool} is used to create the files needed to create dynamic -link libraries (DLLs) on systems which understand PE format image -files such as Windows. A DLL contains an export table which contains -information that the runtime loader needs to resolve references from a -referencing program. - -The export table is generated by this program by reading in a -@file{.def} file or scanning the @file{.a} and @file{.o} files which -will be in the DLL. A @file{.o} file can contain information in -special @samp{.drectve} sections with export information. - -@quotation -@emph{Note:} @command{dlltool} is not always built as part of the -binary utilities, since it is only useful for those targets which -support DLLs. -@end quotation - -@c man title dlltool Create files needed to build and use DLLs. - -@smallexample -@c man begin SYNOPSIS dlltool -dlltool [@option{-d}|@option{--input-def} @var{def-file-name}] - [@option{-b}|@option{--base-file} @var{base-file-name}] - [@option{-e}|@option{--output-exp} @var{exports-file-name}] - [@option{-z}|@option{--output-def} @var{def-file-name}] - [@option{-l}|@option{--output-lib} @var{library-file-name}] - [@option{-y}|@option{--output-delaylib} @var{library-file-name}] - [@option{--export-all-symbols}] [@option{--no-export-all-symbols}] - [@option{--exclude-symbols} @var{list}] - [@option{--no-default-excludes}] - [@option{-S}|@option{--as} @var{path-to-assembler}] [@option{-f}|@option{--as-flags} @var{options}] - [@option{-D}|@option{--dllname} @var{name}] [@option{-m}|@option{--machine} @var{machine}] - [@option{-a}|@option{--add-indirect}] - [@option{-U}|@option{--add-underscore}] [@option{--add-stdcall-underscore}] - [@option{-k}|@option{--kill-at}] [@option{-A}|@option{--add-stdcall-alias}] - [@option{-p}|@option{--ext-prefix-alias} @var{prefix}] - [@option{-x}|@option{--no-idata4}] [@option{-c}|@option{--no-idata5}] - [@option{--use-nul-prefixed-import-tables}] - [@option{-I}|@option{--identify} @var{library-file-name}] [@option{--identify-strict}] - [@option{-i}|@option{--interwork}] - [@option{-n}|@option{--nodelete}] [@option{-t}|@option{--temp-prefix} @var{prefix}] - [@option{-v}|@option{--verbose}] - [@option{-h}|@option{--help}] [@option{-V}|@option{--version}] - [@option{--no-leading-underscore}] [@option{--leading-underscore}] - [object-file @dots{}] -@c man end -@end smallexample - -@c man begin DESCRIPTION dlltool - -@command{dlltool} reads its inputs, which can come from the @option{-d} and -@option{-b} options as well as object files specified on the command -line. It then processes these inputs and if the @option{-e} option has -been specified it creates a exports file. If the @option{-l} option -has been specified it creates a library file and if the @option{-z} option -has been specified it creates a def file. Any or all of the @option{-e}, -@option{-l} and @option{-z} options can be present in one invocation of -dlltool. - -When creating a DLL, along with the source for the DLL, it is necessary -to have three other files. @command{dlltool} can help with the creation of -these files. - -The first file is a @file{.def} file which specifies which functions are -exported from the DLL, which functions the DLL imports, and so on. This -is a text file and can be created by hand, or @command{dlltool} can be used -to create it using the @option{-z} option. In this case @command{dlltool} -will scan the object files specified on its command line looking for -those functions which have been specially marked as being exported and -put entries for them in the @file{.def} file it creates. - -In order to mark a function as being exported from a DLL, it needs to -have an @option{-export:} entry in the @samp{.drectve} -section of the object file. This can be done in C by using the -asm() operator: - -@smallexample - asm (".section .drectve"); - asm (".ascii \"-export:my_func\""); - - int my_func (void) @{ @dots{} @} -@end smallexample - -The second file needed for DLL creation is an exports file. This file -is linked with the object files that make up the body of the DLL and it -handles the interface between the DLL and the outside world. This is a -binary file and it can be created by giving the @option{-e} option to -@command{dlltool} when it is creating or reading in a @file{.def} file. - -The third file needed for DLL creation is the library file that programs -will link with in order to access the functions in the DLL (an `import -library'). This file can be created by giving the @option{-l} option to -dlltool when it is creating or reading in a @file{.def} file. - -If the @option{-y} option is specified, dlltool generates a delay-import -library that can be used instead of the normal import library to allow -a program to link to the dll only as soon as an imported function is -called for the first time. The resulting executable will need to be -linked to the static delayimp library containing __delayLoadHelper2(), -which in turn will import LoadLibraryA and GetProcAddress from kernel32. - -@command{dlltool} builds the library file by hand, but it builds the -exports file by creating temporary files containing assembler statements -and then assembling these. The @option{-S} command line option can be -used to specify the path to the assembler that dlltool will use, -and the @option{-f} option can be used to pass specific flags to that -assembler. The @option{-n} can be used to prevent dlltool from deleting -these temporary assembler files when it is done, and if @option{-n} is -specified twice then this will prevent dlltool from deleting the -temporary object files it used to build the library. - -Here is an example of creating a DLL from a source file @samp{dll.c} and -also creating a program (from an object file called @samp{program.o}) -that uses that DLL: - -@smallexample - gcc -c dll.c - dlltool -e exports.o -l dll.lib dll.o - gcc dll.o exports.o -o dll.dll - gcc program.o dll.lib -o program -@end smallexample - - -@command{dlltool} may also be used to query an existing import library -to determine the name of the DLL to which it is associated. See the -description of the @option{-I} or @option{--identify} option. - -@c man end - -@c man begin OPTIONS dlltool - -The command line options have the following meanings: - -@table @env - -@item -d @var{filename} -@itemx --input-def @var{filename} -@cindex input .def file -Specifies the name of a @file{.def} file to be read in and processed. - -@item -b @var{filename} -@itemx --base-file @var{filename} -@cindex base files -Specifies the name of a base file to be read in and processed. The -contents of this file will be added to the relocation section in the -exports file generated by dlltool. - -@item -e @var{filename} -@itemx --output-exp @var{filename} -Specifies the name of the export file to be created by dlltool. - -@item -z @var{filename} -@itemx --output-def @var{filename} -Specifies the name of the @file{.def} file to be created by dlltool. - -@item -l @var{filename} -@itemx --output-lib @var{filename} -Specifies the name of the library file to be created by dlltool. - -@item -y @var{filename} -@itemx --output-delaylib @var{filename} -Specifies the name of the delay-import library file to be created by dlltool. - -@item --export-all-symbols -Treat all global and weak defined symbols found in the input object -files as symbols to be exported. There is a small list of symbols which -are not exported by default; see the @option{--no-default-excludes} -option. You may add to the list of symbols to not export by using the -@option{--exclude-symbols} option. - -@item --no-export-all-symbols -Only export symbols explicitly listed in an input @file{.def} file or in -@samp{.drectve} sections in the input object files. This is the default -behaviour. The @samp{.drectve} sections are created by @samp{dllexport} -attributes in the source code. - -@item --exclude-symbols @var{list} -Do not export the symbols in @var{list}. This is a list of symbol names -separated by comma or colon characters. The symbol names should not -contain a leading underscore. This is only meaningful when -@option{--export-all-symbols} is used. - -@item --no-default-excludes -When @option{--export-all-symbols} is used, it will by default avoid -exporting certain special symbols. The current list of symbols to avoid -exporting is @samp{DllMain@@12}, @samp{DllEntryPoint@@0}, -@samp{impure_ptr}. You may use the @option{--no-default-excludes} option -to go ahead and export these special symbols. This is only meaningful -when @option{--export-all-symbols} is used. - -@item -S @var{path} -@itemx --as @var{path} -Specifies the path, including the filename, of the assembler to be used -to create the exports file. - -@item -f @var{options} -@itemx --as-flags @var{options} -Specifies any specific command line options to be passed to the -assembler when building the exports file. This option will work even if -the @option{-S} option is not used. This option only takes one argument, -and if it occurs more than once on the command line, then later -occurrences will override earlier occurrences. So if it is necessary to -pass multiple options to the assembler they should be enclosed in -double quotes. - -@item -D @var{name} -@itemx --dll-name @var{name} -Specifies the name to be stored in the @file{.def} file as the name of -the DLL when the @option{-e} option is used. If this option is not -present, then the filename given to the @option{-e} option will be -used as the name of the DLL. - -@item -m @var{machine} -@itemx -machine @var{machine} -Specifies the type of machine for which the library file should be -built. @command{dlltool} has a built in default type, depending upon how -it was created, but this option can be used to override that. This is -normally only useful when creating DLLs for an ARM processor, when the -contents of the DLL are actually encode using Thumb instructions. - -@item -a -@itemx --add-indirect -Specifies that when @command{dlltool} is creating the exports file it -should add a section which allows the exported functions to be -referenced without using the import library. Whatever the hell that -means! - -@item -U -@itemx --add-underscore -Specifies that when @command{dlltool} is creating the exports file it -should prepend an underscore to the names of @emph{all} exported symbols. - -@item --no-leading-underscore -@item --leading-underscore -Specifies whether standard symbol should be forced to be prefixed, or -not. - -@item --add-stdcall-underscore -Specifies that when @command{dlltool} is creating the exports file it -should prepend an underscore to the names of exported @emph{stdcall} -functions. Variable names and non-stdcall function names are not modified. -This option is useful when creating GNU-compatible import libs for third -party DLLs that were built with MS-Windows tools. - -@item -k -@itemx --kill-at -Specifies that when @command{dlltool} is creating the exports file it -should not append the string @samp{@@ }. These numbers are -called ordinal numbers and they represent another way of accessing the -function in a DLL, other than by name. - -@item -A -@itemx --add-stdcall-alias -Specifies that when @command{dlltool} is creating the exports file it -should add aliases for stdcall symbols without @samp{@@ } -in addition to the symbols with @samp{@@ }. - -@item -p -@itemx --ext-prefix-alias @var{prefix} -Causes @command{dlltool} to create external aliases for all DLL -imports with the specified prefix. The aliases are created for both -external and import symbols with no leading underscore. - -@item -x -@itemx --no-idata4 -Specifies that when @command{dlltool} is creating the exports and library -files it should omit the @code{.idata4} section. This is for compatibility -with certain operating systems. - -@item --use-nul-prefixed-import-tables -Specifies that when @command{dlltool} is creating the exports and library -files it should prefix the @code{.idata4} and @code{.idata5} by zero an -element. This emulates old gnu import library generation of -@code{dlltool}. By default this option is turned off. - -@item -c -@itemx --no-idata5 -Specifies that when @command{dlltool} is creating the exports and library -files it should omit the @code{.idata5} section. This is for compatibility -with certain operating systems. - -@item -I @var{filename} -@itemx --identify @var{filename} -Specifies that @command{dlltool} should inspect the import library -indicated by @var{filename} and report, on @code{stdout}, the name(s) -of the associated DLL(s). This can be performed in addition to any -other operations indicated by the other options and arguments. -@command{dlltool} fails if the import library does not exist or is not -actually an import library. See also @option{--identify-strict}. - -@item --identify-strict -Modifies the behavior of the @option{--identify} option, such -that an error is reported if @var{filename} is associated with -more than one DLL. - -@item -i -@itemx --interwork -Specifies that @command{dlltool} should mark the objects in the library -file and exports file that it produces as supporting interworking -between ARM and Thumb code. - -@item -n -@itemx --nodelete -Makes @command{dlltool} preserve the temporary assembler files it used to -create the exports file. If this option is repeated then dlltool will -also preserve the temporary object files it uses to create the library -file. - -@item -t @var{prefix} -@itemx --temp-prefix @var{prefix} -Makes @command{dlltool} use @var{prefix} when constructing the names of -temporary assembler and object files. By default, the temp file prefix -is generated from the pid. - -@item -v -@itemx --verbose -Make dlltool describe what it is doing. - -@item -h -@itemx --help -Displays a list of command line options and then exits. - -@item -V -@itemx --version -Displays dlltool's version number and then exits. - -@end table - -@c man end - -@menu -* def file format:: The format of the dlltool @file{.def} file -@end menu - -@node def file format -@section The format of the @command{dlltool} @file{.def} file - -A @file{.def} file contains any number of the following commands: - -@table @asis - -@item @code{NAME} @var{name} @code{[ ,} @var{base} @code{]} -The result is going to be named @var{name}@code{.exe}. - -@item @code{LIBRARY} @var{name} @code{[ ,} @var{base} @code{]} -The result is going to be named @var{name}@code{.dll}. - -@item @code{EXPORTS ( ( (} @var{name1} @code{[ = } @var{name2} @code{] ) | ( } @var{name1} @code{=} @var{module-name} @code{.} @var{external-name} @code{) ) [ == } @var{its_name} @code{]} -@item @code{[} @var{integer} @code{] [ NONAME ] [ CONSTANT ] [ DATA ] [ PRIVATE ] ) *} -Declares @var{name1} as an exported symbol from the DLL, with optional -ordinal number @var{integer}, or declares @var{name1} as an alias -(forward) of the function @var{external-name} in the DLL. -If @var{its_name} is specified, this name is used as string in export table. -@var{module-name}. - -@item @code{IMPORTS ( (} @var{internal-name} @code{=} @var{module-name} @code{.} @var{integer} @code{) | [} @var{internal-name} @code{= ]} @var{module-name} @code{.} @var{external-name} @code{) [ == ) @var{its_name} @code{]} *} -Declares that @var{external-name} or the exported function whose -ordinal number is @var{integer} is to be imported from the file -@var{module-name}. If @var{internal-name} is specified then this is -the name that the imported function will be referred to in the body of -the DLL. -If @var{its_name} is specified, this name is used as string in import table. - -@item @code{DESCRIPTION} @var{string} -Puts @var{string} into the output @file{.exp} file in the -@code{.rdata} section. - -@item @code{STACKSIZE} @var{number-reserve} @code{[, } @var{number-commit} @code{]} -@item @code{HEAPSIZE} @var{number-reserve} @code{[, } @var{number-commit} @code{]} -Generates @code{--stack} or @code{--heap} -@var{number-reserve},@var{number-commit} in the output @code{.drectve} -section. The linker will see this and act upon it. - -@item @code{CODE} @var{attr} @code{+} -@item @code{DATA} @var{attr} @code{+} -@item @code{SECTIONS (} @var{section-name} @var{attr}@code{ + ) *} -Generates @code{--attr} @var{section-name} @var{attr} in the output -@code{.drectve} section, where @var{attr} is one of @code{READ}, -@code{WRITE}, @code{EXECUTE} or @code{SHARED}. The linker will see -this and act upon it. - -@end table - -@ignore -@c man begin SEEALSO dlltool -The Info pages for @file{binutils}. -@c man end -@end ignore - -@node readelf -@chapter readelf - -@cindex ELF file information -@kindex readelf - -@c man title readelf Displays information about ELF files. - -@smallexample -@c man begin SYNOPSIS readelf -readelf [@option{-a}|@option{--all}] - [@option{-h}|@option{--file-header}] - [@option{-l}|@option{--program-headers}|@option{--segments}] - [@option{-S}|@option{--section-headers}|@option{--sections}] - [@option{-g}|@option{--section-groups}] - [@option{-t}|@option{--section-details}] - [@option{-e}|@option{--headers}] - [@option{-s}|@option{--syms}|@option{--symbols}] - [@option{--dyn-syms}] - [@option{-n}|@option{--notes}] - [@option{-r}|@option{--relocs}] - [@option{-u}|@option{--unwind}] - [@option{-d}|@option{--dynamic}] - [@option{-V}|@option{--version-info}] - [@option{-A}|@option{--arch-specific}] - [@option{-D}|@option{--use-dynamic}] - [@option{-x} |@option{--hex-dump=}] - [@option{-p} |@option{--string-dump=}] - [@option{-R} |@option{--relocated-dump=}] - [@option{-c}|@option{--archive-index}] - [@option{-w[lLiaprmfFsoRt]}| - @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] - [@option{--dwarf-depth=@var{n}}] - [@option{--dwarf-start=@var{n}}] - [@option{-I}|@option{--histogram}] - [@option{-v}|@option{--version}] - [@option{-W}|@option{--wide}] - [@option{-H}|@option{--help}] - @var{elffile}@dots{} -@c man end -@end smallexample - -@c man begin DESCRIPTION readelf - -@command{readelf} displays information about one or more ELF format object -files. The options control what particular information to display. - -@var{elffile}@dots{} are the object files to be examined. 32-bit and -64-bit ELF files are supported, as are archives containing ELF files. - -This program performs a similar function to @command{objdump} but it -goes into more detail and it exists independently of the @sc{bfd} -library, so if there is a bug in @sc{bfd} then readelf will not be -affected. - -@c man end - -@c man begin OPTIONS readelf - -The long and short forms of options, shown here as alternatives, are -equivalent. At least one option besides @samp{-v} or @samp{-H} must be -given. - -@table @env -@item -a -@itemx --all -Equivalent to specifying @option{--file-header}, -@option{--program-headers}, @option{--sections}, @option{--symbols}, -@option{--relocs}, @option{--dynamic}, @option{--notes} and -@option{--version-info}. - -@item -h -@itemx --file-header -@cindex ELF file header information -Displays the information contained in the ELF header at the start of the -file. - -@item -l -@itemx --program-headers -@itemx --segments -@cindex ELF program header information -@cindex ELF segment information -Displays the information contained in the file's segment headers, if it -has any. - -@item -S -@itemx --sections -@itemx --section-headers -@cindex ELF section information -Displays the information contained in the file's section headers, if it -has any. - -@item -g -@itemx --section-groups -@cindex ELF section group information -Displays the information contained in the file's section groups, if it -has any. - -@item -t -@itemx --section-details -@cindex ELF section information -Displays the detailed section information. Implies @option{-S}. - -@item -s -@itemx --symbols -@itemx --syms -@cindex ELF symbol table information -Displays the entries in symbol table section of the file, if it has one. - -@item --dyn-syms -@cindex ELF dynamic symbol table information -Displays the entries in dynamic symbol table section of the file, if it -has one. - -@item -e -@itemx --headers -Display all the headers in the file. Equivalent to @option{-h -l -S}. - -@item -n -@itemx --notes -@cindex ELF notes -Displays the contents of the NOTE segments and/or sections, if any. - -@item -r -@itemx --relocs -@cindex ELF reloc information -Displays the contents of the file's relocation section, if it has one. - -@item -u -@itemx --unwind -@cindex unwind information -Displays the contents of the file's unwind section, if it has one. Only -the unwind sections for IA64 ELF files, as well as ARM unwind tables -(@code{.ARM.exidx} / @code{.ARM.extab}) are currently supported. - -@item -d -@itemx --dynamic -@cindex ELF dynamic section information -Displays the contents of the file's dynamic section, if it has one. - -@item -V -@itemx --version-info -@cindex ELF version sections informations -Displays the contents of the version sections in the file, it they -exist. - -@item -A -@itemx --arch-specific -Displays architecture-specific information in the file, if there -is any. - -@item -D -@itemx --use-dynamic -When displaying symbols, this option makes @command{readelf} use the -symbol hash tables in the file's dynamic section, rather than the -symbol table sections. - -@item -x -@itemx --hex-dump= -Displays the contents of the indicated section as a hexadecimal bytes. -A number identifies a particular section by index in the section table; -any other string identifies all sections with that name in the object file. - -@item -R -@itemx --relocated-dump= -Displays the contents of the indicated section as a hexadecimal -bytes. A number identifies a particular section by index in the -section table; any other string identifies all sections with that name -in the object file. The contents of the section will be relocated -before they are displayed. - -@item -p -@itemx --string-dump= -Displays the contents of the indicated section as printable strings. -A number identifies a particular section by index in the section table; -any other string identifies all sections with that name in the object file. - -@item -c -@itemx --archive-index -@cindex Archive file symbol index information -Displays the file symbol index infomation contained in the header part -of binary archives. Performs the same function as the @option{t} -command to @command{ar}, but without using the BFD library. @xref{ar}. - -@item -w[lLiaprmfFsoRt] -@itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index] -Displays the contents of the debug sections in the file, if any are -present. If one of the optional letters or words follows the switch -then only data found in those specific sections will be dumped. - -Note that there is no single letter option to display the content of -trace sections or .gdb_index. - -Note: the @option{=decodedline} option will display the interpreted -contents of a .debug_line section whereas the @option{=rawline} option -dumps the contents in a raw format. - -Note: the @option{=frames-interp} option will display the interpreted -contents of a .debug_frame section whereas the @option{=frames} option -dumps the contents in a raw format. - -Note: the output from the @option{=info} option can also be affected -by the options @option{--dwarf-depth} and @option{--dwarf-start}. - -@item --dwarf-depth=@var{n} -Limit the dump of the @code{.debug_info} section to @var{n} children. -This is only useful with @option{--debug-dump=info}. The default is -to print all DIEs; the special value 0 for @var{n} will also have this -effect. - -With a non-zero value for @var{n}, DIEs at or deeper than @var{n} -levels will not be printed. The range for @var{n} is zero-based. - -@item --dwarf-start=@var{n} -Print only DIEs beginning with the DIE numbered @var{n}. This is only -useful with @option{--debug-dump=info}. - -If specified, this option will suppress printing of any header -information and all DIEs before the DIE numbered @var{n}. Only -siblings and children of the specified DIE will be printed. - -This can be used in conjunction with @option{--dwarf-depth}. - -@item -I -@itemx --histogram -Display a histogram of bucket list lengths when displaying the contents -of the symbol tables. - -@item -v -@itemx --version -Display the version number of readelf. - -@item -W -@itemx --wide -Don't break output lines to fit into 80 columns. By default -@command{readelf} breaks section header and segment listing lines for -64-bit ELF files, so that they fit into 80 columns. This option causes -@command{readelf} to print each section header resp. each segment one a -single line, which is far more readable on terminals wider than 80 columns. - -@item -H -@itemx --help -Display the command line options understood by @command{readelf}. - -@end table - -@c man end - -@ignore -@c man begin SEEALSO readelf -objdump(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node elfedit -@chapter elfedit - -@cindex Update ELF header -@kindex elfedit - -@c man title elfedit Update the ELF header of ELF files. - -@smallexample -@c man begin SYNOPSIS elfedit -elfedit [@option{--input-mach=}@var{machine}] - [@option{--input-type=}@var{type}] - [@option{--input-osabi=}@var{osabi}] - @option{--output-mach=}@var{machine} - @option{--output-type=}@var{type} - @option{--output-osabi=}@var{osabi} - [@option{-v}|@option{--version}] - [@option{-h}|@option{--help}] - @var{elffile}@dots{} -@c man end -@end smallexample - -@c man begin DESCRIPTION elfedit - -@command{elfedit} updates the ELF header of ELF files which have -the matching ELF machine and file types. The options control how and -which fields in the ELF header should be updated. - -@var{elffile}@dots{} are the ELF files to be updated. 32-bit and -64-bit ELF files are supported, as are archives containing ELF files. -@c man end - -@c man begin OPTIONS elfedit - -The long and short forms of options, shown here as alternatives, are -equivalent. At least one of the @option{--output-mach}, -@option{--output-type} and @option{--output-osabi} options must be given. - -@table @env - -@itemx --input-mach=@var{machine} -Set the matching input ELF machine type to @var{machine}. If -@option{--input-mach} isn't specified, it will match any ELF -machine types. - -The supported ELF machine types are, @var{L1OM}, @var{K1OM} and -@var{x86-64}. - -@itemx --output-mach=@var{machine} -Change the ELF machine type in the ELF header to @var{machine}. The -supported ELF machine types are the same as @option{--input-mach}. - -@itemx --input-type=@var{type} -Set the matching input ELF file type to @var{type}. If -@option{--input-type} isn't specified, it will match any ELF file types. - -The supported ELF file types are, @var{rel}, @var{exec} and @var{dyn}. - -@itemx --output-type=@var{type} -Change the ELF file type in the ELF header to @var{type}. The -supported ELF types are the same as @option{--input-type}. - -@itemx --input-osabi=@var{osabi} -Set the matching input ELF file OSABI to @var{osabi}. If -@option{--input-osabi} isn't specified, it will match any ELF OSABIs. - -The supported ELF OSABIs are, @var{none}, @var{HPUX}, @var{NetBSD}, -@var{GNU}, @var{Linux} (alias for @var{GNU}), -@var{Solaris}, @var{AIX}, @var{Irix}, -@var{FreeBSD}, @var{TRU64}, @var{Modesto}, @var{OpenBSD}, @var{OpenVMS}, -@var{NSK}, @var{AROS} and @var{FenixOS}. - -@itemx --output-osabi=@var{osabi} -Change the ELF OSABI in the ELF header to @var{osabi}. The -supported ELF OSABI are the same as @option{--input-osabi}. - -@item -v -@itemx --version -Display the version number of @command{elfedit}. - -@item -h -@itemx --help -Display the command line options understood by @command{elfedit}. - -@end table - -@c man end - -@ignore -@c man begin SEEALSO elfedit -readelf(1), and the Info entries for @file{binutils}. -@c man end -@end ignore - -@node Common Options -@chapter Common Options - -The following command-line options are supported by all of the -programs described in this manual. - -@c man begin OPTIONS -@table @env -@include at-file.texi -@c man end - -@item --help -Display the command-line options supported by the program. - -@item --version -Display the version number of the program. - -@c man begin OPTIONS -@end table -@c man end - -@node Selecting the Target System -@chapter Selecting the Target System - -You can specify two aspects of the target system to the @sc{gnu} -binary file utilities, each in several ways: - -@itemize @bullet -@item -the target - -@item -the architecture -@end itemize - -In the following summaries, the lists of ways to specify values are in -order of decreasing precedence. The ways listed first override those -listed later. - -The commands to list valid values only list the values for which the -programs you are running were configured. If they were configured with -@option{--enable-targets=all}, the commands list most of the available -values, but a few are left out; not all targets can be configured in at -once because some of them can only be configured @dfn{native} (on hosts -with the same type as the target system). - -@menu -* Target Selection:: -* Architecture Selection:: -@end menu - -@node Target Selection -@section Target Selection - -A @dfn{target} is an object file format. A given target may be -supported for multiple architectures (@pxref{Architecture Selection}). -A target selection may also have variations for different operating -systems or architectures. - -The command to list valid target values is @samp{objdump -i} -(the first column of output contains the relevant information). - -Some sample values are: @samp{a.out-hp300bsd}, @samp{ecoff-littlemips}, -@samp{a.out-sunos-big}. - -You can also specify a target using a configuration triplet. This is -the same sort of name that is passed to @file{configure} to specify a -target. When you use a configuration triplet as an argument, it must be -fully canonicalized. You can see the canonical version of a triplet by -running the shell script @file{config.sub} which is included with the -sources. - -Some sample configuration triplets are: @samp{m68k-hp-bsd}, -@samp{mips-dec-ultrix}, @samp{sparc-sun-sunos}. - -@subheading @command{objdump} Target - -Ways to specify: - -@enumerate -@item -command line option: @option{-b} or @option{--target} - -@item -environment variable @code{GNUTARGET} - -@item -deduced from the input file -@end enumerate - -@subheading @command{objcopy} and @command{strip} Input Target - -Ways to specify: - -@enumerate -@item -command line options: @option{-I} or @option{--input-target}, or @option{-F} or @option{--target} - -@item -environment variable @code{GNUTARGET} - -@item -deduced from the input file -@end enumerate - -@subheading @command{objcopy} and @command{strip} Output Target - -Ways to specify: - -@enumerate -@item -command line options: @option{-O} or @option{--output-target}, or @option{-F} or @option{--target} - -@item -the input target (see ``@command{objcopy} and @command{strip} Input Target'' above) - -@item -environment variable @code{GNUTARGET} - -@item -deduced from the input file -@end enumerate - -@subheading @command{nm}, @command{size}, and @command{strings} Target - -Ways to specify: - -@enumerate -@item -command line option: @option{--target} - -@item -environment variable @code{GNUTARGET} - -@item -deduced from the input file -@end enumerate - -@node Architecture Selection -@section Architecture Selection - -An @dfn{architecture} is a type of @sc{cpu} on which an object file is -to run. Its name may contain a colon, separating the name of the -processor family from the name of the particular @sc{cpu}. - -The command to list valid architecture values is @samp{objdump -i} (the -second column contains the relevant information). - -Sample values: @samp{m68k:68020}, @samp{mips:3000}, @samp{sparc}. - -@subheading @command{objdump} Architecture - -Ways to specify: - -@enumerate -@item -command line option: @option{-m} or @option{--architecture} - -@item -deduced from the input file -@end enumerate - -@subheading @command{objcopy}, @command{nm}, @command{size}, @command{strings} Architecture - -Ways to specify: - -@enumerate -@item -deduced from the input file -@end enumerate - -@node Reporting Bugs -@chapter Reporting Bugs -@cindex bugs -@cindex reporting bugs - -Your bug reports play an essential role in making the binary utilities -reliable. - -Reporting a bug may help you by bringing a solution to your problem, or -it may not. But in any case the principal function of a bug report is -to help the entire community by making the next version of the binary -utilities work better. Bug reports are your contribution to their -maintenance. - -In order for a bug report to serve its purpose, you must include the -information that enables us to fix the bug. - -@menu -* Bug Criteria:: Have you found a bug? -* Bug Reporting:: How to report bugs -@end menu - -@node Bug Criteria -@section Have You Found a Bug? -@cindex bug criteria - -If you are not sure whether you have found a bug, here are some guidelines: - -@itemize @bullet -@cindex fatal signal -@cindex crash -@item -If a binary utility gets a fatal signal, for any input whatever, that is -a bug. Reliable utilities never crash. - -@cindex error on valid input -@item -If a binary utility produces an error message for valid input, that is a -bug. - -@item -If you are an experienced user of binary utilities, your suggestions for -improvement are welcome in any case. -@end itemize - -@node Bug Reporting -@section How to Report Bugs -@cindex bug reports -@cindex bugs, reporting - -A number of companies and individuals offer support for @sc{gnu} -products. If you obtained the binary utilities from a support -organization, we recommend you contact that organization first. - -You can find contact information for many support companies and -individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs -distribution. - -@ifset BUGURL -In any event, we also recommend that you send bug reports for the binary -utilities to @value{BUGURL}. -@end ifset - -The fundamental principle of reporting bugs usefully is this: -@strong{report all the facts}. If you are not sure whether to state a -fact or leave it out, state it! - -Often people omit facts because they think they know what causes the -problem and assume that some details do not matter. Thus, you might -assume that the name of a file you use in an example does not matter. -Well, probably it does not, but one cannot be sure. Perhaps the bug is -a stray memory reference which happens to fetch from the location where -that pathname is stored in memory; perhaps, if the pathname were -different, the contents of that location would fool the utility into -doing the right thing despite the bug. Play it safe and give a -specific, complete example. That is the easiest thing for you to do, -and the most helpful. - -Keep in mind that the purpose of a bug report is to enable us to fix the bug if -it is new to us. Therefore, always write your bug reports on the assumption -that the bug has not been reported previously. - -Sometimes people give a few sketchy facts and ask, ``Does this ring a -bell?'' This cannot help us fix a bug, so it is basically useless. We -respond by asking for enough details to enable us to investigate. -You might as well expedite matters by sending them to begin with. - -To enable us to fix the bug, you should include all these things: - -@itemize @bullet -@item -The version of the utility. Each utility announces it if you start it -with the @option{--version} argument. - -Without this, we will not know whether there is any point in looking for -the bug in the current version of the binary utilities. - -@item -Any patches you may have applied to the source, including any patches -made to the @code{BFD} library. - -@item -The type of machine you are using, and the operating system name and -version number. - -@item -What compiler (and its version) was used to compile the utilities---e.g. -``@code{gcc-2.7}''. - -@item -The command arguments you gave the utility to observe the bug. To -guarantee you will not omit something important, list them all. A copy -of the Makefile (or the output from make) is sufficient. - -If we were to try to guess the arguments, we would probably guess wrong -and then we might not encounter the bug. - -@item -A complete input file, or set of input files, that will reproduce the -bug. If the utility is reading an object file or files, then it is -generally most helpful to send the actual object files. - -If the source files were produced exclusively using @sc{gnu} programs -(e.g., @command{gcc}, @command{gas}, and/or the @sc{gnu} @command{ld}), then it -may be OK to send the source files rather than the object files. In -this case, be sure to say exactly what version of @command{gcc}, or -whatever, was used to produce the object files. Also say how -@command{gcc}, or whatever, was configured. - -@item -A description of what behavior you observe that you believe is -incorrect. For example, ``It gets a fatal signal.'' - -Of course, if the bug is that the utility gets a fatal signal, then we -will certainly notice it. But if the bug is incorrect output, we might -not notice unless it is glaringly wrong. You might as well not give us -a chance to make a mistake. - -Even if the problem you experience is a fatal signal, you should still -say so explicitly. Suppose something strange is going on, such as your -copy of the utility is out of sync, or you have encountered a bug in -the C library on your system. (This has happened!) Your copy might -crash and ours would not. If you told us to expect a crash, then when -ours fails to crash, we would know that the bug was not happening for -us. If you had not told us to expect a crash, then we would not be able -to draw any conclusion from our observations. - -@item -If you wish to suggest changes to the source, send us context diffs, as -generated by @command{diff} with the @option{-u}, @option{-c}, or @option{-p} -option. Always send diffs from the old file to the new file. If you -wish to discuss something in the @command{ld} source, refer to it by -context, not by line number. - -The line numbers in our development sources will not match those in your -sources. Your line numbers would convey no useful information to us. -@end itemize - -Here are some things that are not necessary: - -@itemize @bullet -@item -A description of the envelope of the bug. - -Often people who encounter a bug spend a lot of time investigating -which changes to the input file will make the bug go away and which -changes will not affect it. - -This is often time consuming and not very useful, because the way we -will find the bug is by running a single example under the debugger -with breakpoints, not by pure deduction from a series of examples. -We recommend that you save your time for something else. - -Of course, if you can find a simpler example to report @emph{instead} -of the original one, that is a convenience for us. Errors in the -output will be easier to spot, running under the debugger will take -less time, and so on. - -However, simplification is not vital; if you do not want to do this, -report the bug anyway and send us the entire test case you used. - -@item -A patch for the bug. - -A patch for the bug does help us if it is a good one. But do not omit -the necessary information, such as the test case, on the assumption that -a patch is all we need. We might see problems with your patch and decide -to fix the problem another way, or we might not understand it at all. - -Sometimes with programs as complicated as the binary utilities it is -very hard to construct an example that will make the program follow a -certain path through the code. If you do not send us the example, we -will not be able to construct one, so we will not be able to verify that -the bug is fixed. - -And if we cannot understand what bug you are trying to fix, or why your -patch should be an improvement, we will not install it. A test case will -help us to understand. - -@item -A guess about what the bug is or what it depends on. - -Such guesses are usually wrong. Even we cannot guess right about such -things without first using the debugger to find the facts. -@end itemize - -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@include fdl.texi - -@node Binutils Index -@unnumbered Binutils Index - -@printindex cp - -@bye diff --git a/contrib/binutils-2.22/binutils/doc/elfedit.1 b/contrib/binutils-2.22/binutils/doc/elfedit.1 deleted file mode 100644 index 1544944dac..0000000000 --- a/contrib/binutils-2.22/binutils/doc/elfedit.1 +++ /dev/null @@ -1,235 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "ELFEDIT 1" -.TH ELFEDIT 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -elfedit \- Update the ELF header of ELF files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -elfedit [\fB\-\-input\-mach=\fR\fImachine\fR] - [\fB\-\-input\-type=\fR\fItype\fR] - [\fB\-\-input\-osabi=\fR\fIosabi\fR] - \fB\-\-output\-mach=\fR\fImachine\fR - \fB\-\-output\-type=\fR\fItype\fR - \fB\-\-output\-osabi=\fR\fIosabi\fR - [\fB\-v\fR|\fB\-\-version\fR] - [\fB\-h\fR|\fB\-\-help\fR] - \fIelffile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBelfedit\fR updates the \s-1ELF\s0 header of \s-1ELF\s0 files which have -the matching \s-1ELF\s0 machine and file types. The options control how and -which fields in the \s-1ELF\s0 header should be updated. -.PP -\&\fIelffile\fR... are the \s-1ELF\s0 files to be updated. 32\-bit and -64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. At least one of the \fB\-\-output\-mach\fR, -\&\fB\-\-output\-type\fR and \fB\-\-output\-osabi\fR options must be given. -.IP "\fB\-\-input\-mach=\fR\fImachine\fR" 4 -.IX Item "--input-mach=machine" -Set the matching input \s-1ELF\s0 machine type to \fImachine\fR. If -\&\fB\-\-input\-mach\fR isn't specified, it will match any \s-1ELF\s0 -machine types. -.Sp -The supported \s-1ELF\s0 machine types are, \fIL1OM\fR, \fIK1OM\fR and -\&\fIx86\-64\fR. -.IP "\fB\-\-output\-mach=\fR\fImachine\fR" 4 -.IX Item "--output-mach=machine" -Change the \s-1ELF\s0 machine type in the \s-1ELF\s0 header to \fImachine\fR. The -supported \s-1ELF\s0 machine types are the same as \fB\-\-input\-mach\fR. -.IP "\fB\-\-input\-type=\fR\fItype\fR" 4 -.IX Item "--input-type=type" -Set the matching input \s-1ELF\s0 file type to \fItype\fR. If -\&\fB\-\-input\-type\fR isn't specified, it will match any \s-1ELF\s0 file types. -.Sp -The supported \s-1ELF\s0 file types are, \fIrel\fR, \fIexec\fR and \fIdyn\fR. -.IP "\fB\-\-output\-type=\fR\fItype\fR" 4 -.IX Item "--output-type=type" -Change the \s-1ELF\s0 file type in the \s-1ELF\s0 header to \fItype\fR. The -supported \s-1ELF\s0 types are the same as \fB\-\-input\-type\fR. -.IP "\fB\-\-input\-osabi=\fR\fIosabi\fR" 4 -.IX Item "--input-osabi=osabi" -Set the matching input \s-1ELF\s0 file \s-1OSABI\s0 to \fIosabi\fR. If -\&\fB\-\-input\-osabi\fR isn't specified, it will match any \s-1ELF\s0 OSABIs. -.Sp -The supported \s-1ELF\s0 OSABIs are, \fInone\fR, \fI\s-1HPUX\s0\fR, \fINetBSD\fR, -\&\fI\s-1GNU\s0\fR, \fILinux\fR (alias for \fI\s-1GNU\s0\fR), -\&\fISolaris\fR, \fI\s-1AIX\s0\fR, \fIIrix\fR, -\&\fIFreeBSD\fR, \fI\s-1TRU64\s0\fR, \fIModesto\fR, \fIOpenBSD\fR, \fIOpenVMS\fR, -\&\fI\s-1NSK\s0\fR, \fI\s-1AROS\s0\fR and \fIFenixOS\fR. -.IP "\fB\-\-output\-osabi=\fR\fIosabi\fR" 4 -.IX Item "--output-osabi=osabi" -Change the \s-1ELF\s0 \s-1OSABI\s0 in the \s-1ELF\s0 header to \fIosabi\fR. The -supported \s-1ELF\s0 \s-1OSABI\s0 are the same as \fB\-\-input\-osabi\fR. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Display the version number of \fBelfedit\fR. -.IP "\fB\-h\fR" 4 -.IX Item "-h" -.PD 0 -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -.PD -Display the command line options understood by \fBelfedit\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/fdl.texi b/contrib/binutils-2.22/binutils/doc/fdl.texi deleted file mode 100644 index 8805f1a47d..0000000000 --- a/contrib/binutils-2.22/binutils/doc/fdl.texi +++ /dev/null @@ -1,506 +0,0 @@ -@c The GNU Free Documentation License. -@center Version 1.3, 3 November 2008 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -@uref{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -@sc{ascii} without markup, Texinfo input format, La@TeX{} input -format, @acronym{SGML} or @acronym{XML} using a publicly available -@acronym{DTD}, and standard-conforming simple @acronym{HTML}, -PostScript or @acronym{PDF} designed for human modification. Examples -of transparent image formats include @acronym{PNG}, @acronym{XCF} and -@acronym{JPG}. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, @acronym{SGML} or -@acronym{XML} for which the @acronym{DTD} and/or processing tools are -not generally available, and the machine-generated @acronym{HTML}, -PostScript or @acronym{PDF} produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -The ``publisher'' means any person or entity that distributes copies -of the Document to the public. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements'', -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. - -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, receipt of a copy of some or all of the same material does -not give you any rights to use it. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation 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. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. - -@item -RELICENSING - -``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the -site means any set of copyrightable works thus published on the MMC -site. - -``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. - -``Incorporate'' means to publish or republish a Document, in whole or -in part, as part of another Document. - -An MMC is ``eligible for relicensing'' if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole -or in part into the MMC, (1) had no cover texts or invariant sections, -and (2) were thus incorporated prior to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. - -@end enumerate - -@page -@heading ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.'' line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Texts - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: - diff --git a/contrib/binutils-2.22/binutils/doc/nm.1 b/contrib/binutils-2.22/binutils/doc/nm.1 deleted file mode 100644 index e5941c7765..0000000000 --- a/contrib/binutils-2.22/binutils/doc/nm.1 +++ /dev/null @@ -1,518 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "NM 1" -.TH NM 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -nm \- list symbols from object files -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -nm [\fB\-a\fR|\fB\-\-debug\-syms\fR] - [\fB\-g\fR|\fB\-\-extern\-only\fR][\fB\-\-plugin\fR \fIname\fR] - [\fB\-B\fR] [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] [\fB\-D\fR|\fB\-\-dynamic\fR] - [\fB\-S\fR|\fB\-\-print\-size\fR] [\fB\-s\fR|\fB\-\-print\-armap\fR] - [\fB\-A\fR|\fB\-o\fR|\fB\-\-print\-file\-name\fR][\fB\-\-special\-syms\fR] - [\fB\-n\fR|\fB\-v\fR|\fB\-\-numeric\-sort\fR] [\fB\-p\fR|\fB\-\-no\-sort\fR] - [\fB\-r\fR|\fB\-\-reverse\-sort\fR] [\fB\-\-size\-sort\fR] [\fB\-u\fR|\fB\-\-undefined\-only\fR] - [\fB\-t\fR \fIradix\fR|\fB\-\-radix=\fR\fIradix\fR] [\fB\-P\fR|\fB\-\-portability\fR] - [\fB\-\-target=\fR\fIbfdname\fR] [\fB\-f\fR\fIformat\fR|\fB\-\-format=\fR\fIformat\fR] - [\fB\-\-defined\-only\fR] [\fB\-l\fR|\fB\-\-line\-numbers\fR] [\fB\-\-no\-demangle\fR] - [\fB\-V\fR|\fB\-\-version\fR] [\fB\-X 32_64\fR] [\fB\-\-help\fR] [\fIobjfile\fR...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\s-1GNU\s0 \fBnm\fR lists the symbols from object files \fIobjfile\fR.... -If no object files are listed as arguments, \fBnm\fR assumes the file -\&\fIa.out\fR. -.PP -For each symbol, \fBnm\fR shows: -.IP "\(bu" 4 -The symbol value, in the radix selected by options (see below), or -hexadecimal by default. -.IP "\(bu" 4 -The symbol type. At least the following types are used; others are, as -well, depending on the object file format. If lowercase, the symbol is -usually local; if uppercase, the symbol is global (external). There -are however a few lowercase symbols that are shown for special global -symbols (\f(CW\*(C`u\*(C'\fR, \f(CW\*(C`v\*(C'\fR and \f(CW\*(C`w\*(C'\fR). -.RS 4 -.ie n .IP """A""" 4 -.el .IP "\f(CWA\fR" 4 -.IX Item "A" -The symbol's value is absolute, and will not be changed by further -linking. -.ie n .IP """B""" 4 -.el .IP "\f(CWB\fR" 4 -.IX Item "B" -.PD 0 -.ie n .IP """b""" 4 -.el .IP "\f(CWb\fR" 4 -.IX Item "b" -.PD -The symbol is in the uninitialized data section (known as \s-1BSS\s0). -.ie n .IP """C""" 4 -.el .IP "\f(CWC\fR" 4 -.IX Item "C" -The symbol is common. Common symbols are uninitialized data. When -linking, multiple common symbols may appear with the same name. If the -symbol is defined anywhere, the common symbols are treated as undefined -references. -.ie n .IP """D""" 4 -.el .IP "\f(CWD\fR" 4 -.IX Item "D" -.PD 0 -.ie n .IP """d""" 4 -.el .IP "\f(CWd\fR" 4 -.IX Item "d" -.PD -The symbol is in the initialized data section. -.ie n .IP """G""" 4 -.el .IP "\f(CWG\fR" 4 -.IX Item "G" -.PD 0 -.ie n .IP """g""" 4 -.el .IP "\f(CWg\fR" 4 -.IX Item "g" -.PD -The symbol is in an initialized data section for small objects. Some -object file formats permit more efficient access to small data objects, -such as a global int variable as opposed to a large global array. -.ie n .IP """i""" 4 -.el .IP "\f(CWi\fR" 4 -.IX Item "i" -For \s-1PE\s0 format files this indicates that the symbol is in a section -specific to the implementation of DLLs. For \s-1ELF\s0 format files this -indicates that the symbol is an indirect function. This is a \s-1GNU\s0 -extension to the standard set of \s-1ELF\s0 symbol types. It indicates a -symbol which if referenced by a relocation does not evaluate to its -address, but instead must be invoked at runtime. The runtime -execution will then return the value to be used in the relocation. -.ie n .IP """N""" 4 -.el .IP "\f(CWN\fR" 4 -.IX Item "N" -The symbol is a debugging symbol. -.ie n .IP """p""" 4 -.el .IP "\f(CWp\fR" 4 -.IX Item "p" -The symbols is in a stack unwind section. -.ie n .IP """R""" 4 -.el .IP "\f(CWR\fR" 4 -.IX Item "R" -.PD 0 -.ie n .IP """r""" 4 -.el .IP "\f(CWr\fR" 4 -.IX Item "r" -.PD -The symbol is in a read only data section. -.ie n .IP """S""" 4 -.el .IP "\f(CWS\fR" 4 -.IX Item "S" -.PD 0 -.ie n .IP """s""" 4 -.el .IP "\f(CWs\fR" 4 -.IX Item "s" -.PD -The symbol is in an uninitialized data section for small objects. -.ie n .IP """T""" 4 -.el .IP "\f(CWT\fR" 4 -.IX Item "T" -.PD 0 -.ie n .IP """t""" 4 -.el .IP "\f(CWt\fR" 4 -.IX Item "t" -.PD -The symbol is in the text (code) section. -.ie n .IP """U""" 4 -.el .IP "\f(CWU\fR" 4 -.IX Item "U" -The symbol is undefined. -.ie n .IP """u""" 4 -.el .IP "\f(CWu\fR" 4 -.IX Item "u" -The symbol is a unique global symbol. This is a \s-1GNU\s0 extension to the -standard set of \s-1ELF\s0 symbol bindings. For such a symbol the dynamic linker -will make sure that in the entire process there is just one symbol with -this name and type in use. -.ie n .IP """V""" 4 -.el .IP "\f(CWV\fR" 4 -.IX Item "V" -.PD 0 -.ie n .IP """v""" 4 -.el .IP "\f(CWv\fR" 4 -.IX Item "v" -.PD -The symbol is a weak object. When a weak defined symbol is linked with -a normal defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the weak symbol becomes zero with no error. On some -systems, uppercase indicates that a default value has been specified. -.ie n .IP """W""" 4 -.el .IP "\f(CWW\fR" 4 -.IX Item "W" -.PD 0 -.ie n .IP """w""" 4 -.el .IP "\f(CWw\fR" 4 -.IX Item "w" -.PD -The symbol is a weak symbol that has not been specifically tagged as a -weak object symbol. When a weak defined symbol is linked with a normal -defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the symbol is determined in a system-specific manner without -error. On some systems, uppercase indicates that a default value has been -specified. -.ie n .IP """\-""" 4 -.el .IP "\f(CW\-\fR" 4 -.IX Item "-" -The symbol is a stabs symbol in an a.out object file. In this case, the -next values printed are the stabs other field, the stabs desc field, and -the stab type. Stabs symbols are used to hold debugging information. -.ie n .IP """?""" 4 -.el .IP "\f(CW?\fR" 4 -.IX Item "?" -The symbol type is unknown, or object file format specific. -.RE -.RS 4 -.RE -.IP "\(bu" 4 -The symbol name. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-o\fR" 4 -.IX Item "-o" -.IP "\fB\-\-print\-file\-name\fR" 4 -.IX Item "--print-file-name" -.PD -Precede each symbol by the name of the input file (or archive member) -in which it was found, rather than identifying the input file once only, -before all of its symbols. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-debug\-syms\fR" 4 -.IX Item "--debug-syms" -.PD -Display all symbols, even debugger-only symbols; normally these are not -listed. -.IP "\fB\-B\fR" 4 -.IX Item "-B" -The same as \fB\-\-format=bsd\fR (for compatibility with the \s-1MIPS\s0 \fBnm\fR). -.IP "\fB\-C\fR" 4 -.IX Item "-C" -.PD 0 -.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 -.IX Item "--demangle[=style]" -.PD -Decode (\fIdemangle\fR) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes \*(C+ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. -.IP "\fB\-\-no\-demangle\fR" 4 -.IX Item "--no-demangle" -Do not demangle low-level symbol names. This is the default. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -.PD 0 -.IP "\fB\-\-dynamic\fR" 4 -.IX Item "--dynamic" -.PD -Display the dynamic symbols rather than the normal symbols. This is -only meaningful for dynamic objects, such as certain types of shared -libraries. -.IP "\fB\-f\fR \fIformat\fR" 4 -.IX Item "-f format" -.PD 0 -.IP "\fB\-\-format=\fR\fIformat\fR" 4 -.IX Item "--format=format" -.PD -Use the output format \fIformat\fR, which can be \f(CW\*(C`bsd\*(C'\fR, -\&\f(CW\*(C`sysv\*(C'\fR, or \f(CW\*(C`posix\*(C'\fR. The default is \f(CW\*(C`bsd\*(C'\fR. -Only the first character of \fIformat\fR is significant; it can be -either upper or lower case. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-extern\-only\fR" 4 -.IX Item "--extern-only" -.PD -Display only external symbols. -.IP "\fB\-\-plugin\fR \fIname\fR" 4 -.IX Item "--plugin name" -Load the plugin called \fIname\fR to add support for extra target -types. This option is only available if the toolchain has been built -with plugin support enabled. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -.PD 0 -.IP "\fB\-\-line\-numbers\fR" 4 -.IX Item "--line-numbers" -.PD -For each symbol, use debugging information to try to find a filename and -line number. For a defined symbol, look for the line number of the -address of the symbol. For an undefined symbol, look for the line -number of a relocation entry which refers to the symbol. If line number -information can be found, print it after the other symbol information. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -.PD 0 -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.IP "\fB\-\-numeric\-sort\fR" 4 -.IX Item "--numeric-sort" -.PD -Sort symbols numerically by their addresses, rather than alphabetically -by their names. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-no\-sort\fR" 4 -.IX Item "--no-sort" -.PD -Do not bother to sort the symbols in any order; print them in the order -encountered. -.IP "\fB\-P\fR" 4 -.IX Item "-P" -.PD 0 -.IP "\fB\-\-portability\fR" 4 -.IX Item "--portability" -.PD -Use the \s-1POSIX\s0.2 standard output format instead of the default format. -Equivalent to \fB\-f posix\fR. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-print\-size\fR" 4 -.IX Item "--print-size" -.PD -Print both value and size of defined symbols for the \f(CW\*(C`bsd\*(C'\fR output style. -This option has no effect for object formats that do not record symbol -sizes, unless \fB\-\-size\-sort\fR is also used in which case a -calculated size is displayed. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-print\-armap\fR" 4 -.IX Item "--print-armap" -.PD -When listing symbols from archive members, include the index: a mapping -(stored in the archive by \fBar\fR or \fBranlib\fR) of which modules -contain definitions for which names. -.IP "\fB\-r\fR" 4 -.IX Item "-r" -.PD 0 -.IP "\fB\-\-reverse\-sort\fR" 4 -.IX Item "--reverse-sort" -.PD -Reverse the order of the sort (whether numeric or alphabetic); let the -last come first. -.IP "\fB\-\-size\-sort\fR" 4 -.IX Item "--size-sort" -Sort symbols by size. The size is computed as the difference between -the value of the symbol and the value of the symbol with the next higher -value. If the \f(CW\*(C`bsd\*(C'\fR output format is used the size of the symbol -is printed, rather than the value, and \fB\-S\fR must be used in order -both size and value to be printed. -.IP "\fB\-\-special\-syms\fR" 4 -.IX Item "--special-syms" -Display symbols which have a target-specific special meaning. These -symbols are usually used by the target for some special processing and -are not normally helpful when included included in the normal symbol -lists. For example for \s-1ARM\s0 targets this option would skip the mapping -symbols used to mark transitions between \s-1ARM\s0 code, \s-1THUMB\s0 code and -data. -.IP "\fB\-t\fR \fIradix\fR" 4 -.IX Item "-t radix" -.PD 0 -.IP "\fB\-\-radix=\fR\fIradix\fR" 4 -.IX Item "--radix=radix" -.PD -Use \fIradix\fR as the radix for printing the symbol values. It must be -\&\fBd\fR for decimal, \fBo\fR for octal, or \fBx\fR for hexadecimal. -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -Specify an object code format other than your system's default format. -.IP "\fB\-u\fR" 4 -.IX Item "-u" -.PD 0 -.IP "\fB\-\-undefined\-only\fR" 4 -.IX Item "--undefined-only" -.PD -Display only undefined symbols (those external to each object file). -.IP "\fB\-\-defined\-only\fR" 4 -.IX Item "--defined-only" -Display only defined symbols for each object file. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number of \fBnm\fR and exit. -.IP "\fB\-X\fR" 4 -.IX Item "-X" -This option is ignored for compatibility with the \s-1AIX\s0 version of -\&\fBnm\fR. It takes one parameter which must be the string -\&\fB32_64\fR. The default mode of \s-1AIX\s0 \fBnm\fR corresponds -to \fB\-X 32\fR, which is not supported by \s-1GNU\s0 \fBnm\fR. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of the options to \fBnm\fR and exit. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/objcopy.1 b/contrib/binutils-2.22/binutils/doc/objcopy.1 deleted file mode 100644 index 979f85d31c..0000000000 --- a/contrib/binutils-2.22/binutils/doc/objcopy.1 +++ /dev/null @@ -1,962 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "OBJCOPY 1" -.TH OBJCOPY 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -objcopy \- copy and translate object files -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -objcopy [\fB\-F\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-I\fR \fIbfdname\fR|\fB\-\-input\-target=\fR\fIbfdname\fR] - [\fB\-O\fR \fIbfdname\fR|\fB\-\-output\-target=\fR\fIbfdname\fR] - [\fB\-B\fR \fIbfdarch\fR|\fB\-\-binary\-architecture=\fR\fIbfdarch\fR] - [\fB\-S\fR|\fB\-\-strip\-all\fR] - [\fB\-g\fR|\fB\-\-strip\-debug\fR] - [\fB\-K\fR \fIsymbolname\fR|\fB\-\-keep\-symbol=\fR\fIsymbolname\fR] - [\fB\-N\fR \fIsymbolname\fR|\fB\-\-strip\-symbol=\fR\fIsymbolname\fR] - [\fB\-\-strip\-unneeded\-symbol=\fR\fIsymbolname\fR] - [\fB\-G\fR \fIsymbolname\fR|\fB\-\-keep\-global\-symbol=\fR\fIsymbolname\fR] - [\fB\-\-localize\-hidden\fR] - [\fB\-L\fR \fIsymbolname\fR|\fB\-\-localize\-symbol=\fR\fIsymbolname\fR] - [\fB\-\-globalize\-symbol=\fR\fIsymbolname\fR] - [\fB\-W\fR \fIsymbolname\fR|\fB\-\-weaken\-symbol=\fR\fIsymbolname\fR] - [\fB\-w\fR|\fB\-\-wildcard\fR] - [\fB\-x\fR|\fB\-\-discard\-all\fR] - [\fB\-X\fR|\fB\-\-discard\-locals\fR] - [\fB\-b\fR \fIbyte\fR|\fB\-\-byte=\fR\fIbyte\fR] - [\fB\-i\fR [\fIbreadth\fR]|\fB\-\-interleave\fR[=\fIbreadth\fR]] - [\fB\-\-interleave\-width=\fR\fIwidth\fR] - [\fB\-j\fR \fIsectionname\fR|\fB\-\-only\-section=\fR\fIsectionname\fR] - [\fB\-R\fR \fIsectionname\fR|\fB\-\-remove\-section=\fR\fIsectionname\fR] - [\fB\-p\fR|\fB\-\-preserve\-dates\fR] - [\fB\-\-debugging\fR] - [\fB\-\-gap\-fill=\fR\fIval\fR] - [\fB\-\-pad\-to=\fR\fIaddress\fR] - [\fB\-\-set\-start=\fR\fIval\fR] - [\fB\-\-adjust\-start=\fR\fIincr\fR] - [\fB\-\-change\-addresses=\fR\fIincr\fR] - [\fB\-\-change\-section\-address\fR \fIsection\fR{=,+,\-}\fIval\fR] - [\fB\-\-change\-section\-lma\fR \fIsection\fR{=,+,\-}\fIval\fR] - [\fB\-\-change\-section\-vma\fR \fIsection\fR{=,+,\-}\fIval\fR] - [\fB\-\-change\-warnings\fR] [\fB\-\-no\-change\-warnings\fR] - [\fB\-\-set\-section\-flags\fR \fIsection\fR=\fIflags\fR] - [\fB\-\-add\-section\fR \fIsectionname\fR=\fIfilename\fR] - [\fB\-\-rename\-section\fR \fIoldname\fR=\fInewname\fR[,\fIflags\fR]] - [\fB\-\-long\-section\-names\fR {enable,disable,keep}] - [\fB\-\-change\-leading\-char\fR] [\fB\-\-remove\-leading\-char\fR] - [\fB\-\-reverse\-bytes=\fR\fInum\fR] - [\fB\-\-srec\-len=\fR\fIival\fR] [\fB\-\-srec\-forceS3\fR] - [\fB\-\-redefine\-sym\fR \fIold\fR=\fInew\fR] - [\fB\-\-redefine\-syms=\fR\fIfilename\fR] - [\fB\-\-weaken\fR] - [\fB\-\-keep\-symbols=\fR\fIfilename\fR] - [\fB\-\-strip\-symbols=\fR\fIfilename\fR] - [\fB\-\-strip\-unneeded\-symbols=\fR\fIfilename\fR] - [\fB\-\-keep\-global\-symbols=\fR\fIfilename\fR] - [\fB\-\-localize\-symbols=\fR\fIfilename\fR] - [\fB\-\-globalize\-symbols=\fR\fIfilename\fR] - [\fB\-\-weaken\-symbols=\fR\fIfilename\fR] - [\fB\-\-alt\-machine\-code=\fR\fIindex\fR] - [\fB\-\-prefix\-symbols=\fR\fIstring\fR] - [\fB\-\-prefix\-sections=\fR\fIstring\fR] - [\fB\-\-prefix\-alloc\-sections=\fR\fIstring\fR] - [\fB\-\-add\-gnu\-debuglink=\fR\fIpath-to-file\fR] - [\fB\-\-keep\-file\-symbols\fR] - [\fB\-\-only\-keep\-debug\fR] - [\fB\-\-extract\-symbol\fR] - [\fB\-\-writable\-text\fR] - [\fB\-\-readonly\-text\fR] - [\fB\-\-pure\fR] - [\fB\-\-impure\fR] - [\fB\-\-file\-alignment=\fR\fInum\fR] - [\fB\-\-heap=\fR\fIsize\fR] - [\fB\-\-image\-base=\fR\fIaddress\fR] - [\fB\-\-section\-alignment=\fR\fInum\fR] - [\fB\-\-stack=\fR\fIsize\fR] - [\fB\-\-subsystem=\fR\fIwhich\fR:\fImajor\fR.\fIminor\fR] - [\fB\-\-compress\-debug\-sections\fR] - [\fB\-\-decompress\-debug\-sections\fR] - [\fB\-\-dwarf\-depth=\fR\fIn\fR] - [\fB\-\-dwarf\-start=\fR\fIn\fR] - [\fB\-v\fR|\fB\-\-verbose\fR] - [\fB\-V\fR|\fB\-\-version\fR] - [\fB\-\-help\fR] [\fB\-\-info\fR] - \fIinfile\fR [\fIoutfile\fR] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -The \s-1GNU\s0 \fBobjcopy\fR utility copies the contents of an object -file to another. \fBobjcopy\fR uses the \s-1GNU\s0 \s-1BFD\s0 Library to -read and write the object files. It can write the destination object -file in a format different from that of the source object file. The -exact behavior of \fBobjcopy\fR is controlled by command-line options. -Note that \fBobjcopy\fR should be able to copy a fully linked file -between any two formats. However, copying a relocatable object file -between any two formats may not work as expected. -.PP -\&\fBobjcopy\fR creates temporary files to do its translations and -deletes them afterward. \fBobjcopy\fR uses \s-1BFD\s0 to do all its -translation work; it has access to all the formats described in \s-1BFD\s0 -and thus is able to recognize most formats without being told -explicitly. -.PP -\&\fBobjcopy\fR can be used to generate S\-records by using an output -target of \fBsrec\fR (e.g., use \fB\-O srec\fR). -.PP -\&\fBobjcopy\fR can be used to generate a raw binary file by using an -output target of \fBbinary\fR (e.g., use \fB\-O binary\fR). When -\&\fBobjcopy\fR generates a raw binary file, it will essentially produce -a memory dump of the contents of the input object file. All symbols and -relocation information will be discarded. The memory dump will start at -the load address of the lowest section copied into the output file. -.PP -When generating an S\-record or a raw binary file, it may be helpful to -use \fB\-S\fR to remove sections containing debugging information. In -some cases \fB\-R\fR will be useful to remove sections which contain -information that is not needed by the binary file. -.PP -Note\-\-\-\fBobjcopy\fR is not able to change the endianness of its input -files. If the input format has an endianness (some formats do not), -\&\fBobjcopy\fR can only copy the inputs into file formats that have the -same endianness or which have no endianness (e.g., \fBsrec\fR). -(However, see the \fB\-\-reverse\-bytes\fR option.) -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fIinfile\fR" 4 -.IX Item "infile" -.PD 0 -.IP "\fIoutfile\fR" 4 -.IX Item "outfile" -.PD -The input and output files, respectively. -If you do not specify \fIoutfile\fR, \fBobjcopy\fR creates a -temporary file and destructively renames the result with -the name of \fIinfile\fR. -.IP "\fB\-I\fR \fIbfdname\fR" 4 -.IX Item "-I bfdname" -.PD 0 -.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 -.IX Item "--input-target=bfdname" -.PD -Consider the source file's object format to be \fIbfdname\fR, rather than -attempting to deduce it. -.IP "\fB\-O\fR \fIbfdname\fR" 4 -.IX Item "-O bfdname" -.PD 0 -.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 -.IX Item "--output-target=bfdname" -.PD -Write the output file using the object format \fIbfdname\fR. -.IP "\fB\-F\fR \fIbfdname\fR" 4 -.IX Item "-F bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Use \fIbfdname\fR as the object format for both the input and the output -file; i.e., simply transfer data from source to destination with no -translation. -.IP "\fB\-B\fR \fIbfdarch\fR" 4 -.IX Item "-B bfdarch" -.PD 0 -.IP "\fB\-\-binary\-architecture=\fR\fIbfdarch\fR" 4 -.IX Item "--binary-architecture=bfdarch" -.PD -Useful when transforming a architecture-less input file into an object file. -In this case the output architecture can be set to \fIbfdarch\fR. This -option will be ignored if the input file has a known \fIbfdarch\fR. You -can access this binary data inside a program by referencing the special -symbols that are created by the conversion process. These symbols are -called _binary_\fIobjfile\fR_start, _binary_\fIobjfile\fR_end and -_binary_\fIobjfile\fR_size. e.g. you can transform a picture file into -an object file and then access it in your code using these symbols. -.IP "\fB\-j\fR \fIsectionname\fR" 4 -.IX Item "-j sectionname" -.PD 0 -.IP "\fB\-\-only\-section=\fR\fIsectionname\fR" 4 -.IX Item "--only-section=sectionname" -.PD -Copy only the named section from the input file to the output file. -This option may be given more than once. Note that using this option -inappropriately may make the output file unusable. -.IP "\fB\-R\fR \fIsectionname\fR" 4 -.IX Item "-R sectionname" -.PD 0 -.IP "\fB\-\-remove\-section=\fR\fIsectionname\fR" 4 -.IX Item "--remove-section=sectionname" -.PD -Remove any section named \fIsectionname\fR from the output file. This -option may be given more than once. Note that using this option -inappropriately may make the output file unusable. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-strip\-all\fR" 4 -.IX Item "--strip-all" -.PD -Do not copy relocation and symbol information from the source file. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-strip\-debug\fR" 4 -.IX Item "--strip-debug" -.PD -Do not copy debugging symbols or sections from the source file. -.IP "\fB\-\-strip\-unneeded\fR" 4 -.IX Item "--strip-unneeded" -Strip all symbols that are not needed for relocation processing. -.IP "\fB\-K\fR \fIsymbolname\fR" 4 -.IX Item "-K symbolname" -.PD 0 -.IP "\fB\-\-keep\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--keep-symbol=symbolname" -.PD -When stripping symbols, keep symbol \fIsymbolname\fR even if it would -normally be stripped. This option may be given more than once. -.IP "\fB\-N\fR \fIsymbolname\fR" 4 -.IX Item "-N symbolname" -.PD 0 -.IP "\fB\-\-strip\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--strip-symbol=symbolname" -.PD -Do not copy symbol \fIsymbolname\fR from the source file. This option -may be given more than once. -.IP "\fB\-\-strip\-unneeded\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--strip-unneeded-symbol=symbolname" -Do not copy symbol \fIsymbolname\fR from the source file unless it is needed -by a relocation. This option may be given more than once. -.IP "\fB\-G\fR \fIsymbolname\fR" 4 -.IX Item "-G symbolname" -.PD 0 -.IP "\fB\-\-keep\-global\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--keep-global-symbol=symbolname" -.PD -Keep only symbol \fIsymbolname\fR global. Make all other symbols local -to the file, so that they are not visible externally. This option may -be given more than once. -.IP "\fB\-\-localize\-hidden\fR" 4 -.IX Item "--localize-hidden" -In an \s-1ELF\s0 object, mark all symbols that have hidden or internal visibility -as local. This option applies on top of symbol-specific localization options -such as \fB\-L\fR. -.IP "\fB\-L\fR \fIsymbolname\fR" 4 -.IX Item "-L symbolname" -.PD 0 -.IP "\fB\-\-localize\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--localize-symbol=symbolname" -.PD -Make symbol \fIsymbolname\fR local to the file, so that it is not -visible externally. This option may be given more than once. -.IP "\fB\-W\fR \fIsymbolname\fR" 4 -.IX Item "-W symbolname" -.PD 0 -.IP "\fB\-\-weaken\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--weaken-symbol=symbolname" -.PD -Make symbol \fIsymbolname\fR weak. This option may be given more than once. -.IP "\fB\-\-globalize\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--globalize-symbol=symbolname" -Give symbol \fIsymbolname\fR global scoping so that it is visible -outside of the file in which it is defined. This option may be given -more than once. -.IP "\fB\-w\fR" 4 -.IX Item "-w" -.PD 0 -.IP "\fB\-\-wildcard\fR" 4 -.IX Item "--wildcard" -.PD -Permit regular expressions in \fIsymbolname\fRs used in other command -line options. The question mark (?), asterisk (*), backslash (\e) and -square brackets ([]) operators can be used anywhere in the symbol -name. If the first character of the symbol name is the exclamation -point (!) then the sense of the switch is reversed for that symbol. -For example: -.Sp -.Vb 1 -\& \-w \-W !foo \-W fo* -.Ve -.Sp -would cause objcopy to weaken all symbols that start with \*(L"fo\*(R" -except for the symbol \*(L"foo\*(R". -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.PD 0 -.IP "\fB\-\-discard\-all\fR" 4 -.IX Item "--discard-all" -.PD -Do not copy non-global symbols from the source file. -.IP "\fB\-X\fR" 4 -.IX Item "-X" -.PD 0 -.IP "\fB\-\-discard\-locals\fR" 4 -.IX Item "--discard-locals" -.PD -Do not copy compiler-generated local symbols. -(These usually start with \fBL\fR or \fB.\fR.) -.IP "\fB\-b\fR \fIbyte\fR" 4 -.IX Item "-b byte" -.PD 0 -.IP "\fB\-\-byte=\fR\fIbyte\fR" 4 -.IX Item "--byte=byte" -.PD -If interleaving has been enabled via the \fB\-\-interleave\fR option -then start the range of bytes to keep at the \fIbyte\fRth byte. -\&\fIbyte\fR can be in the range from 0 to \fIbreadth\fR\-1, where -\&\fIbreadth\fR is the value given by the \fB\-\-interleave\fR option. -.IP "\fB\-i [\fR\fIbreadth\fR\fB]\fR" 4 -.IX Item "-i [breadth]" -.PD 0 -.IP "\fB\-\-interleave[=\fR\fIbreadth\fR\fB]\fR" 4 -.IX Item "--interleave[=breadth]" -.PD -Only copy a range out of every \fIbreadth\fR bytes. (Header data is -not affected). Select which byte in the range begins the copy with -the \fB\-\-byte\fR option. Select the width of the range with the -\&\fB\-\-interleave\-width\fR option. -.Sp -This option is useful for creating files to program \s-1ROM\s0. It is -typically used with an \f(CW\*(C`srec\*(C'\fR output target. Note that -\&\fBobjcopy\fR will complain if you do not specify the -\&\fB\-\-byte\fR option as well. -.Sp -The default interleave breadth is 4, so with \fB\-\-byte\fR set to 0, -\&\fBobjcopy\fR would copy the first byte out of every four bytes -from the input to the output. -.IP "\fB\-\-interleave\-width=\fR\fIwidth\fR" 4 -.IX Item "--interleave-width=width" -When used with the \fB\-\-interleave\fR option, copy \fIwidth\fR -bytes at a time. The start of the range of bytes to be copied is set -by the \fB\-\-byte\fR option, and the extent of the range is set with -the \fB\-\-interleave\fR option. -.Sp -The default value for this option is 1. The value of \fIwidth\fR plus -the \fIbyte\fR value set by the \fB\-\-byte\fR option must not exceed -the interleave breadth set by the \fB\-\-interleave\fR option. -.Sp -This option can be used to create images for two 16\-bit flashes interleaved -in a 32\-bit bus by passing \fB\-b 0 \-i 4 \-\-interleave\-width=2\fR -and \fB\-b 2 \-i 4 \-\-interleave\-width=2\fR to two \fBobjcopy\fR -commands. If the input was '12345678' then the outputs would be -\&'1256' and '3478' respectively. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-preserve\-dates\fR" 4 -.IX Item "--preserve-dates" -.PD -Set the access and modification dates of the output file to be the same -as those of the input file. -.IP "\fB\-\-debugging\fR" 4 -.IX Item "--debugging" -Convert debugging information, if possible. This is not the default -because only certain debugging formats are supported, and the -conversion process can be time consuming. -.IP "\fB\-\-gap\-fill\fR \fIval\fR" 4 -.IX Item "--gap-fill val" -Fill gaps between sections with \fIval\fR. This operation applies to -the \fIload address\fR (\s-1LMA\s0) of the sections. It is done by increasing -the size of the section with the lower address, and filling in the extra -space created with \fIval\fR. -.IP "\fB\-\-pad\-to\fR \fIaddress\fR" 4 -.IX Item "--pad-to address" -Pad the output file up to the load address \fIaddress\fR. This is -done by increasing the size of the last section. The extra space is -filled in with the value specified by \fB\-\-gap\-fill\fR (default zero). -.IP "\fB\-\-set\-start\fR \fIval\fR" 4 -.IX Item "--set-start val" -Set the start address of the new file to \fIval\fR. Not all object file -formats support setting the start address. -.IP "\fB\-\-change\-start\fR \fIincr\fR" 4 -.IX Item "--change-start incr" -.PD 0 -.IP "\fB\-\-adjust\-start\fR \fIincr\fR" 4 -.IX Item "--adjust-start incr" -.PD -Change the start address by adding \fIincr\fR. Not all object file -formats support setting the start address. -.IP "\fB\-\-change\-addresses\fR \fIincr\fR" 4 -.IX Item "--change-addresses incr" -.PD 0 -.IP "\fB\-\-adjust\-vma\fR \fIincr\fR" 4 -.IX Item "--adjust-vma incr" -.PD -Change the \s-1VMA\s0 and \s-1LMA\s0 addresses of all sections, as well as the start -address, by adding \fIincr\fR. Some object file formats do not permit -section addresses to be changed arbitrarily. Note that this does not -relocate the sections; if the program expects sections to be loaded at a -certain address, and this option is used to change the sections such -that they are loaded at a different address, the program may fail. -.IP "\fB\-\-change\-section\-address\fR \fIsection\fR\fB{=,+,\-}\fR\fIval\fR" 4 -.IX Item "--change-section-address section{=,+,-}val" -.PD 0 -.IP "\fB\-\-adjust\-section\-vma\fR \fIsection\fR\fB{=,+,\-}\fR\fIval\fR" 4 -.IX Item "--adjust-section-vma section{=,+,-}val" -.PD -Set or change both the \s-1VMA\s0 address and the \s-1LMA\s0 address of the named -\&\fIsection\fR. If \fB=\fR is used, the section address is set to -\&\fIval\fR. Otherwise, \fIval\fR is added to or subtracted from the -section address. See the comments under \fB\-\-change\-addresses\fR, -above. If \fIsection\fR does not exist in the input file, a warning will -be issued, unless \fB\-\-no\-change\-warnings\fR is used. -.IP "\fB\-\-change\-section\-lma\fR \fIsection\fR\fB{=,+,\-}\fR\fIval\fR" 4 -.IX Item "--change-section-lma section{=,+,-}val" -Set or change the \s-1LMA\s0 address of the named \fIsection\fR. The \s-1LMA\s0 -address is the address where the section will be loaded into memory at -program load time. Normally this is the same as the \s-1VMA\s0 address, which -is the address of the section at program run time, but on some systems, -especially those where a program is held in \s-1ROM\s0, the two can be -different. If \fB=\fR is used, the section address is set to -\&\fIval\fR. Otherwise, \fIval\fR is added to or subtracted from the -section address. See the comments under \fB\-\-change\-addresses\fR, -above. If \fIsection\fR does not exist in the input file, a warning -will be issued, unless \fB\-\-no\-change\-warnings\fR is used. -.IP "\fB\-\-change\-section\-vma\fR \fIsection\fR\fB{=,+,\-}\fR\fIval\fR" 4 -.IX Item "--change-section-vma section{=,+,-}val" -Set or change the \s-1VMA\s0 address of the named \fIsection\fR. The \s-1VMA\s0 -address is the address where the section will be located once the -program has started executing. Normally this is the same as the \s-1LMA\s0 -address, which is the address where the section will be loaded into -memory, but on some systems, especially those where a program is held in -\&\s-1ROM\s0, the two can be different. If \fB=\fR is used, the section address -is set to \fIval\fR. Otherwise, \fIval\fR is added to or subtracted -from the section address. See the comments under -\&\fB\-\-change\-addresses\fR, above. If \fIsection\fR does not exist in -the input file, a warning will be issued, unless -\&\fB\-\-no\-change\-warnings\fR is used. -.IP "\fB\-\-change\-warnings\fR" 4 -.IX Item "--change-warnings" -.PD 0 -.IP "\fB\-\-adjust\-warnings\fR" 4 -.IX Item "--adjust-warnings" -.PD -If \fB\-\-change\-section\-address\fR or \fB\-\-change\-section\-lma\fR or -\&\fB\-\-change\-section\-vma\fR is used, and the named section does not -exist, issue a warning. This is the default. -.IP "\fB\-\-no\-change\-warnings\fR" 4 -.IX Item "--no-change-warnings" -.PD 0 -.IP "\fB\-\-no\-adjust\-warnings\fR" 4 -.IX Item "--no-adjust-warnings" -.PD -Do not issue a warning if \fB\-\-change\-section\-address\fR or -\&\fB\-\-adjust\-section\-lma\fR or \fB\-\-adjust\-section\-vma\fR is used, even -if the named section does not exist. -.IP "\fB\-\-set\-section\-flags\fR \fIsection\fR\fB=\fR\fIflags\fR" 4 -.IX Item "--set-section-flags section=flags" -Set the flags for the named section. The \fIflags\fR argument is a -comma separated string of flag names. The recognized names are -\&\fBalloc\fR, \fBcontents\fR, \fBload\fR, \fBnoload\fR, -\&\fBreadonly\fR, \fBcode\fR, \fBdata\fR, \fBrom\fR, \fBshare\fR, and -\&\fBdebug\fR. You can set the \fBcontents\fR flag for a section which -does not have contents, but it is not meaningful to clear the -\&\fBcontents\fR flag of a section which does have contents\*(--just remove -the section instead. Not all flags are meaningful for all object file -formats. -.IP "\fB\-\-add\-section\fR \fIsectionname\fR\fB=\fR\fIfilename\fR" 4 -.IX Item "--add-section sectionname=filename" -Add a new section named \fIsectionname\fR while copying the file. The -contents of the new section are taken from the file \fIfilename\fR. The -size of the section will be the size of the file. This option only -works on file formats which can support sections with arbitrary names. -.IP "\fB\-\-rename\-section\fR \fIoldname\fR\fB=\fR\fInewname\fR\fB[,\fR\fIflags\fR\fB]\fR" 4 -.IX Item "--rename-section oldname=newname[,flags]" -Rename a section from \fIoldname\fR to \fInewname\fR, optionally -changing the section's flags to \fIflags\fR in the process. This has -the advantage over usng a linker script to perform the rename in that -the output stays as an object file and does not become a linked -executable. -.Sp -This option is particularly helpful when the input format is binary, -since this will always create a section called .data. If for example, -you wanted instead to create a section called .rodata containing binary -data you could use the following command line to achieve it: -.Sp -.Vb 3 -\& objcopy \-I binary \-O \-B \e -\& \-\-rename\-section .data=.rodata,alloc,load,readonly,data,contents \e -\& -.Ve -.IP "\fB\-\-long\-section\-names {enable,disable,keep}\fR" 4 -.IX Item "--long-section-names {enable,disable,keep}" -Controls the handling of long section names when processing \f(CW\*(C`COFF\*(C'\fR -and \f(CW\*(C`PE\-COFF\*(C'\fR object formats. The default behaviour, \fBkeep\fR, -is to preserve long section names if any are present in the input file. -The \fBenable\fR and \fBdisable\fR options forcibly enable or disable -the use of long section names in the output object; when \fBdisable\fR -is in effect, any long section names in the input object will be truncated. -The \fBenable\fR option will only emit long section names if any are -present in the inputs; this is mostly the same as \fBkeep\fR, but it -is left undefined whether the \fBenable\fR option might force the -creation of an empty string table in the output file. -.IP "\fB\-\-change\-leading\-char\fR" 4 -.IX Item "--change-leading-char" -Some object file formats use special characters at the start of -symbols. The most common such character is underscore, which compilers -often add before every symbol. This option tells \fBobjcopy\fR to -change the leading character of every symbol when it converts between -object file formats. If the object file formats use the same leading -character, this option has no effect. Otherwise, it will add a -character, or remove a character, or change a character, as -appropriate. -.IP "\fB\-\-remove\-leading\-char\fR" 4 -.IX Item "--remove-leading-char" -If the first character of a global symbol is a special symbol leading -character used by the object file format, remove the character. The -most common symbol leading character is underscore. This option will -remove a leading underscore from all global symbols. This can be useful -if you want to link together objects of different file formats with -different conventions for symbol names. This is different from -\&\fB\-\-change\-leading\-char\fR because it always changes the symbol name -when appropriate, regardless of the object file format of the output -file. -.IP "\fB\-\-reverse\-bytes=\fR\fInum\fR" 4 -.IX Item "--reverse-bytes=num" -Reverse the bytes in a section with output contents. A section length must -be evenly divisible by the value given in order for the swap to be able to -take place. Reversing takes place before the interleaving is performed. -.Sp -This option is used typically in generating \s-1ROM\s0 images for problematic -target systems. For example, on some target boards, the 32\-bit words -fetched from 8\-bit ROMs are re-assembled in little-endian byte order -regardless of the \s-1CPU\s0 byte order. Depending on the programming model, the -endianness of the \s-1ROM\s0 may need to be modified. -.Sp -Consider a simple file with a section containing the following eight -bytes: \f(CW12345678\fR. -.Sp -Using \fB\-\-reverse\-bytes=2\fR for the above example, the bytes in the -output file would be ordered \f(CW21436587\fR. -.Sp -Using \fB\-\-reverse\-bytes=4\fR for the above example, the bytes in the -output file would be ordered \f(CW43218765\fR. -.Sp -By using \fB\-\-reverse\-bytes=2\fR for the above example, followed by -\&\fB\-\-reverse\-bytes=4\fR on the output file, the bytes in the second -output file would be ordered \f(CW34127856\fR. -.IP "\fB\-\-srec\-len=\fR\fIival\fR" 4 -.IX Item "--srec-len=ival" -Meaningful only for srec output. Set the maximum length of the Srecords -being produced to \fIival\fR. This length covers both address, data and -crc fields. -.IP "\fB\-\-srec\-forceS3\fR" 4 -.IX Item "--srec-forceS3" -Meaningful only for srec output. Avoid generation of S1/S2 records, -creating S3\-only record format. -.IP "\fB\-\-redefine\-sym\fR \fIold\fR\fB=\fR\fInew\fR" 4 -.IX Item "--redefine-sym old=new" -Change the name of a symbol \fIold\fR, to \fInew\fR. This can be useful -when one is trying link two things together for which you have no -source, and there are name collisions. -.IP "\fB\-\-redefine\-syms=\fR\fIfilename\fR" 4 -.IX Item "--redefine-syms=filename" -Apply \fB\-\-redefine\-sym\fR to each symbol pair "\fIold\fR \fInew\fR" -listed in the file \fIfilename\fR. \fIfilename\fR is simply a flat file, -with one symbol pair per line. Line comments may be introduced by the hash -character. This option may be given more than once. -.IP "\fB\-\-weaken\fR" 4 -.IX Item "--weaken" -Change all global symbols in the file to be weak. This can be useful -when building an object which will be linked against other objects using -the \fB\-R\fR option to the linker. This option is only effective when -using an object file format which supports weak symbols. -.IP "\fB\-\-keep\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--keep-symbols=filename" -Apply \fB\-\-keep\-symbol\fR option to each symbol listed in the file -\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. -.IP "\fB\-\-strip\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--strip-symbols=filename" -Apply \fB\-\-strip\-symbol\fR option to each symbol listed in the file -\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. -.IP "\fB\-\-strip\-unneeded\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--strip-unneeded-symbols=filename" -Apply \fB\-\-strip\-unneeded\-symbol\fR option to each symbol listed in -the file \fIfilename\fR. \fIfilename\fR is simply a flat file, with one -symbol name per line. Line comments may be introduced by the hash -character. This option may be given more than once. -.IP "\fB\-\-keep\-global\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--keep-global-symbols=filename" -Apply \fB\-\-keep\-global\-symbol\fR option to each symbol listed in the -file \fIfilename\fR. \fIfilename\fR is simply a flat file, with one -symbol name per line. Line comments may be introduced by the hash -character. This option may be given more than once. -.IP "\fB\-\-localize\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--localize-symbols=filename" -Apply \fB\-\-localize\-symbol\fR option to each symbol listed in the file -\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. -.IP "\fB\-\-globalize\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--globalize-symbols=filename" -Apply \fB\-\-globalize\-symbol\fR option to each symbol listed in the file -\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. -.IP "\fB\-\-weaken\-symbols=\fR\fIfilename\fR" 4 -.IX Item "--weaken-symbols=filename" -Apply \fB\-\-weaken\-symbol\fR option to each symbol listed in the file -\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol -name per line. Line comments may be introduced by the hash character. -This option may be given more than once. -.IP "\fB\-\-alt\-machine\-code=\fR\fIindex\fR" 4 -.IX Item "--alt-machine-code=index" -If the output architecture has alternate machine codes, use the -\&\fIindex\fRth code instead of the default one. This is useful in case -a machine is assigned an official code and the tool-chain adopts the -new code, but other applications still depend on the original code -being used. For \s-1ELF\s0 based architectures if the \fIindex\fR -alternative does not exist then the value is treated as an absolute -number to be stored in the e_machine field of the \s-1ELF\s0 header. -.IP "\fB\-\-writable\-text\fR" 4 -.IX Item "--writable-text" -Mark the output text as writable. This option isn't meaningful for all -object file formats. -.IP "\fB\-\-readonly\-text\fR" 4 -.IX Item "--readonly-text" -Make the output text write protected. This option isn't meaningful for all -object file formats. -.IP "\fB\-\-pure\fR" 4 -.IX Item "--pure" -Mark the output file as demand paged. This option isn't meaningful for all -object file formats. -.IP "\fB\-\-impure\fR" 4 -.IX Item "--impure" -Mark the output file as impure. This option isn't meaningful for all -object file formats. -.IP "\fB\-\-prefix\-symbols=\fR\fIstring\fR" 4 -.IX Item "--prefix-symbols=string" -Prefix all symbols in the output file with \fIstring\fR. -.IP "\fB\-\-prefix\-sections=\fR\fIstring\fR" 4 -.IX Item "--prefix-sections=string" -Prefix all section names in the output file with \fIstring\fR. -.IP "\fB\-\-prefix\-alloc\-sections=\fR\fIstring\fR" 4 -.IX Item "--prefix-alloc-sections=string" -Prefix all the names of all allocated sections in the output file with -\&\fIstring\fR. -.IP "\fB\-\-add\-gnu\-debuglink=\fR\fIpath-to-file\fR" 4 -.IX Item "--add-gnu-debuglink=path-to-file" -Creates a .gnu_debuglink section which contains a reference to \fIpath-to-file\fR -and adds it to the output file. -.IP "\fB\-\-keep\-file\-symbols\fR" 4 -.IX Item "--keep-file-symbols" -When stripping a file, perhaps with \fB\-\-strip\-debug\fR or -\&\fB\-\-strip\-unneeded\fR, retain any symbols specifying source file names, -which would otherwise get stripped. -.IP "\fB\-\-only\-keep\-debug\fR" 4 -.IX Item "--only-keep-debug" -Strip a file, removing contents of any sections that would not be -stripped by \fB\-\-strip\-debug\fR and leaving the debugging sections -intact. In \s-1ELF\s0 files, this preserves all note sections in the output. -.Sp -The intention is that this option will be used in conjunction with -\&\fB\-\-add\-gnu\-debuglink\fR to create a two part executable. One a -stripped binary which will occupy less space in \s-1RAM\s0 and in a -distribution and the second a debugging information file which is only -needed if debugging abilities are required. The suggested procedure -to create these files is as follows: -.RS 4 -.IP "1." 4 -.IX Item "1." -\&\f(CW\*(C`foo\*(C'\fR then... -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -create a file containing the debugging info. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -stripped executable. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -to add a link to the debugging info into the stripped executable. -.RE -.RS 4 -.Sp -Note\-\-\-the choice of \f(CW\*(C`.dbg\*(C'\fR as an extension for the debug info -file is arbitrary. Also the \f(CW\*(C`\-\-only\-keep\-debug\*(C'\fR step is -optional. You could instead do this: -.IP "1." 4 -.IX Item "1." -.PD 0 -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.RE -.RS 4 -.PD -.Sp -i.e., the file pointed to by the \fB\-\-add\-gnu\-debuglink\fR can be the -full executable. It does not have to be a file created by the -\&\fB\-\-only\-keep\-debug\fR switch. -.Sp -Note\-\-\-this switch is only intended for use on fully linked files. It -does not make sense to use it on object files where the debugging -information may be incomplete. Besides the gnu_debuglink feature -currently only supports the presence of one filename containing -debugging information, not multiple filenames on a one-per-object-file -basis. -.RE -.IP "\fB\-\-file\-alignment\fR \fInum\fR" 4 -.IX Item "--file-alignment num" -Specify the file alignment. Sections in the file will always begin at -file offsets which are multiples of this number. This defaults to -512. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-heap\fR \fIreserve\fR" 4 -.IX Item "--heap reserve" -.PD 0 -.IP "\fB\-\-heap\fR \fIreserve\fR\fB,\fR\fIcommit\fR" 4 -.IX Item "--heap reserve,commit" -.PD -Specify the number of bytes of memory to reserve (and optionally commit) -to be used as heap for this program. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-image\-base\fR \fIvalue\fR" 4 -.IX Item "--image-base value" -Use \fIvalue\fR as the base address of your program or dll. This is -the lowest memory location that will be used when your program or dll -is loaded. To reduce the need to relocate and improve performance of -your dlls, each should have a unique base address and not overlap any -other dlls. The default is 0x400000 for executables, and 0x10000000 -for dlls. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-section\-alignment\fR \fInum\fR" 4 -.IX Item "--section-alignment num" -Sets the section alignment. Sections in memory will always begin at -addresses which are a multiple of this number. Defaults to 0x1000. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-stack\fR \fIreserve\fR" 4 -.IX Item "--stack reserve" -.PD 0 -.IP "\fB\-\-stack\fR \fIreserve\fR\fB,\fR\fIcommit\fR" 4 -.IX Item "--stack reserve,commit" -.PD -Specify the number of bytes of memory to reserve (and optionally commit) -to be used as stack for this program. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-subsystem\fR \fIwhich\fR" 4 -.IX Item "--subsystem which" -.PD 0 -.IP "\fB\-\-subsystem\fR \fIwhich\fR\fB:\fR\fImajor\fR" 4 -.IX Item "--subsystem which:major" -.IP "\fB\-\-subsystem\fR \fIwhich\fR\fB:\fR\fImajor\fR\fB.\fR\fIminor\fR" 4 -.IX Item "--subsystem which:major.minor" -.PD -Specifies the subsystem under which your program will execute. The -legal values for \fIwhich\fR are \f(CW\*(C`native\*(C'\fR, \f(CW\*(C`windows\*(C'\fR, -\&\f(CW\*(C`console\*(C'\fR, \f(CW\*(C`posix\*(C'\fR, \f(CW\*(C`efi\-app\*(C'\fR, \f(CW\*(C`efi\-bsd\*(C'\fR, -\&\f(CW\*(C`efi\-rtd\*(C'\fR, \f(CW\*(C`sal\-rtd\*(C'\fR, and \f(CW\*(C`xbox\*(C'\fR. You may optionally set -the subsystem version also. Numeric values are also accepted for -\&\fIwhich\fR. -[This option is specific to \s-1PE\s0 targets.] -.IP "\fB\-\-extract\-symbol\fR" 4 -.IX Item "--extract-symbol" -Keep the file's section flags and symbols but remove all section data. -Specifically, the option: -.RS 4 -.IP "*" 4 -.IX Item "*" -.PD 0 -.IP "*" 4 -.IX Item "*" -.IP "*" 4 -.IX Item "*" -.RE -.RS 4 -.PD -.Sp -This option is used to build a \fI.sym\fR file for a VxWorks kernel. -It can also be a useful way of reducing the size of a \fB\-\-just\-symbols\fR -linker input file. -.RE -.IP "\fB\-\-compress\-debug\-sections\fR" 4 -.IX Item "--compress-debug-sections" -Compress \s-1DWARF\s0 debug sections using zlib. -.IP "\fB\-\-decompress\-debug\-sections\fR" 4 -.IX Item "--decompress-debug-sections" -Decompress \s-1DWARF\s0 debug sections using zlib. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number of \fBobjcopy\fR. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-verbose\fR" 4 -.IX Item "--verbose" -.PD -Verbose output: list all object files modified. In the case of -archives, \fBobjcopy \-V\fR lists all members of the archive. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of the options to \fBobjcopy\fR. -.IP "\fB\-\-info\fR" 4 -.IX Item "--info" -Display a list showing all architectures and object formats available. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIld\fR\|(1), \fIobjdump\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/objdump.1 b/contrib/binutils-2.22/binutils/doc/objdump.1 deleted file mode 100644 index 2eccdeffc6..0000000000 --- a/contrib/binutils-2.22/binutils/doc/objdump.1 +++ /dev/null @@ -1,836 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "OBJDUMP 1" -.TH OBJDUMP 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -objdump \- display information from object files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -objdump [\fB\-a\fR|\fB\-\-archive\-headers\fR] - [\fB\-b\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR] ] - [\fB\-d\fR|\fB\-\-disassemble\fR] - [\fB\-D\fR|\fB\-\-disassemble\-all\fR] - [\fB\-z\fR|\fB\-\-disassemble\-zeroes\fR] - [\fB\-EB\fR|\fB\-EL\fR|\fB\-\-endian=\fR{big | little }] - [\fB\-f\fR|\fB\-\-file\-headers\fR] - [\fB\-F\fR|\fB\-\-file\-offsets\fR] - [\fB\-\-file\-start\-context\fR] - [\fB\-g\fR|\fB\-\-debugging\fR] - [\fB\-e\fR|\fB\-\-debugging\-tags\fR] - [\fB\-h\fR|\fB\-\-section\-headers\fR|\fB\-\-headers\fR] - [\fB\-i\fR|\fB\-\-info\fR] - [\fB\-j\fR \fIsection\fR|\fB\-\-section=\fR\fIsection\fR] - [\fB\-l\fR|\fB\-\-line\-numbers\fR] - [\fB\-S\fR|\fB\-\-source\fR] - [\fB\-m\fR \fImachine\fR|\fB\-\-architecture=\fR\fImachine\fR] - [\fB\-M\fR \fIoptions\fR|\fB\-\-disassembler\-options=\fR\fIoptions\fR] - [\fB\-p\fR|\fB\-\-private\-headers\fR] - [\fB\-P\fR \fIoptions\fR|\fB\-\-private=\fR\fIoptions\fR] - [\fB\-r\fR|\fB\-\-reloc\fR] - [\fB\-R\fR|\fB\-\-dynamic\-reloc\fR] - [\fB\-s\fR|\fB\-\-full\-contents\fR] - [\fB\-W[lLiaprmfFsoRt]\fR| - \fB\-\-dwarf\fR[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] - [\fB\-G\fR|\fB\-\-stabs\fR] - [\fB\-t\fR|\fB\-\-syms\fR] - [\fB\-T\fR|\fB\-\-dynamic\-syms\fR] - [\fB\-x\fR|\fB\-\-all\-headers\fR] - [\fB\-w\fR|\fB\-\-wide\fR] - [\fB\-\-start\-address=\fR\fIaddress\fR] - [\fB\-\-stop\-address=\fR\fIaddress\fR] - [\fB\-\-prefix\-addresses\fR] - [\fB\-\-[no\-]show\-raw\-insn\fR] - [\fB\-\-adjust\-vma=\fR\fIoffset\fR] - [\fB\-\-special\-syms\fR] - [\fB\-\-prefix=\fR\fIprefix\fR] - [\fB\-\-prefix\-strip=\fR\fIlevel\fR] - [\fB\-\-insn\-width=\fR\fIwidth\fR] - [\fB\-V\fR|\fB\-\-version\fR] - [\fB\-H\fR|\fB\-\-help\fR] - \fIobjfile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBobjdump\fR displays information about one or more object files. -The options control what particular information to display. This -information is mostly useful to programmers who are working on the -compilation tools, as opposed to programmers who just want their -program to compile and work. -.PP -\&\fIobjfile\fR... are the object files to be examined. When you -specify archives, \fBobjdump\fR shows information on each of the member -object files. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. At least one option from the list -\&\fB\-a,\-d,\-D,\-e,\-f,\-g,\-G,\-h,\-H,\-p,\-P,\-r,\-R,\-s,\-S,\-t,\-T,\-V,\-x\fR must be given. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-archive\-header\fR" 4 -.IX Item "--archive-header" -.PD -If any of the \fIobjfile\fR files are archives, display the archive -header information (in a format similar to \fBls \-l\fR). Besides the -information you could list with \fBar tv\fR, \fBobjdump \-a\fR shows -the object file format of each archive member. -.IP "\fB\-\-adjust\-vma=\fR\fIoffset\fR" 4 -.IX Item "--adjust-vma=offset" -When dumping information, first add \fIoffset\fR to all the section -addresses. This is useful if the section addresses do not correspond to -the symbol table, which can happen when putting sections at particular -addresses when using a format which can not represent section addresses, -such as a.out. -.IP "\fB\-b\fR \fIbfdname\fR" 4 -.IX Item "-b bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Specify that the object-code format for the object files is -\&\fIbfdname\fR. This option may not be necessary; \fIobjdump\fR can -automatically recognize many formats. -.Sp -For example, -.Sp -.Vb 1 -\& objdump \-b oasys \-m vax \-h fu.o -.Ve -.Sp -displays summary information from the section headers (\fB\-h\fR) of -\&\fIfu.o\fR, which is explicitly identified (\fB\-m\fR) as a \s-1VAX\s0 object -file in the format produced by Oasys compilers. You can list the -formats available with the \fB\-i\fR option. -.IP "\fB\-C\fR" 4 -.IX Item "-C" -.PD 0 -.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 -.IX Item "--demangle[=style]" -.PD -Decode (\fIdemangle\fR) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes \*(C+ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-debugging\fR" 4 -.IX Item "--debugging" -.PD -Display debugging information. This attempts to parse \s-1STABS\s0 and \s-1IEEE\s0 -debugging format information stored in the file and print it out using -a C like syntax. If neither of these formats are found this option -falls back on the \fB\-W\fR option to print any \s-1DWARF\s0 information in -the file. -.IP "\fB\-e\fR" 4 -.IX Item "-e" -.PD 0 -.IP "\fB\-\-debugging\-tags\fR" 4 -.IX Item "--debugging-tags" -.PD -Like \fB\-g\fR, but the information is generated in a format compatible -with ctags tool. -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.PD 0 -.IP "\fB\-\-disassemble\fR" 4 -.IX Item "--disassemble" -.PD -Display the assembler mnemonics for the machine instructions from -\&\fIobjfile\fR. This option only disassembles those sections which are -expected to contain instructions. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -.PD 0 -.IP "\fB\-\-disassemble\-all\fR" 4 -.IX Item "--disassemble-all" -.PD -Like \fB\-d\fR, but disassemble the contents of all sections, not just -those expected to contain instructions. -.Sp -If the target is an \s-1ARM\s0 architecture this switch also has the effect -of forcing the disassembler to decode pieces of data found in code -sections as if they were instructions. -.IP "\fB\-\-prefix\-addresses\fR" 4 -.IX Item "--prefix-addresses" -When disassembling, print the complete address on each line. This is -the older disassembly format. -.IP "\fB\-EB\fR" 4 -.IX Item "-EB" -.PD 0 -.IP "\fB\-EL\fR" 4 -.IX Item "-EL" -.IP "\fB\-\-endian={big|little}\fR" 4 -.IX Item "--endian={big|little}" -.PD -Specify the endianness of the object files. This only affects -disassembly. This can be useful when disassembling a file format which -does not describe endianness information, such as S\-records. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -.PD 0 -.IP "\fB\-\-file\-headers\fR" 4 -.IX Item "--file-headers" -.PD -Display summary information from the overall header of -each of the \fIobjfile\fR files. -.IP "\fB\-F\fR" 4 -.IX Item "-F" -.PD 0 -.IP "\fB\-\-file\-offsets\fR" 4 -.IX Item "--file-offsets" -.PD -When disassembling sections, whenever a symbol is displayed, also -display the file offset of the region of data that is about to be -dumped. If zeroes are being skipped, then when disassembly resumes, -tell the user how many zeroes were skipped and the file offset of the -location from where the disassembly resumes. When dumping sections, -display the file offset of the location from where the dump starts. -.IP "\fB\-\-file\-start\-context\fR" 4 -.IX Item "--file-start-context" -Specify that when displaying interlisted source code/disassembly -(assumes \fB\-S\fR) from a file that has not yet been displayed, extend the -context to the start of the file. -.IP "\fB\-h\fR" 4 -.IX Item "-h" -.PD 0 -.IP "\fB\-\-section\-headers\fR" 4 -.IX Item "--section-headers" -.IP "\fB\-\-headers\fR" 4 -.IX Item "--headers" -.PD -Display summary information from the section headers of the -object file. -.Sp -File segments may be relocated to nonstandard addresses, for example by -using the \fB\-Ttext\fR, \fB\-Tdata\fR, or \fB\-Tbss\fR options to -\&\fBld\fR. However, some object file formats, such as a.out, do not -store the starting address of the file segments. In those situations, -although \fBld\fR relocates the sections correctly, using \fBobjdump -\&\-h\fR to list the file section headers cannot show the correct addresses. -Instead, it shows the usual addresses, which are implicit for the -target. -.IP "\fB\-H\fR" 4 -.IX Item "-H" -.PD 0 -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -.PD -Print a summary of the options to \fBobjdump\fR and exit. -.IP "\fB\-i\fR" 4 -.IX Item "-i" -.PD 0 -.IP "\fB\-\-info\fR" 4 -.IX Item "--info" -.PD -Display a list showing all architectures and object formats available -for specification with \fB\-b\fR or \fB\-m\fR. -.IP "\fB\-j\fR \fIname\fR" 4 -.IX Item "-j name" -.PD 0 -.IP "\fB\-\-section=\fR\fIname\fR" 4 -.IX Item "--section=name" -.PD -Display information only for section \fIname\fR. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -.PD 0 -.IP "\fB\-\-line\-numbers\fR" 4 -.IX Item "--line-numbers" -.PD -Label the display (using debugging information) with the filename and -source line numbers corresponding to the object code or relocs shown. -Only useful with \fB\-d\fR, \fB\-D\fR, or \fB\-r\fR. -.IP "\fB\-m\fR \fImachine\fR" 4 -.IX Item "-m machine" -.PD 0 -.IP "\fB\-\-architecture=\fR\fImachine\fR" 4 -.IX Item "--architecture=machine" -.PD -Specify the architecture to use when disassembling object files. This -can be useful when disassembling object files which do not describe -architecture information, such as S\-records. You can list the available -architectures with the \fB\-i\fR option. -.Sp -If the target is an \s-1ARM\s0 architecture then this switch has an -additional effect. It restricts the disassembly to only those -instructions supported by the architecture specified by \fImachine\fR. -If it is necessary to use this switch because the input file does not -contain any architecture information, but it is also desired to -disassemble all the instructions use \fB\-marm\fR. -.IP "\fB\-M\fR \fIoptions\fR" 4 -.IX Item "-M options" -.PD 0 -.IP "\fB\-\-disassembler\-options=\fR\fIoptions\fR" 4 -.IX Item "--disassembler-options=options" -.PD -Pass target specific information to the disassembler. Only supported on -some targets. If it is necessary to specify more than one -disassembler option then multiple \fB\-M\fR options can be used or -can be placed together into a comma separated list. -.Sp -If the target is an \s-1ARM\s0 architecture then this switch can be used to -select which register name set is used during disassembler. Specifying -\&\fB\-M reg-names-std\fR (the default) will select the register names as -used in \s-1ARM\s0's instruction set documentation, but with register 13 called -\&'sp', register 14 called 'lr' and register 15 called 'pc'. Specifying -\&\fB\-M reg-names-apcs\fR will select the name set used by the \s-1ARM\s0 -Procedure Call Standard, whilst specifying \fB\-M reg-names-raw\fR will -just use \fBr\fR followed by the register number. -.Sp -There are also two variants on the \s-1APCS\s0 register naming scheme enabled -by \fB\-M reg-names-atpcs\fR and \fB\-M reg-names-special-atpcs\fR which -use the ARM/Thumb Procedure Call Standard naming conventions. (Either -with the normal register names or the special register names). -.Sp -This option can also be used for \s-1ARM\s0 architectures to force the -disassembler to interpret all instructions as Thumb instructions by -using the switch \fB\-\-disassembler\-options=force\-thumb\fR. This can be -useful when attempting to disassemble thumb code produced by other -compilers. -.Sp -For the x86, some of the options duplicate functions of the \fB\-m\fR -switch, but allow finer grained control. Multiple selections from the -following may be specified as a comma separated string. -\&\fBx86\-64\fR, \fBi386\fR and \fBi8086\fR select disassembly for -the given architecture. \fBintel\fR and \fBatt\fR select between -intel syntax mode and \s-1AT&T\s0 syntax mode. -\&\fBintel-mnemonic\fR and \fBatt-mnemonic\fR select between -intel mnemonic mode and \s-1AT&T\s0 mnemonic mode. \fBintel-mnemonic\fR -implies \fBintel\fR and \fBatt-mnemonic\fR implies \fBatt\fR. -\&\fBaddr64\fR, \fBaddr32\fR, -\&\fBaddr16\fR, \fBdata32\fR and \fBdata16\fR specify the default -address size and operand size. These four options will be overridden if -\&\fBx86\-64\fR, \fBi386\fR or \fBi8086\fR appear later in the -option string. Lastly, \fBsuffix\fR, when in \s-1AT&T\s0 mode, -instructs the disassembler to print a mnemonic suffix even when the -suffix could be inferred by the operands. -.Sp -For PowerPC, \fBbooke\fR controls the disassembly of BookE -instructions. \fB32\fR and \fB64\fR select PowerPC and -PowerPC64 disassembly, respectively. \fBe300\fR selects -disassembly for the e300 family. \fB440\fR selects disassembly for -the PowerPC 440. \fBppcps\fR selects disassembly for the paired -single instructions of the \s-1PPC750CL\s0. -.Sp -For \s-1MIPS\s0, this option controls the printing of instruction mnemonic -names and register names in disassembled instructions. Multiple -selections from the following may be specified as a comma separated -string, and invalid options are ignored: -.RS 4 -.ie n .IP """no\-aliases""" 4 -.el .IP "\f(CWno\-aliases\fR" 4 -.IX Item "no-aliases" -Print the 'raw' instruction mnemonic instead of some pseudo -instruction mnemonic. I.e., print 'daddu' or 'or' instead of 'move', -\&'sll' instead of 'nop', etc. -.ie n .IP """gpr\-names=\f(CIABI\f(CW""" 4 -.el .IP "\f(CWgpr\-names=\f(CIABI\f(CW\fR" 4 -.IX Item "gpr-names=ABI" -Print \s-1GPR\s0 (general-purpose register) names as appropriate -for the specified \s-1ABI\s0. By default, \s-1GPR\s0 names are selected according to -the \s-1ABI\s0 of the binary being disassembled. -.ie n .IP """fpr\-names=\f(CIABI\f(CW""" 4 -.el .IP "\f(CWfpr\-names=\f(CIABI\f(CW\fR" 4 -.IX Item "fpr-names=ABI" -Print \s-1FPR\s0 (floating-point register) names as -appropriate for the specified \s-1ABI\s0. By default, \s-1FPR\s0 numbers are printed -rather than names. -.ie n .IP """cp0\-names=\f(CIARCH\f(CW""" 4 -.el .IP "\f(CWcp0\-names=\f(CIARCH\f(CW\fR" 4 -.IX Item "cp0-names=ARCH" -Print \s-1CP0\s0 (system control coprocessor; coprocessor 0) register names -as appropriate for the \s-1CPU\s0 or architecture specified by -\&\fI\s-1ARCH\s0\fR. By default, \s-1CP0\s0 register names are selected according to -the architecture and \s-1CPU\s0 of the binary being disassembled. -.ie n .IP """hwr\-names=\f(CIARCH\f(CW""" 4 -.el .IP "\f(CWhwr\-names=\f(CIARCH\f(CW\fR" 4 -.IX Item "hwr-names=ARCH" -Print \s-1HWR\s0 (hardware register, used by the \f(CW\*(C`rdhwr\*(C'\fR instruction) names -as appropriate for the \s-1CPU\s0 or architecture specified by -\&\fI\s-1ARCH\s0\fR. By default, \s-1HWR\s0 names are selected according to -the architecture and \s-1CPU\s0 of the binary being disassembled. -.ie n .IP """reg\-names=\f(CIABI\f(CW""" 4 -.el .IP "\f(CWreg\-names=\f(CIABI\f(CW\fR" 4 -.IX Item "reg-names=ABI" -Print \s-1GPR\s0 and \s-1FPR\s0 names as appropriate for the selected \s-1ABI\s0. -.ie n .IP """reg\-names=\f(CIARCH\f(CW""" 4 -.el .IP "\f(CWreg\-names=\f(CIARCH\f(CW\fR" 4 -.IX Item "reg-names=ARCH" -Print CPU-specific register names (\s-1CP0\s0 register and \s-1HWR\s0 names) -as appropriate for the selected \s-1CPU\s0 or architecture. -.RE -.RS 4 -.Sp -For any of the options listed above, \fI\s-1ABI\s0\fR or -\&\fI\s-1ARCH\s0\fR may be specified as \fBnumeric\fR to have numbers printed -rather than names, for the selected types of registers. -You can list the available values of \fI\s-1ABI\s0\fR and \fI\s-1ARCH\s0\fR using -the \fB\-\-help\fR option. -.Sp -For \s-1VAX\s0, you can specify function entry addresses with \fB\-M -entry:0xf00ba\fR. You can use this multiple times to properly -disassemble \s-1VAX\s0 binary files that don't contain symbol tables (like -\&\s-1ROM\s0 dumps). In these cases, the function entry mask would otherwise -be decoded as \s-1VAX\s0 instructions, which would probably lead the rest -of the function being wrongly disassembled. -.RE -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-private\-headers\fR" 4 -.IX Item "--private-headers" -.PD -Print information that is specific to the object file format. The exact -information printed depends upon the object file format. For some -object file formats, no additional information is printed. -.IP "\fB\-P\fR \fIoptions\fR" 4 -.IX Item "-P options" -.PD 0 -.IP "\fB\-\-private=\fR\fIoptions\fR" 4 -.IX Item "--private=options" -.PD -Print information that is specific to the object file format. The -argument \fIoptions\fR is a comma separated list that depends on the -format (the lists of options is displayed with the help). -.Sp -For \s-1XCOFF\s0, the available options are: \fBheader\fR, \fBaout\fR, -\&\fBsections\fR, \fBsyms\fR, \fBrelocs\fR, \fBlineno\fR, -\&\fBloader\fR, \fBexcept\fR, \fBtypchk\fR, \fBtraceback\fR -and \fBtoc\fR. -.IP "\fB\-r\fR" 4 -.IX Item "-r" -.PD 0 -.IP "\fB\-\-reloc\fR" 4 -.IX Item "--reloc" -.PD -Print the relocation entries of the file. If used with \fB\-d\fR or -\&\fB\-D\fR, the relocations are printed interspersed with the -disassembly. -.IP "\fB\-R\fR" 4 -.IX Item "-R" -.PD 0 -.IP "\fB\-\-dynamic\-reloc\fR" 4 -.IX Item "--dynamic-reloc" -.PD -Print the dynamic relocation entries of the file. This is only -meaningful for dynamic objects, such as certain types of shared -libraries. As for \fB\-r\fR, if used with \fB\-d\fR or -\&\fB\-D\fR, the relocations are printed interspersed with the -disassembly. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-full\-contents\fR" 4 -.IX Item "--full-contents" -.PD -Display the full contents of any sections requested. By default all -non-empty sections are displayed. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-source\fR" 4 -.IX Item "--source" -.PD -Display source code intermixed with disassembly, if possible. Implies -\&\fB\-d\fR. -.IP "\fB\-\-prefix=\fR\fIprefix\fR" 4 -.IX Item "--prefix=prefix" -Specify \fIprefix\fR to add to the absolute paths when used with -\&\fB\-S\fR. -.IP "\fB\-\-prefix\-strip=\fR\fIlevel\fR" 4 -.IX Item "--prefix-strip=level" -Indicate how many initial directory names to strip off the hardwired -absolute paths. It has no effect without \fB\-\-prefix=\fR\fIprefix\fR. -.IP "\fB\-\-show\-raw\-insn\fR" 4 -.IX Item "--show-raw-insn" -When disassembling instructions, print the instruction in hex as well as -in symbolic form. This is the default except when -\&\fB\-\-prefix\-addresses\fR is used. -.IP "\fB\-\-no\-show\-raw\-insn\fR" 4 -.IX Item "--no-show-raw-insn" -When disassembling instructions, do not print the instruction bytes. -This is the default when \fB\-\-prefix\-addresses\fR is used. -.IP "\fB\-\-insn\-width=\fR\fIwidth\fR" 4 -.IX Item "--insn-width=width" -Display \fIwidth\fR bytes on a single line when disassembling -instructions. -.IP "\fB\-W[lLiaprmfFsoRt]\fR" 4 -.IX Item "-W[lLiaprmfFsoRt]" -.PD 0 -.IP "\fB\-\-dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]\fR" 4 -.IX Item "--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]" -.PD -Displays the contents of the debug sections in the file, if any are -present. If one of the optional letters or words follows the switch -then only data found in those specific sections will be dumped. -.Sp -Note that there is no single letter option to display the content of -trace sections or .gdb_index. -.Sp -Note: the output from the \fB=info\fR option can also be affected -by the options \fB\-\-dwarf\-depth\fR and \fB\-\-dwarf\-start\fR. -.IP "\fB\-\-dwarf\-depth=\fR\fIn\fR" 4 -.IX Item "--dwarf-depth=n" -Limit the dump of the \f(CW\*(C`.debug_info\*(C'\fR section to \fIn\fR children. -This is only useful with \fB\-\-dwarf=info\fR. The default is -to print all DIEs; the special value 0 for \fIn\fR will also have this -effect. -.Sp -With a non-zero value for \fIn\fR, DIEs at or deeper than \fIn\fR -levels will not be printed. The range for \fIn\fR is zero-based. -.IP "\fB\-\-dwarf\-start=\fR\fIn\fR" 4 -.IX Item "--dwarf-start=n" -Print only DIEs beginning with the \s-1DIE\s0 numbered \fIn\fR. This is only -useful with \fB\-\-dwarf=info\fR. -.Sp -If specified, this option will suppress printing of any header -information and all DIEs before the \s-1DIE\s0 numbered \fIn\fR. Only -siblings and children of the specified \s-1DIE\s0 will be printed. -.Sp -This can be used in conjunction with \fB\-\-dwarf\-depth\fR. -.IP "\fB\-G\fR" 4 -.IX Item "-G" -.PD 0 -.IP "\fB\-\-stabs\fR" 4 -.IX Item "--stabs" -.PD -Display the full contents of any sections requested. Display the -contents of the .stab and .stab.index and .stab.excl sections from an -\&\s-1ELF\s0 file. This is only useful on systems (such as Solaris 2.0) in which -\&\f(CW\*(C`.stab\*(C'\fR debugging symbol-table entries are carried in an \s-1ELF\s0 -section. In most other file formats, debugging symbol-table entries are -interleaved with linkage symbols, and are visible in the \fB\-\-syms\fR -output. -.IP "\fB\-\-start\-address=\fR\fIaddress\fR" 4 -.IX Item "--start-address=address" -Start displaying data at the specified address. This affects the output -of the \fB\-d\fR, \fB\-r\fR and \fB\-s\fR options. -.IP "\fB\-\-stop\-address=\fR\fIaddress\fR" 4 -.IX Item "--stop-address=address" -Stop displaying data at the specified address. This affects the output -of the \fB\-d\fR, \fB\-r\fR and \fB\-s\fR options. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -.PD 0 -.IP "\fB\-\-syms\fR" 4 -.IX Item "--syms" -.PD -Print the symbol table entries of the file. -This is similar to the information provided by the \fBnm\fR program, -although the display format is different. The format of the output -depends upon the format of the file being dumped, but there are two main -types. One looks like this: -.Sp -.Vb 2 -\& [ 4](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss -\& [ 6](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 fred -.Ve -.Sp -where the number inside the square brackets is the number of the entry -in the symbol table, the \fIsec\fR number is the section number, the -\&\fIfl\fR value are the symbol's flag bits, the \fIty\fR number is the -symbol's type, the \fIscl\fR number is the symbol's storage class and -the \fInx\fR value is the number of auxilary entries associated with -the symbol. The last two fields are the symbol's value and its name. -.Sp -The other common output format, usually seen with \s-1ELF\s0 based files, -looks like this: -.Sp -.Vb 2 -\& 00000000 l d .bss 00000000 .bss -\& 00000000 g .text 00000000 fred -.Ve -.Sp -Here the first number is the symbol's value (sometimes refered to as -its address). The next field is actually a set of characters and -spaces indicating the flag bits that are set on the symbol. These -characters are described below. Next is the section with which the -symbol is associated or \fI*ABS*\fR if the section is absolute (ie -not connected with any section), or \fI*UND*\fR if the section is -referenced in the file being dumped, but not defined there. -.Sp -After the section name comes another field, a number, which for common -symbols is the alignment and for other symbol is the size. Finally -the symbol's name is displayed. -.Sp -The flag characters are divided into 7 groups as follows: -.RS 4 -.ie n .IP """l""" 4 -.el .IP "\f(CWl\fR" 4 -.IX Item "l" -.PD 0 -.ie n .IP """g""" 4 -.el .IP "\f(CWg\fR" 4 -.IX Item "g" -.ie n .IP """u""" 4 -.el .IP "\f(CWu\fR" 4 -.IX Item "u" -.ie n .IP """!""" 4 -.el .IP "\f(CW!\fR" 4 -.IX Item "!" -.PD -The symbol is a local (l), global (g), unique global (u), neither -global nor local (a space) or both global and local (!). A -symbol can be neither local or global for a variety of reasons, e.g., -because it is used for debugging, but it is probably an indication of -a bug if it is ever both local and global. Unique global symbols are -a \s-1GNU\s0 extension to the standard set of \s-1ELF\s0 symbol bindings. For such -a symbol the dynamic linker will make sure that in the entire process -there is just one symbol with this name and type in use. -.ie n .IP """w""" 4 -.el .IP "\f(CWw\fR" 4 -.IX Item "w" -The symbol is weak (w) or strong (a space). -.ie n .IP """C""" 4 -.el .IP "\f(CWC\fR" 4 -.IX Item "C" -The symbol denotes a constructor (C) or an ordinary symbol (a space). -.ie n .IP """W""" 4 -.el .IP "\f(CWW\fR" 4 -.IX Item "W" -The symbol is a warning (W) or a normal symbol (a space). A warning -symbol's name is a message to be displayed if the symbol following the -warning symbol is ever referenced. -.ie n .IP """I""" 4 -.el .IP "\f(CWI\fR" 4 -.IX Item "I" -.PD 0 -.ie n .IP """i""" 4 -.el .IP "\f(CWi\fR" 4 -.IX Item "i" -.PD -The symbol is an indirect reference to another symbol (I), a function -to be evaluated during reloc processing (i) or a normal symbol (a -space). -.ie n .IP """d""" 4 -.el .IP "\f(CWd\fR" 4 -.IX Item "d" -.PD 0 -.ie n .IP """D""" 4 -.el .IP "\f(CWD\fR" 4 -.IX Item "D" -.PD -The symbol is a debugging symbol (d) or a dynamic symbol (D) or a -normal symbol (a space). -.ie n .IP """F""" 4 -.el .IP "\f(CWF\fR" 4 -.IX Item "F" -.PD 0 -.ie n .IP """f""" 4 -.el .IP "\f(CWf\fR" 4 -.IX Item "f" -.ie n .IP """O""" 4 -.el .IP "\f(CWO\fR" 4 -.IX Item "O" -.PD -The symbol is the name of a function (F) or a file (f) or an object -(O) or just a normal symbol (a space). -.RE -.RS 4 -.RE -.IP "\fB\-T\fR" 4 -.IX Item "-T" -.PD 0 -.IP "\fB\-\-dynamic\-syms\fR" 4 -.IX Item "--dynamic-syms" -.PD -Print the dynamic symbol table entries of the file. This is only -meaningful for dynamic objects, such as certain types of shared -libraries. This is similar to the information provided by the \fBnm\fR -program when given the \fB\-D\fR (\fB\-\-dynamic\fR) option. -.IP "\fB\-\-special\-syms\fR" 4 -.IX Item "--special-syms" -When displaying symbols include those which the target considers to be -special in some way and which would not normally be of interest to the -user. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Print the version number of \fBobjdump\fR and exit. -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.PD 0 -.IP "\fB\-\-all\-headers\fR" 4 -.IX Item "--all-headers" -.PD -Display all available header information, including the symbol table and -relocation entries. Using \fB\-x\fR is equivalent to specifying all of -\&\fB\-a \-f \-h \-p \-r \-t\fR. -.IP "\fB\-w\fR" 4 -.IX Item "-w" -.PD 0 -.IP "\fB\-\-wide\fR" 4 -.IX Item "--wide" -.PD -Format some lines for output devices that have more than 80 columns. -Also do not truncate symbol names when they are displayed. -.IP "\fB\-z\fR" 4 -.IX Item "-z" -.PD 0 -.IP "\fB\-\-disassemble\-zeroes\fR" 4 -.IX Item "--disassemble-zeroes" -.PD -Normally the disassembly output will skip blocks of zeroes. This -option directs the disassembler to disassemble those blocks, just like -any other data. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fInm\fR\|(1), \fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/ranlib.1 b/contrib/binutils-2.22/binutils/doc/ranlib.1 deleted file mode 100644 index b99513f446..0000000000 --- a/contrib/binutils-2.22/binutils/doc/ranlib.1 +++ /dev/null @@ -1,192 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "RANLIB 1" -.TH RANLIB 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -ranlib \- generate index to archive. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -ranlib [\fB\-vVt\fR] \fIarchive\fR -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBranlib\fR generates an index to the contents of an archive and -stores it in the archive. The index lists each symbol defined by a -member of an archive that is a relocatable object file. -.PP -You may use \fBnm \-s\fR or \fBnm \-\-print\-armap\fR to list this index. -.PP -An archive with such an index speeds up linking to the library and -allows routines in the library to call each other without regard to -their placement in the archive. -.PP -The \s-1GNU\s0 \fBranlib\fR program is another form of \s-1GNU\s0 \fBar\fR; running -\&\fBranlib\fR is completely equivalent to executing \fBar \-s\fR. -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number of \fBranlib\fR. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -Update the timestamp of the symbol map of an archive. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fInm\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/readelf.1 b/contrib/binutils-2.22/binutils/doc/readelf.1 deleted file mode 100644 index cd051ed7f3..0000000000 --- a/contrib/binutils-2.22/binutils/doc/readelf.1 +++ /dev/null @@ -1,450 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "READELF 1" -.TH READELF 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -readelf \- Displays information about ELF files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -readelf [\fB\-a\fR|\fB\-\-all\fR] - [\fB\-h\fR|\fB\-\-file\-header\fR] - [\fB\-l\fR|\fB\-\-program\-headers\fR|\fB\-\-segments\fR] - [\fB\-S\fR|\fB\-\-section\-headers\fR|\fB\-\-sections\fR] - [\fB\-g\fR|\fB\-\-section\-groups\fR] - [\fB\-t\fR|\fB\-\-section\-details\fR] - [\fB\-e\fR|\fB\-\-headers\fR] - [\fB\-s\fR|\fB\-\-syms\fR|\fB\-\-symbols\fR] - [\fB\-\-dyn\-syms\fR] - [\fB\-n\fR|\fB\-\-notes\fR] - [\fB\-r\fR|\fB\-\-relocs\fR] - [\fB\-u\fR|\fB\-\-unwind\fR] - [\fB\-d\fR|\fB\-\-dynamic\fR] - [\fB\-V\fR|\fB\-\-version\-info\fR] - [\fB\-A\fR|\fB\-\-arch\-specific\fR] - [\fB\-D\fR|\fB\-\-use\-dynamic\fR] - [\fB\-x\fR |\fB\-\-hex\-dump=\fR] - [\fB\-p\fR |\fB\-\-string\-dump=\fR] - [\fB\-R\fR |\fB\-\-relocated\-dump=\fR] - [\fB\-c\fR|\fB\-\-archive\-index\fR] - [\fB\-w[lLiaprmfFsoRt]\fR| - \fB\-\-debug\-dump\fR[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] - [\fB\-\-dwarf\-depth=\fR\fIn\fR] - [\fB\-\-dwarf\-start=\fR\fIn\fR] - [\fB\-I\fR|\fB\-\-histogram\fR] - [\fB\-v\fR|\fB\-\-version\fR] - [\fB\-W\fR|\fB\-\-wide\fR] - [\fB\-H\fR|\fB\-\-help\fR] - \fIelffile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBreadelf\fR displays information about one or more \s-1ELF\s0 format object -files. The options control what particular information to display. -.PP -\&\fIelffile\fR... are the object files to be examined. 32\-bit and -64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. -.PP -This program performs a similar function to \fBobjdump\fR but it -goes into more detail and it exists independently of the \s-1BFD\s0 -library, so if there is a bug in \s-1BFD\s0 then readelf will not be -affected. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. At least one option besides \fB\-v\fR or \fB\-H\fR must be -given. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-all\fR" 4 -.IX Item "--all" -.PD -Equivalent to specifying \fB\-\-file\-header\fR, -\&\fB\-\-program\-headers\fR, \fB\-\-sections\fR, \fB\-\-symbols\fR, -\&\fB\-\-relocs\fR, \fB\-\-dynamic\fR, \fB\-\-notes\fR and -\&\fB\-\-version\-info\fR. -.IP "\fB\-h\fR" 4 -.IX Item "-h" -.PD 0 -.IP "\fB\-\-file\-header\fR" 4 -.IX Item "--file-header" -.PD -Displays the information contained in the \s-1ELF\s0 header at the start of the -file. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -.PD 0 -.IP "\fB\-\-program\-headers\fR" 4 -.IX Item "--program-headers" -.IP "\fB\-\-segments\fR" 4 -.IX Item "--segments" -.PD -Displays the information contained in the file's segment headers, if it -has any. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-sections\fR" 4 -.IX Item "--sections" -.IP "\fB\-\-section\-headers\fR" 4 -.IX Item "--section-headers" -.PD -Displays the information contained in the file's section headers, if it -has any. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-section\-groups\fR" 4 -.IX Item "--section-groups" -.PD -Displays the information contained in the file's section groups, if it -has any. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -.PD 0 -.IP "\fB\-\-section\-details\fR" 4 -.IX Item "--section-details" -.PD -Displays the detailed section information. Implies \fB\-S\fR. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-symbols\fR" 4 -.IX Item "--symbols" -.IP "\fB\-\-syms\fR" 4 -.IX Item "--syms" -.PD -Displays the entries in symbol table section of the file, if it has one. -.IP "\fB\-\-dyn\-syms\fR" 4 -.IX Item "--dyn-syms" -Displays the entries in dynamic symbol table section of the file, if it -has one. -.IP "\fB\-e\fR" 4 -.IX Item "-e" -.PD 0 -.IP "\fB\-\-headers\fR" 4 -.IX Item "--headers" -.PD -Display all the headers in the file. Equivalent to \fB\-h \-l \-S\fR. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -.PD 0 -.IP "\fB\-\-notes\fR" 4 -.IX Item "--notes" -.PD -Displays the contents of the \s-1NOTE\s0 segments and/or sections, if any. -.IP "\fB\-r\fR" 4 -.IX Item "-r" -.PD 0 -.IP "\fB\-\-relocs\fR" 4 -.IX Item "--relocs" -.PD -Displays the contents of the file's relocation section, if it has one. -.IP "\fB\-u\fR" 4 -.IX Item "-u" -.PD 0 -.IP "\fB\-\-unwind\fR" 4 -.IX Item "--unwind" -.PD -Displays the contents of the file's unwind section, if it has one. Only -the unwind sections for \s-1IA64\s0 \s-1ELF\s0 files, as well as \s-1ARM\s0 unwind tables -(\f(CW\*(C`.ARM.exidx\*(C'\fR / \f(CW\*(C`.ARM.extab\*(C'\fR) are currently supported. -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.PD 0 -.IP "\fB\-\-dynamic\fR" 4 -.IX Item "--dynamic" -.PD -Displays the contents of the file's dynamic section, if it has one. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\-info\fR" 4 -.IX Item "--version-info" -.PD -Displays the contents of the version sections in the file, it they -exist. -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-\-arch\-specific\fR" 4 -.IX Item "--arch-specific" -.PD -Displays architecture-specific information in the file, if there -is any. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -.PD 0 -.IP "\fB\-\-use\-dynamic\fR" 4 -.IX Item "--use-dynamic" -.PD -When displaying symbols, this option makes \fBreadelf\fR use the -symbol hash tables in the file's dynamic section, rather than the -symbol table sections. -.IP "\fB\-x \fR" 4 -.IX Item "-x " -.PD 0 -.IP "\fB\-\-hex\-dump=\fR" 4 -.IX Item "--hex-dump=" -.PD -Displays the contents of the indicated section as a hexadecimal bytes. -A number identifies a particular section by index in the section table; -any other string identifies all sections with that name in the object file. -.IP "\fB\-R \fR" 4 -.IX Item "-R " -.PD 0 -.IP "\fB\-\-relocated\-dump=\fR" 4 -.IX Item "--relocated-dump=" -.PD -Displays the contents of the indicated section as a hexadecimal -bytes. A number identifies a particular section by index in the -section table; any other string identifies all sections with that name -in the object file. The contents of the section will be relocated -before they are displayed. -.IP "\fB\-p \fR" 4 -.IX Item "-p " -.PD 0 -.IP "\fB\-\-string\-dump=\fR" 4 -.IX Item "--string-dump=" -.PD -Displays the contents of the indicated section as printable strings. -A number identifies a particular section by index in the section table; -any other string identifies all sections with that name in the object file. -.IP "\fB\-c\fR" 4 -.IX Item "-c" -.PD 0 -.IP "\fB\-\-archive\-index\fR" 4 -.IX Item "--archive-index" -.PD -Displays the file symbol index infomation contained in the header part -of binary archives. Performs the same function as the \fBt\fR -command to \fBar\fR, but without using the \s-1BFD\s0 library. -.IP "\fB\-w[lLiaprmfFsoRt]\fR" 4 -.IX Item "-w[lLiaprmfFsoRt]" -.PD 0 -.IP "\fB\-\-debug\-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]\fR" 4 -.IX Item "--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]" -.PD -Displays the contents of the debug sections in the file, if any are -present. If one of the optional letters or words follows the switch -then only data found in those specific sections will be dumped. -.Sp -Note that there is no single letter option to display the content of -trace sections or .gdb_index. -.Sp -Note: the \fB=decodedline\fR option will display the interpreted -contents of a .debug_line section whereas the \fB=rawline\fR option -dumps the contents in a raw format. -.Sp -Note: the \fB=frames\-interp\fR option will display the interpreted -contents of a .debug_frame section whereas the \fB=frames\fR option -dumps the contents in a raw format. -.Sp -Note: the output from the \fB=info\fR option can also be affected -by the options \fB\-\-dwarf\-depth\fR and \fB\-\-dwarf\-start\fR. -.IP "\fB\-\-dwarf\-depth=\fR\fIn\fR" 4 -.IX Item "--dwarf-depth=n" -Limit the dump of the \f(CW\*(C`.debug_info\*(C'\fR section to \fIn\fR children. -This is only useful with \fB\-\-debug\-dump=info\fR. The default is -to print all DIEs; the special value 0 for \fIn\fR will also have this -effect. -.Sp -With a non-zero value for \fIn\fR, DIEs at or deeper than \fIn\fR -levels will not be printed. The range for \fIn\fR is zero-based. -.IP "\fB\-\-dwarf\-start=\fR\fIn\fR" 4 -.IX Item "--dwarf-start=n" -Print only DIEs beginning with the \s-1DIE\s0 numbered \fIn\fR. This is only -useful with \fB\-\-debug\-dump=info\fR. -.Sp -If specified, this option will suppress printing of any header -information and all DIEs before the \s-1DIE\s0 numbered \fIn\fR. Only -siblings and children of the specified \s-1DIE\s0 will be printed. -.Sp -This can be used in conjunction with \fB\-\-dwarf\-depth\fR. -.IP "\fB\-I\fR" 4 -.IX Item "-I" -.PD 0 -.IP "\fB\-\-histogram\fR" 4 -.IX Item "--histogram" -.PD -Display a histogram of bucket list lengths when displaying the contents -of the symbol tables. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Display the version number of readelf. -.IP "\fB\-W\fR" 4 -.IX Item "-W" -.PD 0 -.IP "\fB\-\-wide\fR" 4 -.IX Item "--wide" -.PD -Don't break output lines to fit into 80 columns. By default -\&\fBreadelf\fR breaks section header and segment listing lines for -64\-bit \s-1ELF\s0 files, so that they fit into 80 columns. This option causes -\&\fBreadelf\fR to print each section header resp. each segment one a -single line, which is far more readable on terminals wider than 80 columns. -.IP "\fB\-H\fR" 4 -.IX Item "-H" -.PD 0 -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -.PD -Display the command line options understood by \fBreadelf\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIobjdump\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/size.1 b/contrib/binutils-2.22/binutils/doc/size.1 deleted file mode 100644 index 79e112f9f4..0000000000 --- a/contrib/binutils-2.22/binutils/doc/size.1 +++ /dev/null @@ -1,268 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "SIZE 1" -.TH SIZE 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -size \- list section sizes and total size. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -size [\fB\-A\fR|\fB\-B\fR|\fB\-\-format=\fR\fIcompatibility\fR] - [\fB\-\-help\fR] - [\fB\-d\fR|\fB\-o\fR|\fB\-x\fR|\fB\-\-radix=\fR\fInumber\fR] - [\fB\-\-common\fR] - [\fB\-t\fR|\fB\-\-totals\fR] - [\fB\-\-target=\fR\fIbfdname\fR] [\fB\-V\fR|\fB\-\-version\fR] - [\fIobjfile\fR...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -The \s-1GNU\s0 \fBsize\fR utility lists the section sizes\-\-\-and the total -size\-\-\-for each of the object or archive files \fIobjfile\fR in its -argument list. By default, one line of output is generated for each -object file or each module in an archive. -.PP -\&\fIobjfile\fR... are the object files to be examined. -If none are specified, the file \f(CW\*(C`a.out\*(C'\fR will be used. -.SH "OPTIONS" -.IX Header "OPTIONS" -The command line options have the following meanings: -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-B\fR" 4 -.IX Item "-B" -.IP "\fB\-\-format=\fR\fIcompatibility\fR" 4 -.IX Item "--format=compatibility" -.PD -Using one of these options, you can choose whether the output from \s-1GNU\s0 -\&\fBsize\fR resembles output from System V \fBsize\fR (using \fB\-A\fR, -or \fB\-\-format=sysv\fR), or Berkeley \fBsize\fR (using \fB\-B\fR, or -\&\fB\-\-format=berkeley\fR). The default is the one-line format similar to -Berkeley's. -.Sp -Here is an example of the Berkeley (default) format of output from -\&\fBsize\fR: -.Sp -.Vb 4 -\& $ size \-\-format=Berkeley ranlib size -\& text data bss dec hex filename -\& 294880 81920 11592 388392 5ed28 ranlib -\& 294880 81920 11888 388688 5ee50 size -.Ve -.Sp -This is the same data, but displayed closer to System V conventions: -.Sp -.Vb 7 -\& $ size \-\-format=SysV ranlib size -\& ranlib : -\& section size addr -\& .text 294880 8192 -\& .data 81920 303104 -\& .bss 11592 385024 -\& Total 388392 -\& -\& -\& size : -\& section size addr -\& .text 294880 8192 -\& .data 81920 303104 -\& .bss 11888 385024 -\& Total 388688 -.Ve -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of acceptable arguments and options. -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.PD 0 -.IP "\fB\-o\fR" 4 -.IX Item "-o" -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.IP "\fB\-\-radix=\fR\fInumber\fR" 4 -.IX Item "--radix=number" -.PD -Using one of these options, you can control whether the size of each -section is given in decimal (\fB\-d\fR, or \fB\-\-radix=10\fR); octal -(\fB\-o\fR, or \fB\-\-radix=8\fR); or hexadecimal (\fB\-x\fR, or -\&\fB\-\-radix=16\fR). In \fB\-\-radix=\fR\fInumber\fR, only the three -values (8, 10, 16) are supported. The total size is always given in two -radices; decimal and hexadecimal for \fB\-d\fR or \fB\-x\fR output, or -octal and hexadecimal if you're using \fB\-o\fR. -.IP "\fB\-\-common\fR" 4 -.IX Item "--common" -Print total size of common symbols in each file. When using Berkeley -format these are included in the bss size. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -.PD 0 -.IP "\fB\-\-totals\fR" 4 -.IX Item "--totals" -.PD -Show totals of all objects listed (Berkeley format listing mode only). -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -Specify that the object-code format for \fIobjfile\fR is -\&\fIbfdname\fR. This option may not be necessary; \fBsize\fR can -automatically recognize many formats. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Display the version number of \fBsize\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/strings.1 b/contrib/binutils-2.22/binutils/doc/strings.1 deleted file mode 100644 index 02b0121c8f..0000000000 --- a/contrib/binutils-2.22/binutils/doc/strings.1 +++ /dev/null @@ -1,257 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "STRINGS 1" -.TH STRINGS 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -strings \- print the strings of printable characters in files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -strings [\fB\-afovV\fR] [\fB\-\fR\fImin-len\fR] - [\fB\-n\fR \fImin-len\fR] [\fB\-\-bytes=\fR\fImin-len\fR] - [\fB\-t\fR \fIradix\fR] [\fB\-\-radix=\fR\fIradix\fR] - [\fB\-e\fR \fIencoding\fR] [\fB\-\-encoding=\fR\fIencoding\fR] - [\fB\-\fR] [\fB\-\-all\fR] [\fB\-\-print\-file\-name\fR] - [\fB\-T\fR \fIbfdname\fR] [\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-\-help\fR] [\fB\-\-version\fR] \fIfile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -For each \fIfile\fR given, \s-1GNU\s0 \fBstrings\fR prints the printable -character sequences that are at least 4 characters long (or the number -given with the options below) and are followed by an unprintable -character. By default, it only prints the strings from the initialized -and loaded sections of object files; for other types of files, it prints -the strings from the whole file. -.PP -\&\fBstrings\fR is mainly useful for determining the contents of non-text -files. -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-all\fR" 4 -.IX Item "--all" -.IP "\fB\-\fR" 4 -.IX Item "-" -.PD -Do not scan only the initialized and loaded sections of object files; -scan the whole files. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -.PD 0 -.IP "\fB\-\-print\-file\-name\fR" 4 -.IX Item "--print-file-name" -.PD -Print the name of the file before each string. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Print a summary of the program usage on the standard output and exit. -.IP "\fB\-\fR\fImin-len\fR" 4 -.IX Item "-min-len" -.PD 0 -.IP "\fB\-n\fR \fImin-len\fR" 4 -.IX Item "-n min-len" -.IP "\fB\-\-bytes=\fR\fImin-len\fR" 4 -.IX Item "--bytes=min-len" -.PD -Print sequences of characters that are at least \fImin-len\fR characters -long, instead of the default 4. -.IP "\fB\-o\fR" 4 -.IX Item "-o" -Like \fB\-t o\fR. Some other versions of \fBstrings\fR have \fB\-o\fR -act like \fB\-t d\fR instead. Since we can not be compatible with both -ways, we simply chose one. -.IP "\fB\-t\fR \fIradix\fR" 4 -.IX Item "-t radix" -.PD 0 -.IP "\fB\-\-radix=\fR\fIradix\fR" 4 -.IX Item "--radix=radix" -.PD -Print the offset within the file before each string. The single -character argument specifies the radix of the offset\-\-\-\fBo\fR for -octal, \fBx\fR for hexadecimal, or \fBd\fR for decimal. -.IP "\fB\-e\fR \fIencoding\fR" 4 -.IX Item "-e encoding" -.PD 0 -.IP "\fB\-\-encoding=\fR\fIencoding\fR" 4 -.IX Item "--encoding=encoding" -.PD -Select the character encoding of the strings that are to be found. -Possible values for \fIencoding\fR are: \fBs\fR = single\-7\-bit\-byte -characters (\s-1ASCII\s0, \s-1ISO\s0 8859, etc., default), \fBS\fR = -single\-8\-bit\-byte characters, \fBb\fR = 16\-bit bigendian, \fBl\fR = -16\-bit littleendian, \fBB\fR = 32\-bit bigendian, \fBL\fR = 32\-bit -littleendian. Useful for finding wide character strings. (\fBl\fR -and \fBb\fR apply to, for example, Unicode \s-1UTF\-16/UCS\-2\s0 encodings). -.IP "\fB\-T\fR \fIbfdname\fR" 4 -.IX Item "-T bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Specify an object code format other than your system's default format. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Print the program version number on the standard output and exit. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fInm\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), \fIreadelf\fR\|(1) -and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/doc/strip.1 b/contrib/binutils-2.22/binutils/doc/strip.1 deleted file mode 100644 index 9720925329..0000000000 --- a/contrib/binutils-2.22/binutils/doc/strip.1 +++ /dev/null @@ -1,392 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "STRIP 1" -.TH STRIP 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -strip \- Discard symbols from object files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -strip [\fB\-F\fR \fIbfdname\fR |\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-I\fR \fIbfdname\fR |\fB\-\-input\-target=\fR\fIbfdname\fR] - [\fB\-O\fR \fIbfdname\fR |\fB\-\-output\-target=\fR\fIbfdname\fR] - [\fB\-s\fR|\fB\-\-strip\-all\fR] - [\fB\-S\fR|\fB\-g\fR|\fB\-d\fR|\fB\-\-strip\-debug\fR] - [\fB\-K\fR \fIsymbolname\fR |\fB\-\-keep\-symbol=\fR\fIsymbolname\fR] - [\fB\-N\fR \fIsymbolname\fR |\fB\-\-strip\-symbol=\fR\fIsymbolname\fR] - [\fB\-w\fR|\fB\-\-wildcard\fR] - [\fB\-x\fR|\fB\-\-discard\-all\fR] [\fB\-X\fR |\fB\-\-discard\-locals\fR] - [\fB\-R\fR \fIsectionname\fR |\fB\-\-remove\-section=\fR\fIsectionname\fR] - [\fB\-o\fR \fIfile\fR] [\fB\-p\fR|\fB\-\-preserve\-dates\fR] - [\fB\-\-keep\-file\-symbols\fR] - [\fB\-\-only\-keep\-debug\fR] - [\fB\-v\fR |\fB\-\-verbose\fR] [\fB\-V\fR|\fB\-\-version\fR] - [\fB\-\-help\fR] [\fB\-\-info\fR] - \fIobjfile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\s-1GNU\s0 \fBstrip\fR discards all symbols from object files -\&\fIobjfile\fR. The list of object files may include archives. -At least one object file must be given. -.PP -\&\fBstrip\fR modifies the files named in its argument, -rather than writing modified copies under different names. -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB\-F\fR \fIbfdname\fR" 4 -.IX Item "-F bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Treat the original \fIobjfile\fR as a file with the object -code format \fIbfdname\fR, and rewrite it in the same format. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of the options to \fBstrip\fR and exit. -.IP "\fB\-\-info\fR" 4 -.IX Item "--info" -Display a list showing all architectures and object formats available. -.IP "\fB\-I\fR \fIbfdname\fR" 4 -.IX Item "-I bfdname" -.PD 0 -.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 -.IX Item "--input-target=bfdname" -.PD -Treat the original \fIobjfile\fR as a file with the object -code format \fIbfdname\fR. -.IP "\fB\-O\fR \fIbfdname\fR" 4 -.IX Item "-O bfdname" -.PD 0 -.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 -.IX Item "--output-target=bfdname" -.PD -Replace \fIobjfile\fR with a file in the output format \fIbfdname\fR. -.IP "\fB\-R\fR \fIsectionname\fR" 4 -.IX Item "-R sectionname" -.PD 0 -.IP "\fB\-\-remove\-section=\fR\fIsectionname\fR" 4 -.IX Item "--remove-section=sectionname" -.PD -Remove any section named \fIsectionname\fR from the output file. This -option may be given more than once. Note that using this option -inappropriately may make the output file unusable. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-strip\-all\fR" 4 -.IX Item "--strip-all" -.PD -Remove all symbols. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.IP "\fB\-\-strip\-debug\fR" 4 -.IX Item "--strip-debug" -.PD -Remove debugging symbols only. -.IP "\fB\-\-strip\-unneeded\fR" 4 -.IX Item "--strip-unneeded" -Remove all symbols that are not needed for relocation processing. -.IP "\fB\-K\fR \fIsymbolname\fR" 4 -.IX Item "-K symbolname" -.PD 0 -.IP "\fB\-\-keep\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--keep-symbol=symbolname" -.PD -When stripping symbols, keep symbol \fIsymbolname\fR even if it would -normally be stripped. This option may be given more than once. -.IP "\fB\-N\fR \fIsymbolname\fR" 4 -.IX Item "-N symbolname" -.PD 0 -.IP "\fB\-\-strip\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--strip-symbol=symbolname" -.PD -Remove symbol \fIsymbolname\fR from the source file. This option may be -given more than once, and may be combined with strip options other than -\&\fB\-K\fR. -.IP "\fB\-o\fR \fIfile\fR" 4 -.IX Item "-o file" -Put the stripped output in \fIfile\fR, rather than replacing the -existing file. When this argument is used, only one \fIobjfile\fR -argument may be specified. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-preserve\-dates\fR" 4 -.IX Item "--preserve-dates" -.PD -Preserve the access and modification dates of the file. -.IP "\fB\-w\fR" 4 -.IX Item "-w" -.PD 0 -.IP "\fB\-\-wildcard\fR" 4 -.IX Item "--wildcard" -.PD -Permit regular expressions in \fIsymbolname\fRs used in other command -line options. The question mark (?), asterisk (*), backslash (\e) and -square brackets ([]) operators can be used anywhere in the symbol -name. If the first character of the symbol name is the exclamation -point (!) then the sense of the switch is reversed for that symbol. -For example: -.Sp -.Vb 1 -\& \-w \-K !foo \-K fo* -.Ve -.Sp -would cause strip to only keep symbols that start with the letters -\&\*(L"fo\*(R", but to discard the symbol \*(L"foo\*(R". -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.PD 0 -.IP "\fB\-\-discard\-all\fR" 4 -.IX Item "--discard-all" -.PD -Remove non-global symbols. -.IP "\fB\-X\fR" 4 -.IX Item "-X" -.PD 0 -.IP "\fB\-\-discard\-locals\fR" 4 -.IX Item "--discard-locals" -.PD -Remove compiler-generated local symbols. -(These usually start with \fBL\fR or \fB.\fR.) -.IP "\fB\-\-keep\-file\-symbols\fR" 4 -.IX Item "--keep-file-symbols" -When stripping a file, perhaps with \fB\-\-strip\-debug\fR or -\&\fB\-\-strip\-unneeded\fR, retain any symbols specifying source file names, -which would otherwise get stripped. -.IP "\fB\-\-only\-keep\-debug\fR" 4 -.IX Item "--only-keep-debug" -Strip a file, removing contents of any sections that would not be -stripped by \fB\-\-strip\-debug\fR and leaving the debugging sections -intact. In \s-1ELF\s0 files, this preserves all note sections in the output. -.Sp -The intention is that this option will be used in conjunction with -\&\fB\-\-add\-gnu\-debuglink\fR to create a two part executable. One a -stripped binary which will occupy less space in \s-1RAM\s0 and in a -distribution and the second a debugging information file which is only -needed if debugging abilities are required. The suggested procedure -to create these files is as follows: -.RS 4 -.IP "1." 4 -.IX Item "1." -\&\f(CW\*(C`foo\*(C'\fR then... -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -create a file containing the debugging info. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -stripped executable. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -to add a link to the debugging info into the stripped executable. -.RE -.RS 4 -.Sp -Note\-\-\-the choice of \f(CW\*(C`.dbg\*(C'\fR as an extension for the debug info -file is arbitrary. Also the \f(CW\*(C`\-\-only\-keep\-debug\*(C'\fR step is -optional. You could instead do this: -.IP "1." 4 -.IX Item "1." -.PD 0 -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.RE -.RS 4 -.PD -.Sp -i.e., the file pointed to by the \fB\-\-add\-gnu\-debuglink\fR can be the -full executable. It does not have to be a file created by the -\&\fB\-\-only\-keep\-debug\fR switch. -.Sp -Note\-\-\-this switch is only intended for use on fully linked files. It -does not make sense to use it on object files where the debugging -information may be incomplete. Besides the gnu_debuglink feature -currently only supports the presence of one filename containing -debugging information, not multiple filenames on a one-per-object-file -basis. -.RE -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number for \fBstrip\fR. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-verbose\fR" 4 -.IX Item "--verbose" -.PD -Verbose output: list all object files modified. In the case of -archives, \fBstrip \-v\fR lists all members of the archive. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/binutils/dwarf-mode.el b/contrib/binutils-2.22/binutils/dwarf-mode.el deleted file mode 100644 index f95319ded5..0000000000 --- a/contrib/binutils-2.22/binutils/dwarf-mode.el +++ /dev/null @@ -1,167 +0,0 @@ -;;; dwarf-mode.el --- Browser for DWARF information. - -;; Version: 1.0 - -;; This file is not part of GNU Emacs, but is distributed under the -;; same terms: - -;; GNU Emacs 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. - -;; GNU Emacs is distributed in the hope that 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 GNU Emacs. If not, see . - -;;; Code: - -(defvar dwarf-objdump-program "objdump") - -(defconst dwarf-font-lock-keywords - '( - ;; Name and linkage name. - ("DW_AT_[a-z_]*name\\s *: .*:\\(.*\\)\\s *$" - (1 font-lock-function-name-face)) - - ("Compilation Unit @ offset 0x[0-9a-f]+" - (0 font-lock-string-face)) - )) - -(defvar dwarf-file nil - "Buffer-local variable holding the file name passed to objdump.") - -;; Expand a "..." to show all the child DIES. NEW-DEPTH controls how -;; deep to display the new dies; `nil' means display all of them. -(defun dwarf-do-insert-substructure (new-depth die) - (let ((inhibit-read-only t)) - (beginning-of-line) - (delete-region (point) (progn - (end-of-line) - (forward-char) - (point))) - (save-excursion - (apply #'call-process dwarf-objdump-program nil (current-buffer) nil - "-Wi" (concat "--dwarf-start=0x" die) - (expand-file-name dwarf-file) - (if new-depth (list (concat "--dwarf-depth=" - (int-to-string new-depth)))))) - (set-buffer-modified-p nil))) - -(defun dwarf-insert-substructure-button (die) - (beginning-of-line) - (unless (looking-at "^ <\\([0-9]+\\)>") - (error "Unrecognized line.")) - (let ((new-depth (1+ (string-to-int (match-string 1))))) - (dwarf-do-insert-substructure new-depth die))) - -(defun dwarf-insert-substructure (arg) - "Expand a `...' to show children of the current DIE. -By default, expands just one level of children. -A prefix argument means expand all children." - (interactive "P") - (beginning-of-line) - (unless (looking-at "^ <\\([0-9]+\\)><\\([0-9a-f]+\\)>") - (error "Unrecognized line.")) - (let ((die (match-string 2))) - (if arg - (dwarf-do-insert-substructure nil die) - (dwarf-insert-substructure-button die)))) - -;; Called when a button is pressed. -;; Either follows a DIE reference, or expands a "...". -(defun dwarf-die-button-action (button) - (let* ((die (button-get button 'die)) - ;; Note that the first number can only be decimal. - (die-rx (concat "^\\s *\\(<[0-9]+>\\)?<" - die ">[^<]")) - (old (point)) - (is-ref (button-get button 'die-ref))) - (if is-ref - (progn - (goto-char (point-min)) - (if (re-search-forward die-rx nil 'move) - (push-mark old) - (goto-char old) - (error "Could not find DIE <0x%s>" die))) - (dwarf-insert-substructure-button die)))) - -;; Button definition. -(define-button-type 'dwarf-die-button - 'follow-link t - 'action #'dwarf-die-button-action) - -;; Helper regexp to match a DIE reference. -(defconst dwarf-die-reference ": \\(<0x\\([0-9a-f]+\\)>\\)\\s *$") - -;; Helper regexp to match a `...' indicating that there are hidden -;; children. -(defconst dwarf-die-more "^ <[0-9]+><\\([0-9a-z]+\\)>: \\([.][.][.]\\)") - -;; jit-lock callback function to fontify a region. This applies the -;; buttons, since AFAICT there is no good way to apply buttons via -;; font-lock. -(defun dwarf-fontify-region (start end) - (save-excursion - (let ((beg-line (progn (goto-char start) (line-beginning-position))) - (end-line (progn (goto-char end) (line-end-position)))) - (goto-char beg-line) - (while (re-search-forward dwarf-die-reference end-line 'move) - (let ((b-start (match-beginning 1)) - (b-end (match-end 1)) - (hex (match-string-no-properties 2))) - (make-text-button b-start b-end :type 'dwarf-die-button - 'die hex 'die-ref t))) - ;; This is a bogus approach. Why can't we make buttons from the - ;; font-lock defaults? - (goto-char beg-line) - (while (re-search-forward dwarf-die-more end-line 'move) - (let ((hex (match-string-no-properties 1)) - (b-start (match-beginning 2)) - (b-end (match-end 2))) - (make-text-button b-start b-end :type 'dwarf-die-button - 'die hex 'die-ref nil)))))) - -;; Run objdump and insert the contents into the buffer. The arguments -;; are the way they are because this is also called as a -;; revert-buffer-function. -(defun dwarf-do-refresh (&rest ignore) - (let ((inhibit-read-only t)) - (erase-buffer) - (save-excursion - (call-process dwarf-objdump-program - nil (current-buffer) nil - "-Wi" "--dwarf-depth=1" - (expand-file-name dwarf-file))) - (set-buffer-modified-p nil))) - -;;;###autoload -(define-derived-mode dwarf-mode special-mode "DWARF" - "Major mode for browsing DWARF output. - -\\{dwarf-mode-map}" - - (set (make-local-variable 'font-lock-defaults) '(dwarf-font-lock-keywords)) - ;; FIXME: we could be smarter and check the file time. - (set (make-local-variable 'revert-buffer-function) #'dwarf-do-refresh) - (jit-lock-register #'dwarf-fontify-region)) - -(define-key dwarf-mode-map [(control ?m)] #'dwarf-insert-substructure) - -;;:###autoload -(defun dwarf-browse (file) - "Invoke `objdump' and put output into a `dwarf-mode' buffer. -This is the main interface to `dwarf-mode'." - (interactive "fFile name: ") - (let* ((base-name (file-name-nondirectory file)) - (buffer (generate-new-buffer (concat "*DWARF for " base-name "*")))) - (pop-to-buffer buffer) - (dwarf-mode) - (set (make-local-variable 'dwarf-file) file) - (dwarf-do-refresh))) - -(provide 'dwarf-mode) diff --git a/contrib/binutils-2.22/binutils/dwarf.c b/contrib/binutils-2.22/binutils/dwarf.c deleted file mode 100644 index 1ee0e336c1..0000000000 --- a/contrib/binutils-2.22/binutils/dwarf.c +++ /dev/null @@ -1,5889 +0,0 @@ -/* dwarf.c -- display DWARF contents of a BFD binary file - Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "libiberty.h" -#include "bfd.h" -#include "bfd_stdint.h" -#include "bucomm.h" -#include "elfcomm.h" -#include "elf/common.h" -#include "dwarf2.h" -#include "dwarf.h" - -static const char *regname (unsigned int regno, int row); - -static int have_frame_base; -static int need_base_address; - -static unsigned int last_pointer_size = 0; -static int warned_about_missing_comp_units = FALSE; - -static unsigned int num_debug_info_entries = 0; -static debug_info *debug_information = NULL; -/* Special value for num_debug_info_entries to indicate - that the .debug_info section could not be loaded/parsed. */ -#define DEBUG_INFO_UNAVAILABLE (unsigned int) -1 - -int eh_addr_size; - -int do_debug_info; -int do_debug_abbrevs; -int do_debug_lines; -int do_debug_pubnames; -int do_debug_pubtypes; -int do_debug_aranges; -int do_debug_ranges; -int do_debug_frames; -int do_debug_frames_interp; -int do_debug_macinfo; -int do_debug_str; -int do_debug_loc; -int do_gdb_index; -int do_trace_info; -int do_trace_abbrevs; -int do_trace_aranges; -int do_wide; - -int dwarf_cutoff_level = -1; -unsigned long dwarf_start_die; - -/* Values for do_debug_lines. */ -#define FLAG_DEBUG_LINES_RAW 1 -#define FLAG_DEBUG_LINES_DECODED 2 - -static int -size_of_encoded_value (int encoding) -{ - switch (encoding & 0x7) - { - default: /* ??? */ - case 0: return eh_addr_size; - case 2: return 2; - case 3: return 4; - case 4: return 8; - } -} - -static dwarf_vma -get_encoded_value (unsigned char *data, - int encoding, - struct dwarf_section *section) -{ - int size = size_of_encoded_value (encoding); - dwarf_vma val; - - if (encoding & DW_EH_PE_signed) - val = byte_get_signed (data, size); - else - val = byte_get (data, size); - - if ((encoding & 0x70) == DW_EH_PE_pcrel) - val += section->address + (data - section->start); - return val; -} - -/* Print a dwarf_vma value (typically an address, offset or length) in - hexadecimal format, followed by a space. The length of the value (and - hence the precision displayed) is determined by the byte_size parameter. */ - -static void -print_dwarf_vma (dwarf_vma val, unsigned byte_size) -{ - static char buff[18]; - int offset = 0; - - /* Printf does not have a way of specifiying a maximum field width for an - integer value, so we print the full value into a buffer and then select - the precision we need. */ -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) -#ifndef __MINGW32__ - snprintf (buff, sizeof (buff), "%16.16llx ", val); -#else - snprintf (buff, sizeof (buff), "%016I64x ", val); -#endif -#else - snprintf (buff, sizeof (buff), "%16.16lx ", val); -#endif - - if (byte_size != 0) - { - if (byte_size > 0 && byte_size <= 8) - offset = 16 - 2 * byte_size; - else - error ("Wrong size in print_dwarf_vma"); - } - - fputs (buff + offset, stdout); -} - -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) -#ifndef __MINGW32__ -#define DWARF_VMA_FMT "ll" -#else -#define DWARF_VMA_FMT "I64" -#endif -#else -#define DWARF_VMA_FMT "l" -#endif - -static const char * -dwarf_vmatoa (const char *fmtch, dwarf_vma value) -{ - /* As dwarf_vmatoa is used more then once in a printf call - for output, we are cycling through an fixed array of pointers - for return address. */ - static int buf_pos = 0; - static struct dwarf_vmatoa_buf - { - char place[64]; - } buf[16]; - char fmt[32]; - char *ret; - - sprintf (fmt, "%%%s%s", DWARF_VMA_FMT, fmtch); - - ret = buf[buf_pos++].place; - buf_pos %= ARRAY_SIZE (buf); - - snprintf (ret, sizeof (buf[0].place), fmt, value); - - return ret; -} - -dwarf_vma -read_leb128 (unsigned char *data, unsigned int *length_return, int sign) -{ - dwarf_vma result = 0; - unsigned int num_read = 0; - unsigned int shift = 0; - unsigned char byte; - - do - { - byte = *data++; - num_read++; - - result |= ((dwarf_vma) (byte & 0x7f)) << shift; - - shift += 7; - - } - while (byte & 0x80); - - if (length_return != NULL) - *length_return = num_read; - - if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -1L << shift; - - return result; -} - -/* Create a signed version to avoid painful typecasts. */ -static dwarf_signed_vma -read_sleb128 (unsigned char *data, unsigned int *length_return) -{ - return (dwarf_signed_vma) read_leb128 (data, length_return, 1); -} - -typedef struct State_Machine_Registers -{ - dwarf_vma address; - unsigned int file; - unsigned int line; - unsigned int column; - int is_stmt; - int basic_block; - unsigned char op_index; - unsigned char end_sequence; -/* This variable hold the number of the last entry seen - in the File Table. */ - unsigned int last_file_entry; -} SMR; - -static SMR state_machine_regs; - -static void -reset_state_machine (int is_stmt) -{ - state_machine_regs.address = 0; - state_machine_regs.op_index = 0; - state_machine_regs.file = 1; - state_machine_regs.line = 1; - state_machine_regs.column = 0; - state_machine_regs.is_stmt = is_stmt; - state_machine_regs.basic_block = 0; - state_machine_regs.end_sequence = 0; - state_machine_regs.last_file_entry = 0; -} - -/* Handled an extend line op. - Returns the number of bytes read. */ - -static int -process_extended_line_op (unsigned char *data, int is_stmt) -{ - unsigned char op_code; - unsigned int bytes_read; - unsigned int len; - unsigned char *name; - dwarf_vma adr; - - len = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - - if (len == 0) - { - warn (_("badly formed extended line op encountered!\n")); - return bytes_read; - } - - len += bytes_read; - op_code = *data++; - - printf (_(" Extended opcode %d: "), op_code); - - switch (op_code) - { - case DW_LNE_end_sequence: - printf (_("End of Sequence\n\n")); - reset_state_machine (is_stmt); - break; - - case DW_LNE_set_address: - adr = byte_get (data, len - bytes_read - 1); - printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr)); - state_machine_regs.address = adr; - state_machine_regs.op_index = 0; - break; - - case DW_LNE_define_file: - printf (_(" define new File Table entry\n")); - printf (_(" Entry\tDir\tTime\tSize\tName\n")); - - printf (" %d\t", ++state_machine_regs.last_file_entry); - name = data; - data += strlen ((char *) data) + 1; - printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - printf ("%s\n\n", name); - break; - - case DW_LNE_set_discriminator: - printf (_("set Discriminator to %s\n"), - dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - break; - - /* HP extensions. */ - case DW_LNE_HP_negate_is_UV_update: - printf ("DW_LNE_HP_negate_is_UV_update\n"); - break; - case DW_LNE_HP_push_context: - printf ("DW_LNE_HP_push_context\n"); - break; - case DW_LNE_HP_pop_context: - printf ("DW_LNE_HP_pop_context\n"); - break; - case DW_LNE_HP_set_file_line_column: - printf ("DW_LNE_HP_set_file_line_column\n"); - break; - case DW_LNE_HP_set_routine_name: - printf ("DW_LNE_HP_set_routine_name\n"); - break; - case DW_LNE_HP_set_sequence: - printf ("DW_LNE_HP_set_sequence\n"); - break; - case DW_LNE_HP_negate_post_semantics: - printf ("DW_LNE_HP_negate_post_semantics\n"); - break; - case DW_LNE_HP_negate_function_exit: - printf ("DW_LNE_HP_negate_function_exit\n"); - break; - case DW_LNE_HP_negate_front_end_logical: - printf ("DW_LNE_HP_negate_front_end_logical\n"); - break; - case DW_LNE_HP_define_proc: - printf ("DW_LNE_HP_define_proc\n"); - break; - case DW_LNE_HP_source_file_correlation: - { - unsigned char *edata = data + len - bytes_read - 1; - - printf ("DW_LNE_HP_source_file_correlation\n"); - - while (data < edata) - { - unsigned int opc; - - opc = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - - switch (opc) - { - case DW_LNE_HP_SFC_formfeed: - printf (" DW_LNE_HP_SFC_formfeed\n"); - break; - case DW_LNE_HP_SFC_set_listing_line: - printf (" DW_LNE_HP_SFC_set_listing_line (%s)\n", - dwarf_vmatoa ("u", - read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - break; - case DW_LNE_HP_SFC_associate: - printf (" DW_LNE_HP_SFC_associate "); - printf (_("(%s"), - dwarf_vmatoa ("u", - read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf (_(",%s"), - dwarf_vmatoa ("u", - read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf (_(",%s)\n"), - dwarf_vmatoa ("u", - read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - break; - default: - printf (" UNKNOW DW_LNE_HP_SFC opcode (%u)\n", opc); - data = edata; - break; - } - } - } - break; - - default: - { - unsigned int rlen = len - bytes_read - 1; - - if (op_code >= DW_LNE_lo_user - /* The test against DW_LNW_hi_user is redundant due to - the limited range of the unsigned char data type used - for op_code. */ - /*&& op_code <= DW_LNE_hi_user*/) - printf (_("user defined: ")); - else - printf (_("UNKNOWN: ")); - printf (_("length %d ["), rlen); - for (; rlen; rlen--) - printf (" %02x", *data++); - printf ("]\n"); - } - break; - } - - return len; -} - -static const char * -fetch_indirect_string (dwarf_vma offset) -{ - struct dwarf_section *section = &debug_displays [str].section; - - if (section->start == NULL) - return _(""); - - /* DWARF sections under Mach-O have non-zero addresses. */ - offset -= section->address; - if (offset > section->size) - { - warn (_("DW_FORM_strp offset too big: %s\n"), - dwarf_vmatoa ("x", offset)); - return _(""); - } - - return (const char *) section->start + offset; -} - -/* FIXME: There are better and more efficient ways to handle - these structures. For now though, I just want something that - is simple to implement. */ -typedef struct abbrev_attr -{ - unsigned long attribute; - unsigned long form; - struct abbrev_attr *next; -} -abbrev_attr; - -typedef struct abbrev_entry -{ - unsigned long entry; - unsigned long tag; - int children; - struct abbrev_attr *first_attr; - struct abbrev_attr *last_attr; - struct abbrev_entry *next; -} -abbrev_entry; - -static abbrev_entry *first_abbrev = NULL; -static abbrev_entry *last_abbrev = NULL; - -static void -free_abbrevs (void) -{ - abbrev_entry *abbrv; - - for (abbrv = first_abbrev; abbrv;) - { - abbrev_entry *next_abbrev = abbrv->next; - abbrev_attr *attr; - - for (attr = abbrv->first_attr; attr;) - { - abbrev_attr *next_attr = attr->next; - - free (attr); - attr = next_attr; - } - - free (abbrv); - abbrv = next_abbrev; - } - - last_abbrev = first_abbrev = NULL; -} - -static void -add_abbrev (unsigned long number, unsigned long tag, int children) -{ - abbrev_entry *entry; - - entry = (abbrev_entry *) malloc (sizeof (*entry)); - if (entry == NULL) - /* ugg */ - return; - - entry->entry = number; - entry->tag = tag; - entry->children = children; - entry->first_attr = NULL; - entry->last_attr = NULL; - entry->next = NULL; - - if (first_abbrev == NULL) - first_abbrev = entry; - else - last_abbrev->next = entry; - - last_abbrev = entry; -} - -static void -add_abbrev_attr (unsigned long attribute, unsigned long form) -{ - abbrev_attr *attr; - - attr = (abbrev_attr *) malloc (sizeof (*attr)); - if (attr == NULL) - /* ugg */ - return; - - attr->attribute = attribute; - attr->form = form; - attr->next = NULL; - - if (last_abbrev->first_attr == NULL) - last_abbrev->first_attr = attr; - else - last_abbrev->last_attr->next = attr; - - last_abbrev->last_attr = attr; -} - -/* Processes the (partial) contents of a .debug_abbrev section. - Returns NULL if the end of the section was encountered. - Returns the address after the last byte read if the end of - an abbreviation set was found. */ - -static unsigned char * -process_abbrev_section (unsigned char *start, unsigned char *end) -{ - if (first_abbrev != NULL) - return NULL; - - while (start < end) - { - unsigned int bytes_read; - unsigned long entry; - unsigned long tag; - unsigned long attribute; - int children; - - entry = read_leb128 (start, & bytes_read, 0); - start += bytes_read; - - /* A single zero is supposed to end the section according - to the standard. If there's more, then signal that to - the caller. */ - if (entry == 0) - return start == end ? NULL : start; - - tag = read_leb128 (start, & bytes_read, 0); - start += bytes_read; - - children = *start++; - - add_abbrev (entry, tag, children); - - do - { - unsigned long form; - - attribute = read_leb128 (start, & bytes_read, 0); - start += bytes_read; - - form = read_leb128 (start, & bytes_read, 0); - start += bytes_read; - - if (attribute != 0) - add_abbrev_attr (attribute, form); - } - while (attribute != 0); - } - - return NULL; -} - -static char * -get_TAG_name (unsigned long tag) -{ - switch (tag) - { - case DW_TAG_padding: return "DW_TAG_padding"; - 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_param: return "DW_TAG_template_type_param"; - case DW_TAG_template_value_param: return "DW_TAG_template_value_param"; - 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_MIPS_loop: return "DW_TAG_MIPS_loop"; - case DW_TAG_format_label: return "DW_TAG_format_label"; - case DW_TAG_function_template: return "DW_TAG_function_template"; - case DW_TAG_class_template: return "DW_TAG_class_template"; - /* DWARF 2.1 values. */ - 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_condition: return "DW_TAG_condition"; - case DW_TAG_shared_type: return "DW_TAG_shared_type"; - /* DWARF 4 values. */ - case DW_TAG_type_unit: return "DW_TAG_type_unit"; - case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type"; - case DW_TAG_template_alias: return "DW_TAG_template_alias"; - /* UPC values. */ - case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type"; - case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type"; - case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type"; - /* GNU values. */ - case DW_TAG_GNU_call_site: return "DW_TAG_GNU_call_site"; - case DW_TAG_GNU_call_site_parameter:return "DW_TAG_GNU_call_site_parameter"; - default: - { - static char buffer[100]; - - snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag); - return buffer; - } - } -} - -static char * -get_FORM_name (unsigned long 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"; - /* DWARF 4 values. */ - case DW_FORM_sec_offset: return "DW_FORM_sec_offset"; - case DW_FORM_exprloc: return "DW_FORM_exprloc"; - case DW_FORM_flag_present: return "DW_FORM_flag_present"; - case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8"; - default: - { - static char buffer[100]; - - snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form); - return buffer; - } - } -} - -static unsigned char * -display_block (unsigned char *data, dwarf_vma length) -{ - printf (_(" %s byte block: "), dwarf_vmatoa ("u", length)); - - while (length --) - printf ("%lx ", (unsigned long) byte_get (data++, 1)); - - return data; -} - -static int -decode_location_expression (unsigned char * data, - unsigned int pointer_size, - unsigned int offset_size, - int dwarf_version, - dwarf_vma length, - dwarf_vma cu_offset, - struct dwarf_section * section) -{ - unsigned op; - unsigned int bytes_read; - dwarf_vma uvalue; - unsigned char *end = data + length; - int need_frame_base = 0; - - while (data < end) - { - op = *data++; - - switch (op) - { - case DW_OP_addr: - printf ("DW_OP_addr: %s", - dwarf_vmatoa ("x", byte_get (data, pointer_size))); - data += pointer_size; - break; - case DW_OP_deref: - printf ("DW_OP_deref"); - break; - case DW_OP_const1u: - printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1)); - break; - case DW_OP_const1s: - printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1)); - break; - case DW_OP_const2u: - printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2)); - data += 2; - break; - case DW_OP_const2s: - printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2)); - data += 2; - break; - case DW_OP_const4u: - printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4)); - data += 4; - break; - case DW_OP_const4s: - printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4)); - data += 4; - break; - case DW_OP_const8u: - printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4), - (unsigned long) byte_get (data + 4, 4)); - data += 8; - break; - case DW_OP_const8s: - printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4), - (long) byte_get (data + 4, 4)); - data += 8; - break; - case DW_OP_constu: - printf ("DW_OP_constu: %s", - dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0))); - data += bytes_read; - break; - case DW_OP_consts: - printf ("DW_OP_consts: %s", - dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read))); - data += bytes_read; - break; - case DW_OP_dup: - printf ("DW_OP_dup"); - break; - case DW_OP_drop: - printf ("DW_OP_drop"); - break; - case DW_OP_over: - printf ("DW_OP_over"); - break; - case DW_OP_pick: - printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1)); - break; - case DW_OP_swap: - printf ("DW_OP_swap"); - break; - case DW_OP_rot: - printf ("DW_OP_rot"); - break; - case DW_OP_xderef: - printf ("DW_OP_xderef"); - break; - case DW_OP_abs: - printf ("DW_OP_abs"); - break; - case DW_OP_and: - printf ("DW_OP_and"); - break; - case DW_OP_div: - printf ("DW_OP_div"); - break; - case DW_OP_minus: - printf ("DW_OP_minus"); - break; - case DW_OP_mod: - printf ("DW_OP_mod"); - break; - case DW_OP_mul: - printf ("DW_OP_mul"); - break; - case DW_OP_neg: - printf ("DW_OP_neg"); - break; - case DW_OP_not: - printf ("DW_OP_not"); - break; - case DW_OP_or: - printf ("DW_OP_or"); - break; - case DW_OP_plus: - printf ("DW_OP_plus"); - break; - case DW_OP_plus_uconst: - printf ("DW_OP_plus_uconst: %s", - dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0))); - data += bytes_read; - break; - case DW_OP_shl: - printf ("DW_OP_shl"); - break; - case DW_OP_shr: - printf ("DW_OP_shr"); - break; - case DW_OP_shra: - printf ("DW_OP_shra"); - break; - case DW_OP_xor: - printf ("DW_OP_xor"); - break; - case DW_OP_bra: - printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2)); - data += 2; - break; - case DW_OP_eq: - printf ("DW_OP_eq"); - break; - case DW_OP_ge: - printf ("DW_OP_ge"); - break; - case DW_OP_gt: - printf ("DW_OP_gt"); - break; - case DW_OP_le: - printf ("DW_OP_le"); - break; - case DW_OP_lt: - printf ("DW_OP_lt"); - break; - case DW_OP_ne: - printf ("DW_OP_ne"); - break; - case DW_OP_skip: - printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2)); - 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: - printf ("DW_OP_lit%d", op - DW_OP_lit0); - 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: - printf ("DW_OP_reg%d (%s)", op - DW_OP_reg0, - regname (op - DW_OP_reg0, 1)); - 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: - printf ("DW_OP_breg%d (%s): %s", - op - DW_OP_breg0, - regname (op - DW_OP_breg0, 1), - dwarf_vmatoa ("d", (dwarf_signed_vma) - read_leb128 (data, &bytes_read, 1))); - data += bytes_read; - break; - - case DW_OP_regx: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_regx: %s (%s)", - dwarf_vmatoa ("u", uvalue), regname (uvalue, 1)); - break; - case DW_OP_fbreg: - need_frame_base = 1; - printf ("DW_OP_fbreg: %s", - dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read))); - data += bytes_read; - break; - case DW_OP_bregx: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_bregx: %s (%s) %s", - dwarf_vmatoa ("u", uvalue), regname (uvalue, 1), - dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read))); - data += bytes_read; - break; - case DW_OP_piece: - printf ("DW_OP_piece: %s", - dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0))); - data += bytes_read; - break; - case DW_OP_deref_size: - printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1)); - break; - case DW_OP_xderef_size: - printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1)); - break; - case DW_OP_nop: - printf ("DW_OP_nop"); - break; - - /* DWARF 3 extensions. */ - case DW_OP_push_object_address: - printf ("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. */ - printf ("DW_OP_call2: <0x%s>", - dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 2) - + cu_offset)); - data += 2; - break; - case DW_OP_call4: - /* XXX: Strictly speaking for 64-bit DWARF3 files - this ought to be an 8-byte wide computation. */ - printf ("DW_OP_call4: <0x%s>", - dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 4) - + cu_offset)); - 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. */ - if (dwarf_version == -1) - { - printf (_("(DW_OP_call_ref in frame info)")); - /* No way to tell where the next op is, so just bail. */ - return need_frame_base; - } - if (dwarf_version == 2) - { - printf ("DW_OP_call_ref: <0x%s>", - dwarf_vmatoa ("x", byte_get (data, pointer_size))); - data += pointer_size; - } - else - { - printf ("DW_OP_call_ref: <0x%s>", - dwarf_vmatoa ("x", byte_get (data, offset_size))); - data += offset_size; - } - break; - case DW_OP_form_tls_address: - printf ("DW_OP_form_tls_address"); - break; - case DW_OP_call_frame_cfa: - printf ("DW_OP_call_frame_cfa"); - break; - case DW_OP_bit_piece: - printf ("DW_OP_bit_piece: "); - printf ("size: %s ", - dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0))); - data += bytes_read; - printf ("offset: %s ", - dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0))); - data += bytes_read; - break; - - /* DWARF 4 extensions. */ - case DW_OP_stack_value: - printf ("DW_OP_stack_value"); - break; - - case DW_OP_implicit_value: - printf ("DW_OP_implicit_value"); - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - display_block (data, uvalue); - data += uvalue; - break; - - /* GNU extensions. */ - case DW_OP_GNU_push_tls_address: - printf ("DW_OP_GNU_push_tls_address or DW_OP_HP_unknown"); - break; - case DW_OP_GNU_uninit: - printf ("DW_OP_GNU_uninit"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_GNU_encoded_addr: - { - int encoding; - dwarf_vma addr; - - encoding = *data++; - addr = get_encoded_value (data, encoding, section); - data += size_of_encoded_value (encoding); - - printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", encoding); - print_dwarf_vma (addr, pointer_size); - } - break; - case DW_OP_GNU_implicit_pointer: - /* XXX: Strictly speaking for 64-bit DWARF3 files - this ought to be an 8-byte wide computation. */ - if (dwarf_version == -1) - { - printf (_("(DW_OP_GNU_implicit_pointer in frame info)")); - /* No way to tell where the next op is, so just bail. */ - return need_frame_base; - } - if (dwarf_version == 2) - { - printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s", - dwarf_vmatoa ("x", byte_get (data, pointer_size)), - dwarf_vmatoa ("d", read_sleb128 (data + pointer_size, - &bytes_read))); - data += pointer_size + bytes_read; - } - else - { - printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s", - dwarf_vmatoa ("x", byte_get (data, offset_size)), - dwarf_vmatoa ("d", read_sleb128 (data + offset_size, - &bytes_read))); - data += offset_size + bytes_read; - } - break; - case DW_OP_GNU_entry_value: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_entry_value: ("); - if (decode_location_expression (data, pointer_size, offset_size, - dwarf_version, uvalue, - cu_offset, section)) - need_frame_base = 1; - putchar (')'); - data += uvalue; - break; - case DW_OP_GNU_const_type: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_const_type: <0x%s> ", - dwarf_vmatoa ("x", cu_offset + uvalue)); - uvalue = byte_get (data++, 1); - display_block (data, uvalue); - data += uvalue; - break; - case DW_OP_GNU_regval_type: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_regval_type: %s (%s)", - dwarf_vmatoa ("u", uvalue), regname (uvalue, 1)); - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue)); - break; - case DW_OP_GNU_deref_type: - printf ("DW_OP_GNU_deref_type: %ld", (long) byte_get (data++, 1)); - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue)); - break; - case DW_OP_GNU_convert: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_convert <0x%s>", - dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0)); - break; - case DW_OP_GNU_reinterpret: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_reinterpret <0x%s>", - dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0)); - break; - case DW_OP_GNU_parameter_ref: - printf ("DW_OP_GNU_parameter_ref: <0x%s>", - dwarf_vmatoa ("x", cu_offset + byte_get (data, 4))); - data += 4; - break; - - /* HP extensions. */ - case DW_OP_HP_is_value: - printf ("DW_OP_HP_is_value"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_HP_fltconst4: - printf ("DW_OP_HP_fltconst4"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_HP_fltconst8: - printf ("DW_OP_HP_fltconst8"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_HP_mod_range: - printf ("DW_OP_HP_mod_range"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_HP_unmod_range: - printf ("DW_OP_HP_unmod_range"); - /* FIXME: Is there data associated with this OP ? */ - break; - case DW_OP_HP_tls: - printf ("DW_OP_HP_tls"); - /* FIXME: Is there data associated with this OP ? */ - break; - - /* PGI (STMicroelectronics) extensions. */ - case DW_OP_PGI_omp_thread_num: - /* Pushes the thread number for the current thread as it would be - returned by the standard OpenMP library function: - omp_get_thread_num(). The "current thread" is the thread for - which the expression is being evaluated. */ - printf ("DW_OP_PGI_omp_thread_num"); - break; - - default: - if (op >= DW_OP_lo_user - && op <= DW_OP_hi_user) - printf (_("(User defined location op)")); - else - printf (_("(Unknown location op)")); - /* No way to tell where the next op is, so just bail. */ - return need_frame_base; - } - - /* Separate the ops. */ - if (data < end) - printf ("; "); - } - - return need_frame_base; -} - -static unsigned char * -read_and_display_attr_value (unsigned long attribute, - unsigned long form, - unsigned char * data, - dwarf_vma cu_offset, - dwarf_vma pointer_size, - dwarf_vma offset_size, - int dwarf_version, - debug_info * debug_info_p, - int do_loc, - struct dwarf_section * section) -{ - dwarf_vma uvalue = 0; - unsigned char *block_start = NULL; - unsigned char * orig_data = data; - unsigned int bytes_read; - - switch (form) - { - default: - break; - - case DW_FORM_ref_addr: - if (dwarf_version == 2) - { - uvalue = byte_get (data, pointer_size); - data += pointer_size; - } - else if (dwarf_version == 3 || dwarf_version == 4) - { - uvalue = byte_get (data, offset_size); - data += offset_size; - } - else - error (_("Internal error: DWARF version is not 2, 3 or 4.\n")); - - break; - - case DW_FORM_addr: - uvalue = byte_get (data, pointer_size); - data += pointer_size; - break; - - case DW_FORM_strp: - case DW_FORM_sec_offset: - uvalue = byte_get (data, offset_size); - data += offset_size; - break; - - case DW_FORM_flag_present: - uvalue = 1; - break; - - case DW_FORM_ref1: - case DW_FORM_flag: - case DW_FORM_data1: - uvalue = byte_get (data++, 1); - break; - - case DW_FORM_ref2: - case DW_FORM_data2: - uvalue = byte_get (data, 2); - data += 2; - break; - - case DW_FORM_ref4: - case DW_FORM_data4: - uvalue = byte_get (data, 4); - data += 4; - break; - - case DW_FORM_sdata: - uvalue = read_leb128 (data, & bytes_read, 1); - data += bytes_read; - break; - - case DW_FORM_ref_udata: - case DW_FORM_udata: - uvalue = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - break; - - case DW_FORM_indirect: - form = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - if (!do_loc) - printf (" %s", get_FORM_name (form)); - return read_and_display_attr_value (attribute, form, data, - cu_offset, pointer_size, - offset_size, dwarf_version, - debug_info_p, do_loc, - section); - } - - switch (form) - { - case DW_FORM_ref_addr: - if (!do_loc) - printf (" <0x%s>", dwarf_vmatoa ("x",uvalue)); - break; - - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref_udata: - if (!do_loc) - printf (" <0x%s>", dwarf_vmatoa ("x", uvalue + cu_offset)); - break; - - case DW_FORM_data4: - case DW_FORM_addr: - case DW_FORM_sec_offset: - if (!do_loc) - printf (" 0x%s", dwarf_vmatoa ("x", uvalue)); - break; - - case DW_FORM_flag_present: - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_sdata: - case DW_FORM_udata: - if (!do_loc) - printf (" %s", dwarf_vmatoa ("d", uvalue)); - break; - - case DW_FORM_ref8: - case DW_FORM_data8: - if (!do_loc) - { - uvalue = byte_get (data, 4); - printf (" 0x%s", dwarf_vmatoa ("x", uvalue)); - printf (" 0x%lx", (unsigned long) byte_get (data + 4, 4)); - } - if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0) - { - if (sizeof (uvalue) == 8) - uvalue = byte_get (data, 8); - else - error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n")); - } - data += 8; - break; - - case DW_FORM_string: - if (!do_loc) - printf (" %s", data); - data += strlen ((char *) data) + 1; - break; - - case DW_FORM_block: - case DW_FORM_exprloc: - uvalue = read_leb128 (data, & bytes_read, 0); - block_start = data + bytes_read; - if (do_loc) - data = block_start + uvalue; - else - data = display_block (block_start, uvalue); - break; - - case DW_FORM_block1: - uvalue = byte_get (data, 1); - block_start = data + 1; - if (do_loc) - data = block_start + uvalue; - else - data = display_block (block_start, uvalue); - break; - - case DW_FORM_block2: - uvalue = byte_get (data, 2); - block_start = data + 2; - if (do_loc) - data = block_start + uvalue; - else - data = display_block (block_start, uvalue); - break; - - case DW_FORM_block4: - uvalue = byte_get (data, 4); - block_start = data + 4; - if (do_loc) - data = block_start + uvalue; - else - data = display_block (block_start, uvalue); - break; - - case DW_FORM_strp: - if (!do_loc) - printf (_(" (indirect string, offset: 0x%s): %s"), - dwarf_vmatoa ("x", uvalue), - fetch_indirect_string (uvalue)); - break; - - case DW_FORM_indirect: - /* Handled above. */ - break; - - case DW_FORM_ref_sig8: - if (!do_loc) - { - int i; - printf (" signature: "); - for (i = 0; i < 8; i++) - { - printf ("%02x", (unsigned) byte_get (data, 1)); - data += 1; - } - } - else - data += 8; - break; - - default: - warn (_("Unrecognized form: %lu\n"), form); - break; - } - - if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0 - && debug_info_p != NULL) - { - switch (attribute) - { - case DW_AT_frame_base: - have_frame_base = 1; - case DW_AT_location: - case DW_AT_string_length: - case DW_AT_return_addr: - case DW_AT_data_member_location: - case DW_AT_vtable_elem_location: - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: - case DW_AT_GNU_call_site_value: - case DW_AT_GNU_call_site_data_value: - case DW_AT_GNU_call_site_target: - case DW_AT_GNU_call_site_target_clobbered: - if ((dwarf_version < 4 - && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) - { - /* Process location list. */ - unsigned int lmax = debug_info_p->max_loc_offsets; - unsigned int num = debug_info_p->num_loc_offsets; - - if (lmax == 0 || num >= lmax) - { - lmax += 1024; - debug_info_p->loc_offsets = (dwarf_vma *) - xcrealloc (debug_info_p->loc_offsets, - lmax, sizeof (*debug_info_p->loc_offsets)); - debug_info_p->have_frame_base = (int *) - xcrealloc (debug_info_p->have_frame_base, - lmax, sizeof (*debug_info_p->have_frame_base)); - debug_info_p->max_loc_offsets = lmax; - } - debug_info_p->loc_offsets [num] = uvalue; - debug_info_p->have_frame_base [num] = have_frame_base; - debug_info_p->num_loc_offsets++; - } - break; - - case DW_AT_low_pc: - if (need_base_address) - debug_info_p->base_address = uvalue; - break; - - case DW_AT_ranges: - if ((dwarf_version < 4 - && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) - { - /* Process range list. */ - unsigned int lmax = debug_info_p->max_range_lists; - unsigned int num = debug_info_p->num_range_lists; - - if (lmax == 0 || num >= lmax) - { - lmax += 1024; - debug_info_p->range_lists = (dwarf_vma *) - xcrealloc (debug_info_p->range_lists, - lmax, sizeof (*debug_info_p->range_lists)); - debug_info_p->max_range_lists = lmax; - } - debug_info_p->range_lists [num] = uvalue; - debug_info_p->num_range_lists++; - } - break; - - default: - break; - } - } - - if (do_loc || attribute == 0) - return data; - - /* For some attributes we can display further information. */ - printf ("\t"); - - switch (attribute) - { - case DW_AT_inline: - switch (uvalue) - { - case DW_INL_not_inlined: - printf (_("(not inlined)")); - break; - case DW_INL_inlined: - printf (_("(inlined)")); - break; - case DW_INL_declared_not_inlined: - printf (_("(declared as inline but ignored)")); - break; - case DW_INL_declared_inlined: - printf (_("(declared as inline and inlined)")); - break; - default: - printf (_(" (Unknown inline attribute value: %s)"), - dwarf_vmatoa ("x", uvalue)); - break; - } - break; - - case DW_AT_language: - switch (uvalue) - { - /* Ordered by the numeric value of these constants. */ - case DW_LANG_C89: printf ("(ANSI C)"); break; - case DW_LANG_C: printf ("(non-ANSI C)"); break; - case DW_LANG_Ada83: printf ("(Ada)"); break; - case DW_LANG_C_plus_plus: printf ("(C++)"); break; - case DW_LANG_Cobol74: printf ("(Cobol 74)"); break; - case DW_LANG_Cobol85: printf ("(Cobol 85)"); break; - case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break; - case DW_LANG_Fortran90: printf ("(Fortran 90)"); break; - case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break; - case DW_LANG_Modula2: printf ("(Modula 2)"); break; - /* DWARF 2.1 values. */ - case DW_LANG_Java: printf ("(Java)"); break; - case DW_LANG_C99: printf ("(ANSI C99)"); break; - case DW_LANG_Ada95: printf ("(ADA 95)"); break; - case DW_LANG_Fortran95: printf ("(Fortran 95)"); break; - /* DWARF 3 values. */ - case DW_LANG_PLI: printf ("(PLI)"); break; - case DW_LANG_ObjC: printf ("(Objective C)"); break; - case DW_LANG_ObjC_plus_plus: printf ("(Objective C++)"); break; - case DW_LANG_UPC: printf ("(Unified Parallel C)"); break; - case DW_LANG_D: printf ("(D)"); break; - /* DWARF 4 values. */ - case DW_LANG_Python: printf ("(Python)"); break; - /* MIPS extension. */ - case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break; - /* UPC extension. */ - case DW_LANG_Upc: printf ("(Unified Parallel C)"); break; - default: - if (uvalue >= DW_LANG_lo_user && uvalue <= DW_LANG_hi_user) - printf ("(implementation defined: %s)", - dwarf_vmatoa ("x", uvalue)); - else - printf ("(Unknown: %s)", dwarf_vmatoa ("x", uvalue)); - break; - } - break; - - case DW_AT_encoding: - switch (uvalue) - { - case DW_ATE_void: printf ("(void)"); break; - case DW_ATE_address: printf ("(machine address)"); break; - case DW_ATE_boolean: printf ("(boolean)"); break; - case DW_ATE_complex_float: printf ("(complex float)"); break; - case DW_ATE_float: printf ("(float)"); break; - case DW_ATE_signed: printf ("(signed)"); break; - case DW_ATE_signed_char: printf ("(signed char)"); break; - case DW_ATE_unsigned: printf ("(unsigned)"); break; - case DW_ATE_unsigned_char: printf ("(unsigned char)"); break; - /* DWARF 2.1 values: */ - case DW_ATE_imaginary_float: printf ("(imaginary float)"); break; - case DW_ATE_decimal_float: printf ("(decimal float)"); break; - /* DWARF 3 values: */ - case DW_ATE_packed_decimal: printf ("(packed_decimal)"); break; - case DW_ATE_numeric_string: printf ("(numeric_string)"); break; - case DW_ATE_edited: printf ("(edited)"); break; - case DW_ATE_signed_fixed: printf ("(signed_fixed)"); break; - case DW_ATE_unsigned_fixed: printf ("(unsigned_fixed)"); break; - /* HP extensions: */ - case DW_ATE_HP_float80: printf ("(HP_float80)"); break; - case DW_ATE_HP_complex_float80: printf ("(HP_complex_float80)"); break; - case DW_ATE_HP_float128: printf ("(HP_float128)"); break; - case DW_ATE_HP_complex_float128:printf ("(HP_complex_float128)"); break; - case DW_ATE_HP_floathpintel: printf ("(HP_floathpintel)"); break; - case DW_ATE_HP_imaginary_float80: printf ("(HP_imaginary_float80)"); break; - case DW_ATE_HP_imaginary_float128: printf ("(HP_imaginary_float128)"); break; - - default: - if (uvalue >= DW_ATE_lo_user - && uvalue <= DW_ATE_hi_user) - printf ("(user defined type)"); - else - printf ("(unknown type)"); - break; - } - break; - - case DW_AT_accessibility: - switch (uvalue) - { - case DW_ACCESS_public: printf ("(public)"); break; - case DW_ACCESS_protected: printf ("(protected)"); break; - case DW_ACCESS_private: printf ("(private)"); break; - default: - printf ("(unknown accessibility)"); - break; - } - break; - - case DW_AT_visibility: - switch (uvalue) - { - case DW_VIS_local: printf ("(local)"); break; - case DW_VIS_exported: printf ("(exported)"); break; - case DW_VIS_qualified: printf ("(qualified)"); break; - default: printf ("(unknown visibility)"); break; - } - break; - - case DW_AT_virtuality: - switch (uvalue) - { - case DW_VIRTUALITY_none: printf ("(none)"); break; - case DW_VIRTUALITY_virtual: printf ("(virtual)"); break; - case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break; - default: printf ("(unknown virtuality)"); break; - } - break; - - case DW_AT_identifier_case: - switch (uvalue) - { - case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; - case DW_ID_up_case: printf ("(up_case)"); break; - case DW_ID_down_case: printf ("(down_case)"); break; - case DW_ID_case_insensitive: printf ("(case_insensitive)"); break; - default: printf ("(unknown case)"); break; - } - break; - - case DW_AT_calling_convention: - switch (uvalue) - { - case DW_CC_normal: printf ("(normal)"); break; - case DW_CC_program: printf ("(program)"); break; - case DW_CC_nocall: printf ("(nocall)"); break; - default: - if (uvalue >= DW_CC_lo_user - && uvalue <= DW_CC_hi_user) - printf ("(user defined)"); - else - printf ("(unknown convention)"); - } - break; - - case DW_AT_ordering: - switch (uvalue) - { - case -1: printf ("(undefined)"); break; - case 0: printf ("(row major)"); break; - case 1: printf ("(column major)"); break; - } - break; - - case DW_AT_frame_base: - have_frame_base = 1; - case DW_AT_location: - case DW_AT_string_length: - case DW_AT_return_addr: - case DW_AT_data_member_location: - case DW_AT_vtable_elem_location: - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: - case DW_AT_GNU_call_site_value: - case DW_AT_GNU_call_site_data_value: - case DW_AT_GNU_call_site_target: - case DW_AT_GNU_call_site_target_clobbered: - if ((dwarf_version < 4 - && (form == DW_FORM_data4 || form == DW_FORM_data8)) - || form == DW_FORM_sec_offset) - printf (_("(location list)")); - /* Fall through. */ - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_stride: - case DW_AT_upper_bound: - case DW_AT_lower_bound: - if (block_start) - { - int need_frame_base; - - printf ("("); - need_frame_base = decode_location_expression (block_start, - pointer_size, - offset_size, - dwarf_version, - uvalue, - cu_offset, section); - printf (")"); - if (need_frame_base && !have_frame_base) - printf (_(" [without DW_AT_frame_base]")); - } - break; - - case DW_AT_import: - { - if (form == DW_FORM_ref_sig8) - break; - - if (form == DW_FORM_ref1 - || form == DW_FORM_ref2 - || form == DW_FORM_ref4) - uvalue += cu_offset; - - if (uvalue >= section->size) - warn (_("Offset %s used as value for DW_AT_import attribute of DIE at offset %lx is too big.\n"), - dwarf_vmatoa ("x", uvalue), - (unsigned long) (orig_data - section->start)); - else - { - unsigned long abbrev_number; - abbrev_entry * entry; - - abbrev_number = read_leb128 (section->start + uvalue, NULL, 0); - - printf ("[Abbrev Number: %ld", abbrev_number); - for (entry = first_abbrev; entry != NULL; entry = entry->next) - if (entry->entry == abbrev_number) - break; - if (entry != NULL) - printf (" (%s)", get_TAG_name (entry->tag)); - printf ("]"); - } - } - break; - - default: - break; - } - - return data; -} - -static char * -get_AT_name (unsigned long attribute) -{ - switch (attribute) - { - 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_stride_size: return "DW_AT_stride_size"; - 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_items: return "DW_AT_namelist_items"; - 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"; - /* DWARF 2.1 values. */ - 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_stride: return "DW_AT_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"; - /* DWARF 4 values. */ - case DW_AT_signature: return "DW_AT_signature"; - case DW_AT_main_subprogram: return "DW_AT_main_subprogram"; - case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset"; - case DW_AT_const_expr: return "DW_AT_const_expr"; - case DW_AT_enum_class: return "DW_AT_enum_class"; - case DW_AT_linkage_name: return "DW_AT_linkage_name"; - - /* HP and SGI/MIPS extensions. */ - case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; - case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; - case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; - case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor"; - case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth"; - case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; - case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride"; - case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name"; - case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin"; - case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; - - /* HP Extensions. */ - case DW_AT_HP_block_index: return "DW_AT_HP_block_index"; - case DW_AT_HP_actuals_stmt_list: return "DW_AT_HP_actuals_stmt_list"; - case DW_AT_HP_proc_per_section: return "DW_AT_HP_proc_per_section"; - case DW_AT_HP_raw_data_ptr: return "DW_AT_HP_raw_data_ptr"; - case DW_AT_HP_pass_by_reference: return "DW_AT_HP_pass_by_reference"; - case DW_AT_HP_opt_level: return "DW_AT_HP_opt_level"; - case DW_AT_HP_prof_version_id: return "DW_AT_HP_prof_version_id"; - case DW_AT_HP_opt_flags: return "DW_AT_HP_opt_flags"; - case DW_AT_HP_cold_region_low_pc: return "DW_AT_HP_cold_region_low_pc"; - case DW_AT_HP_cold_region_high_pc: return "DW_AT_HP_cold_region_high_pc"; - case DW_AT_HP_all_variables_modifiable: return "DW_AT_HP_all_variables_modifiable"; - case DW_AT_HP_linkage_name: return "DW_AT_HP_linkage_name"; - case DW_AT_HP_prof_flags: return "DW_AT_HP_prof_flags"; - - /* One value is shared by the MIPS and HP extensions: */ - case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable"; - - /* GNU extensions. */ - case DW_AT_sf_names: return "DW_AT_sf_names"; - case DW_AT_src_info: return "DW_AT_src_info"; - case DW_AT_mac_info: return "DW_AT_mac_info"; - case DW_AT_src_coords: return "DW_AT_src_coords"; - case DW_AT_body_begin: return "DW_AT_body_begin"; - case DW_AT_body_end: return "DW_AT_body_end"; - case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; - case DW_AT_GNU_guarded_by: return "DW_AT_GNU_guarded_by"; - case DW_AT_GNU_pt_guarded_by: return "DW_AT_GNU_pt_guarded_by"; - case DW_AT_GNU_guarded: return "DW_AT_GNU_guarded"; - case DW_AT_GNU_pt_guarded: return "DW_AT_GNU_pt_guarded"; - case DW_AT_GNU_locks_excluded: return "DW_AT_GNU_locks_excluded"; - case DW_AT_GNU_exclusive_locks_required: return "DW_AT_GNU_exclusive_locks_required"; - case DW_AT_GNU_shared_locks_required: return "DW_AT_GNU_shared_locks_required"; - case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature"; - case DW_AT_use_GNAT_descriptive_type: return "DW_AT_use_GNAT_descriptive_type"; - case DW_AT_GNAT_descriptive_type: return "DW_AT_GNAT_descriptive_type"; - case DW_AT_GNU_call_site_value: return "DW_AT_GNU_call_site_value"; - case DW_AT_GNU_call_site_data_value: return "DW_AT_GNU_call_site_data_value"; - case DW_AT_GNU_call_site_target: return "DW_AT_GNU_call_site_target"; - case DW_AT_GNU_call_site_target_clobbered: return "DW_AT_GNU_call_site_target_clobbered"; - case DW_AT_GNU_tail_call: return "DW_AT_GNU_tail_call"; - case DW_AT_GNU_all_tail_call_sites: return "DW_AT_GNU_all_tail_call_sites"; - case DW_AT_GNU_all_call_sites: return "DW_AT_GNU_all_call_sites"; - case DW_AT_GNU_all_source_call_sites: return "DW_AT_GNU_all_source_call_sites"; - case DW_AT_GNU_macros: return "DW_AT_GNU_macros"; - - /* UPC extension. */ - case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled"; - - /* PGI (STMicroelectronics) extensions. */ - case DW_AT_PGI_lbase: return "DW_AT_PGI_lbase"; - case DW_AT_PGI_soffset: return "DW_AT_PGI_soffset"; - case DW_AT_PGI_lstride: return "DW_AT_PGI_lstride"; - - default: - { - static char buffer[100]; - - snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"), - attribute); - return buffer; - } - } -} - -static unsigned char * -read_and_display_attr (unsigned long attribute, - unsigned long form, - unsigned char * data, - dwarf_vma cu_offset, - dwarf_vma pointer_size, - dwarf_vma offset_size, - int dwarf_version, - debug_info * debug_info_p, - int do_loc, - struct dwarf_section * section) -{ - if (!do_loc) - printf (" %-18s:", get_AT_name (attribute)); - data = read_and_display_attr_value (attribute, form, data, cu_offset, - pointer_size, offset_size, - dwarf_version, debug_info_p, - do_loc, section); - if (!do_loc) - printf ("\n"); - return data; -} - - -/* Process the contents of a .debug_info section. If do_loc is non-zero - then we are scanning for location lists and we do not want to display - anything to the user. If do_types is non-zero, we are processing - a .debug_types section instead of a .debug_info section. */ - -static int -process_debug_info (struct dwarf_section *section, - void *file, - enum dwarf_section_display_enum abbrev_sec, - int do_loc, - int do_types) -{ - unsigned char *start = section->start; - unsigned char *end = start + section->size; - unsigned char *section_begin; - unsigned int unit; - unsigned int num_units = 0; - - if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0 - && ! do_types) - { - dwarf_vma length; - - /* First scan the section to get the number of comp units. */ - for (section_begin = start, num_units = 0; section_begin < end; - num_units ++) - { - /* Read the first 4 bytes. For a 32-bit DWARF section, this - will be the length. For a 64-bit DWARF section, it'll be - the escape code 0xffffffff followed by an 8 byte length. */ - length = byte_get (section_begin, 4); - - if (length == 0xffffffff) - { - length = byte_get (section_begin + 4, 8); - section_begin += length + 12; - } - else if (length >= 0xfffffff0 && length < 0xffffffff) - { - warn (_("Reserved length value (0x%s) found in section %s\n"), - dwarf_vmatoa ("x", length), section->name); - return 0; - } - else - section_begin += length + 4; - - /* Negative values are illegal, they may even cause infinite - looping. This can happen if we can't accurately apply - relocations to an object file. */ - if ((signed long) length <= 0) - { - warn (_("Corrupt unit length (0x%s) found in section %s\n"), - dwarf_vmatoa ("x", length), section->name); - return 0; - } - } - - if (num_units == 0) - { - error (_("No comp units in %s section ?"), section->name); - return 0; - } - - /* Then allocate an array to hold the information. */ - debug_information = (debug_info *) cmalloc (num_units, - sizeof (* debug_information)); - if (debug_information == NULL) - { - error (_("Not enough memory for a debug info array of %u entries"), - num_units); - return 0; - } - } - - if (!do_loc) - { - if (dwarf_start_die == 0) - printf (_("Contents of the %s section:\n\n"), section->name); - - load_debug_section (str, file); - } - - load_debug_section (abbrev_sec, file); - if (debug_displays [abbrev_sec].section.start == NULL) - { - warn (_("Unable to locate %s section!\n"), - debug_displays [abbrev_sec].section.name); - return 0; - } - - for (section_begin = start, unit = 0; start < end; unit++) - { - DWARF2_Internal_CompUnit compunit; - unsigned char *hdrptr; - unsigned char *tags; - int level, last_level, saved_level; - dwarf_vma cu_offset; - int offset_size; - int initial_length_size; - unsigned char signature[8] = { 0 }; - dwarf_vma type_offset = 0; - - hdrptr = start; - - compunit.cu_length = byte_get (hdrptr, 4); - hdrptr += 4; - - if (compunit.cu_length == 0xffffffff) - { - compunit.cu_length = byte_get (hdrptr, 8); - hdrptr += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - compunit.cu_version = byte_get (hdrptr, 2); - hdrptr += 2; - - cu_offset = start - section_begin; - - compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size); - hdrptr += offset_size; - - compunit.cu_pointer_size = byte_get (hdrptr, 1); - hdrptr += 1; - - if (do_types) - { - int i; - - for (i = 0; i < 8; i++) - { - signature[i] = byte_get (hdrptr, 1); - hdrptr += 1; - } - - type_offset = byte_get (hdrptr, offset_size); - hdrptr += offset_size; - } - - if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0 - && ! do_types) - { - debug_information [unit].cu_offset = cu_offset; - debug_information [unit].pointer_size - = compunit.cu_pointer_size; - debug_information [unit].offset_size = offset_size; - debug_information [unit].dwarf_version = compunit.cu_version; - debug_information [unit].base_address = 0; - debug_information [unit].loc_offsets = NULL; - debug_information [unit].have_frame_base = NULL; - debug_information [unit].max_loc_offsets = 0; - debug_information [unit].num_loc_offsets = 0; - debug_information [unit].range_lists = NULL; - debug_information [unit].max_range_lists= 0; - debug_information [unit].num_range_lists = 0; - } - - if (!do_loc && dwarf_start_die == 0) - { - printf (_(" Compilation Unit @ offset 0x%s:\n"), - dwarf_vmatoa ("x", cu_offset)); - printf (_(" Length: 0x%s (%s)\n"), - dwarf_vmatoa ("x", compunit.cu_length), - offset_size == 8 ? "64-bit" : "32-bit"); - printf (_(" Version: %d\n"), compunit.cu_version); - printf (_(" Abbrev Offset: %s\n"), - dwarf_vmatoa ("d", compunit.cu_abbrev_offset)); - printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size); - if (do_types) - { - int i; - printf (_(" Signature: ")); - for (i = 0; i < 8; i++) - printf ("%02x", signature[i]); - printf ("\n"); - printf (_(" Type Offset: 0x%s\n"), - dwarf_vmatoa ("x", type_offset)); - } - } - - if (cu_offset + compunit.cu_length + initial_length_size - > section->size) - { - warn (_("Debug info is corrupted, length of CU at %s" - " extends beyond end of section (length = %s)\n"), - dwarf_vmatoa ("x", cu_offset), - dwarf_vmatoa ("x", compunit.cu_length)); - break; - } - tags = hdrptr; - start += compunit.cu_length + initial_length_size; - - if (compunit.cu_version != 2 - && compunit.cu_version != 3 - && compunit.cu_version != 4) - { - warn (_("CU at offset %s contains corrupt or " - "unsupported version number: %d.\n"), - dwarf_vmatoa ("x", cu_offset), compunit.cu_version); - continue; - } - - free_abbrevs (); - - /* Process the abbrevs used by this compilation unit. DWARF - sections under Mach-O have non-zero addresses. */ - if (compunit.cu_abbrev_offset >= debug_displays [abbrev_sec].section.size) - warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"), - (unsigned long) compunit.cu_abbrev_offset, - (unsigned long) debug_displays [abbrev_sec].section.size); - else - process_abbrev_section - ((unsigned char *) debug_displays [abbrev_sec].section.start - + compunit.cu_abbrev_offset, - (unsigned char *) debug_displays [abbrev_sec].section.start - + debug_displays [abbrev_sec].section.size); - - level = 0; - last_level = level; - saved_level = -1; - while (tags < start) - { - unsigned int bytes_read; - unsigned long abbrev_number; - unsigned long die_offset; - abbrev_entry *entry; - abbrev_attr *attr; - int do_printing = 1; - - die_offset = tags - section_begin; - - abbrev_number = read_leb128 (tags, & bytes_read, 0); - tags += bytes_read; - - /* A null DIE marks the end of a list of siblings or it may also be - a section padding. */ - if (abbrev_number == 0) - { - /* Check if it can be a section padding for the last CU. */ - if (level == 0 && start == end) - { - unsigned char *chk; - - for (chk = tags; chk < start; chk++) - if (*chk != 0) - break; - if (chk == start) - break; - } - - --level; - if (level < 0) - { - static unsigned num_bogus_warns = 0; - - if (num_bogus_warns < 3) - { - warn (_("Bogus end-of-siblings marker detected at offset %lx in .debug_info section\n"), - die_offset); - num_bogus_warns ++; - if (num_bogus_warns == 3) - warn (_("Further warnings about bogus end-of-sibling markers suppressed\n")); - } - } - if (dwarf_start_die != 0 && level < saved_level) - return 1; - continue; - } - - if (!do_loc) - { - if (dwarf_start_die != 0 && die_offset < dwarf_start_die) - do_printing = 0; - else - { - if (dwarf_start_die != 0 && die_offset == dwarf_start_die) - saved_level = level; - do_printing = (dwarf_cutoff_level == -1 - || level < dwarf_cutoff_level); - if (do_printing) - printf (_(" <%d><%lx>: Abbrev Number: %lu"), - level, die_offset, abbrev_number); - else if (dwarf_cutoff_level == -1 - || last_level < dwarf_cutoff_level) - printf (_(" <%d><%lx>: ...\n"), level, die_offset); - last_level = level; - } - } - - /* Scan through the abbreviation list until we reach the - correct entry. */ - for (entry = first_abbrev; - entry && entry->entry != abbrev_number; - entry = entry->next) - continue; - - if (entry == NULL) - { - if (!do_loc && do_printing) - { - printf ("\n"); - fflush (stdout); - } - warn (_("DIE at offset %lx refers to abbreviation number %lu which does not exist\n"), - die_offset, abbrev_number); - return 0; - } - - if (!do_loc && do_printing) - printf (" (%s)\n", get_TAG_name (entry->tag)); - - switch (entry->tag) - { - default: - need_base_address = 0; - break; - case DW_TAG_compile_unit: - need_base_address = 1; - break; - case DW_TAG_entry_point: - case DW_TAG_subprogram: - need_base_address = 0; - /* Assuming that there is no DW_AT_frame_base. */ - have_frame_base = 0; - break; - } - - for (attr = entry->first_attr; attr; attr = attr->next) - { - debug_info *arg; - - if (! do_loc && do_printing) - /* Show the offset from where the tag was extracted. */ - printf (" <%lx>", (unsigned long)(tags - section_begin)); - - arg = debug_information; - if (debug_information) - arg += unit; - - tags = read_and_display_attr (attr->attribute, - attr->form, - tags, cu_offset, - compunit.cu_pointer_size, - offset_size, - compunit.cu_version, - arg, - do_loc || ! do_printing, section); - } - - if (entry->children) - ++level; - } - } - - /* Set num_debug_info_entries here so that it can be used to check if - we need to process .debug_loc and .debug_ranges sections. */ - if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0 - && ! do_types) - num_debug_info_entries = num_units; - - if (!do_loc) - printf ("\n"); - - return 1; -} - -/* Locate and scan the .debug_info section in the file and record the pointer - sizes and offsets for the compilation units in it. Usually an executable - will have just one pointer size, but this is not guaranteed, and so we try - not to make any assumptions. Returns zero upon failure, or the number of - compilation units upon success. */ - -static unsigned int -load_debug_info (void * file) -{ - /* Reset the last pointer size so that we can issue correct error - messages if we are displaying the contents of more than one section. */ - last_pointer_size = 0; - warned_about_missing_comp_units = FALSE; - - /* If we have already tried and failed to load the .debug_info - section then do not bother to repear the task. */ - if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE) - return 0; - - /* If we already have the information there is nothing else to do. */ - if (num_debug_info_entries > 0) - return num_debug_info_entries; - - if (load_debug_section (info, file) - && process_debug_info (&debug_displays [info].section, file, abbrev, 1, 0)) - return num_debug_info_entries; - - num_debug_info_entries = DEBUG_INFO_UNAVAILABLE; - return 0; -} - -static int -display_debug_lines_raw (struct dwarf_section *section, - unsigned char *data, - unsigned char *end) -{ - unsigned char *start = section->start; - - printf (_("Raw dump of debug contents of section %s:\n\n"), - section->name); - - while (data < end) - { - DWARF2_Internal_LineInfo linfo; - unsigned char *standard_opcodes; - unsigned char *end_of_sequence; - unsigned char *hdrptr; - unsigned long hdroff; - int initial_length_size; - int offset_size; - int i; - - hdrptr = data; - hdroff = hdrptr - start; - - /* Check the length of the block. */ - linfo.li_length = byte_get (hdrptr, 4); - hdrptr += 4; - - if (linfo.li_length == 0xffffffff) - { - /* This section is 64-bit DWARF 3. */ - linfo.li_length = byte_get (hdrptr, 8); - hdrptr += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - if (linfo.li_length + initial_length_size > section->size) - { - warn - (_("The information in section %s appears to be corrupt - the section is too small\n"), - section->name); - return 0; - } - - /* Check its version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; - if (linfo.li_version != 2 - && linfo.li_version != 3 - && linfo.li_version != 4) - { - warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n")); - return 0; - } - - linfo.li_prologue_length = byte_get (hdrptr, offset_size); - hdrptr += offset_size; - linfo.li_min_insn_length = byte_get (hdrptr, 1); - hdrptr++; - if (linfo.li_version >= 4) - { - linfo.li_max_ops_per_insn = byte_get (hdrptr, 1); - hdrptr++; - if (linfo.li_max_ops_per_insn == 0) - { - warn (_("Invalid maximum operations per insn.\n")); - return 0; - } - } - else - linfo.li_max_ops_per_insn = 1; - linfo.li_default_is_stmt = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_base = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_range = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_opcode_base = byte_get (hdrptr, 1); - hdrptr++; - - /* Sign extend the line base field. */ - linfo.li_line_base <<= 24; - linfo.li_line_base >>= 24; - - printf (_(" Offset: 0x%lx\n"), hdroff); - printf (_(" Length: %ld\n"), (long) linfo.li_length); - printf (_(" DWARF Version: %d\n"), linfo.li_version); - printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length); - printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length); - if (linfo.li_version >= 4) - printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn); - printf (_(" Initial value of 'is_stmt': %d\n"), linfo.li_default_is_stmt); - printf (_(" Line Base: %d\n"), linfo.li_line_base); - printf (_(" Line Range: %d\n"), linfo.li_line_range); - printf (_(" Opcode Base: %d\n"), linfo.li_opcode_base); - - end_of_sequence = data + linfo.li_length + initial_length_size; - - reset_state_machine (linfo.li_default_is_stmt); - - /* Display the contents of the Opcodes table. */ - standard_opcodes = hdrptr; - - printf (_("\n Opcodes:\n")); - - for (i = 1; i < linfo.li_opcode_base; i++) - printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]); - - /* Display the contents of the Directory table. */ - data = standard_opcodes + linfo.li_opcode_base - 1; - - if (*data == 0) - printf (_("\n The Directory Table is empty.\n")); - else - { - printf (_("\n The Directory Table:\n")); - - while (*data != 0) - { - printf (" %s\n", data); - - data += strlen ((char *) data) + 1; - } - } - - /* Skip the NUL at the end of the table. */ - data++; - - /* Display the contents of the File Name table. */ - if (*data == 0) - printf (_("\n The File Name Table is empty.\n")); - else - { - printf (_("\n The File Name Table:\n")); - printf (_(" Entry\tDir\tTime\tSize\tName\n")); - - while (*data != 0) - { - unsigned char *name; - unsigned int bytes_read; - - printf (" %d\t", ++state_machine_regs.last_file_entry); - name = data; - - data += strlen ((char *) data) + 1; - - printf ("%s\t", - dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf ("%s\t", - dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf ("%s\t", - dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0))); - data += bytes_read; - printf ("%s\n", name); - } - } - - /* Skip the NUL at the end of the table. */ - data++; - - /* Now display the statements. */ - printf (_("\n Line Number Statements:\n")); - - while (data < end_of_sequence) - { - unsigned char op_code; - dwarf_signed_vma adv; - dwarf_vma uladv; - unsigned int bytes_read; - - op_code = *data++; - - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; - uladv = (op_code / linfo.li_line_range); - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Special opcode %d: " - "advance Address by %s to 0x%s"), - op_code, dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Special opcode %d: " - "advance Address by %s to 0x%s[%d]"), - op_code, dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); - } - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; - printf (_(" and Line by %s to %d\n"), - dwarf_vmatoa ("d", adv), state_machine_regs.line); - } - else switch (op_code) - { - case DW_LNS_extended_op: - data += process_extended_line_op (data, linfo.li_default_is_stmt); - break; - - case DW_LNS_copy: - printf (_(" Copy\n")); - break; - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Advance PC by %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Advance PC by %s to 0x%s[%d]\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); - } - break; - - case DW_LNS_advance_line: - adv = read_sleb128 (data, & bytes_read); - data += bytes_read; - state_machine_regs.line += adv; - printf (_(" Advance Line by %s to %d\n"), - dwarf_vmatoa ("d", adv), - state_machine_regs.line); - break; - - case DW_LNS_set_file: - adv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - printf (_(" Set File Name to entry %s in the File Name Table\n"), - dwarf_vmatoa ("d", adv)); - state_machine_regs.file = adv; - break; - - case DW_LNS_set_column: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - printf (_(" Set column to %s\n"), - dwarf_vmatoa ("u", uladv)); - state_machine_regs.column = uladv; - break; - - case DW_LNS_negate_stmt: - adv = state_machine_regs.is_stmt; - adv = ! adv; - printf (_(" Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv)); - state_machine_regs.is_stmt = adv; - break; - - case DW_LNS_set_basic_block: - printf (_(" Set basic block\n")); - state_machine_regs.basic_block = 1; - break; - - case DW_LNS_const_add_pc: - uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); - if (linfo.li_max_ops_per_insn) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Advance PC by constant %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Advance PC by constant %s to 0x%s[%d]\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); - } - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; - state_machine_regs.op_index = 0; - printf (_(" Advance PC by fixed size amount %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - break; - - case DW_LNS_set_prologue_end: - printf (_(" Set prologue_end to true\n")); - break; - - case DW_LNS_set_epilogue_begin: - printf (_(" Set epilogue_begin to true\n")); - break; - - case DW_LNS_set_isa: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv)); - break; - - default: - printf (_(" Unknown opcode %d with operands: "), op_code); - - for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) - { - printf ("0x%s%s", dwarf_vmatoa ("x", read_leb128 (data, - &bytes_read, 0)), - i == 1 ? "" : ", "); - data += bytes_read; - } - putchar ('\n'); - break; - } - } - putchar ('\n'); - } - - return 1; -} - -typedef struct -{ - unsigned char *name; - unsigned int directory_index; - unsigned int modification_date; - unsigned int length; -} File_Entry; - -/* Output a decoded representation of the .debug_line section. */ - -static int -display_debug_lines_decoded (struct dwarf_section *section, - unsigned char *data, - unsigned char *end) -{ - printf (_("Decoded dump of debug contents of section %s:\n\n"), - section->name); - - while (data < end) - { - /* This loop amounts to one iteration per compilation unit. */ - DWARF2_Internal_LineInfo linfo; - unsigned char *standard_opcodes; - unsigned char *end_of_sequence; - unsigned char *hdrptr; - int initial_length_size; - int offset_size; - int i; - File_Entry *file_table = NULL; - unsigned char **directory_table = NULL; - - hdrptr = data; - - /* Extract information from the Line Number Program Header. - (section 6.2.4 in the Dwarf3 doc). */ - - /* Get the length of this CU's line number information block. */ - linfo.li_length = byte_get (hdrptr, 4); - hdrptr += 4; - - if (linfo.li_length == 0xffffffff) - { - /* This section is 64-bit DWARF 3. */ - linfo.li_length = byte_get (hdrptr, 8); - hdrptr += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - if (linfo.li_length + initial_length_size > section->size) - { - warn (_("The line info appears to be corrupt - " - "the section is too small\n")); - return 0; - } - - /* Get this CU's Line Number Block version number. */ - linfo.li_version = byte_get (hdrptr, 2); - hdrptr += 2; - if (linfo.li_version != 2 - && linfo.li_version != 3 - && linfo.li_version != 4) - { - warn (_("Only DWARF version 2, 3 and 4 line info is currently " - "supported.\n")); - return 0; - } - - linfo.li_prologue_length = byte_get (hdrptr, offset_size); - hdrptr += offset_size; - linfo.li_min_insn_length = byte_get (hdrptr, 1); - hdrptr++; - if (linfo.li_version >= 4) - { - linfo.li_max_ops_per_insn = byte_get (hdrptr, 1); - hdrptr++; - if (linfo.li_max_ops_per_insn == 0) - { - warn (_("Invalid maximum operations per insn.\n")); - return 0; - } - } - else - linfo.li_max_ops_per_insn = 1; - linfo.li_default_is_stmt = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_base = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_line_range = byte_get (hdrptr, 1); - hdrptr++; - linfo.li_opcode_base = byte_get (hdrptr, 1); - hdrptr++; - - /* Sign extend the line base field. */ - linfo.li_line_base <<= 24; - linfo.li_line_base >>= 24; - - /* Find the end of this CU's Line Number Information Block. */ - end_of_sequence = data + linfo.li_length + initial_length_size; - - reset_state_machine (linfo.li_default_is_stmt); - - /* Save a pointer to the contents of the Opcodes table. */ - standard_opcodes = hdrptr; - - /* Traverse the Directory table just to count entries. */ - data = standard_opcodes + linfo.li_opcode_base - 1; - if (*data != 0) - { - unsigned int n_directories = 0; - unsigned char *ptr_directory_table = data; - - while (*data != 0) - { - data += strlen ((char *) data) + 1; - n_directories++; - } - - /* Go through the directory table again to save the directories. */ - directory_table = (unsigned char **) - xmalloc (n_directories * sizeof (unsigned char *)); - - i = 0; - while (*ptr_directory_table != 0) - { - directory_table[i] = ptr_directory_table; - ptr_directory_table += strlen ((char *) ptr_directory_table) + 1; - i++; - } - } - /* Skip the NUL at the end of the table. */ - data++; - - /* Traverse the File Name table just to count the entries. */ - if (*data != 0) - { - unsigned int n_files = 0; - unsigned char *ptr_file_name_table = data; - - while (*data != 0) - { - unsigned int bytes_read; - - /* Skip Name, directory index, last modification time and length - of file. */ - data += strlen ((char *) data) + 1; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - read_leb128 (data, & bytes_read, 0); - data += bytes_read; - - n_files++; - } - - /* Go through the file table again to save the strings. */ - file_table = (File_Entry *) xmalloc (n_files * sizeof (File_Entry)); - - i = 0; - while (*ptr_file_name_table != 0) - { - unsigned int bytes_read; - - file_table[i].name = ptr_file_name_table; - ptr_file_name_table += strlen ((char *) ptr_file_name_table) + 1; - - /* We are not interested in directory, time or size. */ - file_table[i].directory_index = read_leb128 (ptr_file_name_table, - & bytes_read, 0); - ptr_file_name_table += bytes_read; - file_table[i].modification_date = read_leb128 (ptr_file_name_table, - & bytes_read, 0); - ptr_file_name_table += bytes_read; - file_table[i].length = read_leb128 (ptr_file_name_table, & bytes_read, 0); - ptr_file_name_table += bytes_read; - i++; - } - i = 0; - - /* Print the Compilation Unit's name and a header. */ - if (directory_table == NULL) - { - printf (_("CU: %s:\n"), file_table[0].name); - printf (_("File name Line number Starting address\n")); - } - else - { - if (do_wide || strlen ((char *) directory_table[0]) < 76) - printf (_("CU: %s/%s:\n"), directory_table[0], - file_table[0].name); - else - printf ("%s:\n", file_table[0].name); - - printf (_("File name Line number Starting address\n")); - } - } - - /* Skip the NUL at the end of the table. */ - data++; - - /* This loop iterates through the Dwarf Line Number Program. */ - while (data < end_of_sequence) - { - unsigned char op_code; - int adv; - unsigned long int uladv; - unsigned int bytes_read; - int is_special_opcode = 0; - - op_code = *data++; - - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; - uladv = (op_code / linfo.li_line_range); - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - } - - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; - is_special_opcode = 1; - } - else switch (op_code) - { - case DW_LNS_extended_op: - { - unsigned int ext_op_code_len; - unsigned char ext_op_code; - unsigned char *op_code_data = data; - - ext_op_code_len = read_leb128 (op_code_data, &bytes_read, 0); - op_code_data += bytes_read; - - if (ext_op_code_len == 0) - { - warn (_("badly formed extended line op encountered!\n")); - break; - } - ext_op_code_len += bytes_read; - ext_op_code = *op_code_data++; - - switch (ext_op_code) - { - case DW_LNE_end_sequence: - reset_state_machine (linfo.li_default_is_stmt); - break; - case DW_LNE_set_address: - state_machine_regs.address = - byte_get (op_code_data, ext_op_code_len - bytes_read - 1); - state_machine_regs.op_index = 0; - break; - case DW_LNE_define_file: - { - unsigned int dir_index = 0; - - ++state_machine_regs.last_file_entry; - op_code_data += strlen ((char *) op_code_data) + 1; - dir_index = read_leb128 (op_code_data, & bytes_read, 0); - op_code_data += bytes_read; - read_leb128 (op_code_data, & bytes_read, 0); - op_code_data += bytes_read; - read_leb128 (op_code_data, & bytes_read, 0); - - printf ("%s:\n", directory_table[dir_index]); - break; - } - default: - printf (_("UNKNOWN: length %d\n"), ext_op_code_len - bytes_read); - break; - } - data += ext_op_code_len; - break; - } - case DW_LNS_copy: - break; - - case DW_LNS_advance_pc: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - } - break; - - case DW_LNS_advance_line: - adv = read_sleb128 (data, & bytes_read); - data += bytes_read; - state_machine_regs.line += adv; - break; - - case DW_LNS_set_file: - adv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - state_machine_regs.file = adv; - if (file_table[state_machine_regs.file - 1].directory_index == 0) - { - /* If directory index is 0, that means current directory. */ - printf ("\n./%s:[++]\n", - file_table[state_machine_regs.file - 1].name); - } - else - { - /* The directory index starts counting at 1. */ - printf ("\n%s/%s:\n", - directory_table[file_table[state_machine_regs.file - 1].directory_index - 1], - file_table[state_machine_regs.file - 1].name); - } - break; - - case DW_LNS_set_column: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - state_machine_regs.column = uladv; - break; - - case DW_LNS_negate_stmt: - adv = state_machine_regs.is_stmt; - adv = ! adv; - state_machine_regs.is_stmt = adv; - break; - - case DW_LNS_set_basic_block: - state_machine_regs.basic_block = 1; - break; - - case DW_LNS_const_add_pc: - uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - } - break; - - case DW_LNS_fixed_advance_pc: - uladv = byte_get (data, 2); - data += 2; - state_machine_regs.address += uladv; - state_machine_regs.op_index = 0; - break; - - case DW_LNS_set_prologue_end: - break; - - case DW_LNS_set_epilogue_begin: - break; - - case DW_LNS_set_isa: - uladv = read_leb128 (data, & bytes_read, 0); - data += bytes_read; - printf (_(" Set ISA to %lu\n"), uladv); - break; - - default: - printf (_(" Unknown opcode %d with operands: "), op_code); - - for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) - { - printf ("0x%s%s", dwarf_vmatoa ("x", read_leb128 (data, - &bytes_read, 0)), - i == 1 ? "" : ", "); - data += bytes_read; - } - putchar ('\n'); - break; - } - - /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row - to the DWARF address/line matrix. */ - if ((is_special_opcode) || (op_code == DW_LNE_end_sequence) - || (op_code == DW_LNS_copy)) - { - const unsigned int MAX_FILENAME_LENGTH = 35; - char *fileName = (char *)file_table[state_machine_regs.file - 1].name; - char *newFileName = NULL; - size_t fileNameLength = strlen (fileName); - - if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide)) - { - newFileName = (char *) xmalloc (MAX_FILENAME_LENGTH + 1); - /* Truncate file name */ - strncpy (newFileName, - fileName + fileNameLength - MAX_FILENAME_LENGTH, - MAX_FILENAME_LENGTH + 1); - } - else - { - newFileName = (char *) xmalloc (fileNameLength + 1); - strncpy (newFileName, fileName, fileNameLength + 1); - } - - if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH)) - { - if (linfo.li_max_ops_per_insn == 1) - printf ("%-35s %11d %#18" DWARF_VMA_FMT "x\n", - newFileName, state_machine_regs.line, - state_machine_regs.address); - else - printf ("%-35s %11d %#18" DWARF_VMA_FMT "x[%d]\n", - newFileName, state_machine_regs.line, - state_machine_regs.address, - state_machine_regs.op_index); - } - else - { - if (linfo.li_max_ops_per_insn == 1) - printf ("%s %11d %#18" DWARF_VMA_FMT "x\n", - newFileName, state_machine_regs.line, - state_machine_regs.address); - else - printf ("%s %11d %#18" DWARF_VMA_FMT "x[%d]\n", - newFileName, state_machine_regs.line, - state_machine_regs.address, - state_machine_regs.op_index); - } - - if (op_code == DW_LNE_end_sequence) - printf ("\n"); - - free (newFileName); - } - } - free (file_table); - file_table = NULL; - free (directory_table); - directory_table = NULL; - putchar ('\n'); - } - - return 1; -} - -static int -display_debug_lines (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED) -{ - unsigned char *data = section->start; - unsigned char *end = data + section->size; - int retValRaw = 1; - int retValDecoded = 1; - - if (do_debug_lines == 0) - do_debug_lines |= FLAG_DEBUG_LINES_RAW; - - if (do_debug_lines & FLAG_DEBUG_LINES_RAW) - retValRaw = display_debug_lines_raw (section, data, end); - - if (do_debug_lines & FLAG_DEBUG_LINES_DECODED) - retValDecoded = display_debug_lines_decoded (section, data, end); - - if (!retValRaw || !retValDecoded) - return 0; - - return 1; -} - -static debug_info * -find_debug_info_for_offset (unsigned long offset) -{ - unsigned int i; - - if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE) - return NULL; - - for (i = 0; i < num_debug_info_entries; i++) - if (debug_information[i].cu_offset == offset) - return debug_information + i; - - return NULL; -} - -static int -display_debug_pubnames (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - DWARF2_Internal_PubNames names; - unsigned char *start = section->start; - unsigned char *end = start + section->size; - - /* It does not matter if this load fails, - we test for that later on. */ - load_debug_info (file); - - printf (_("Contents of the %s section:\n\n"), section->name); - - while (start < end) - { - unsigned char *data; - unsigned long offset; - int offset_size, initial_length_size; - - data = start; - - names.pn_length = byte_get (data, 4); - data += 4; - if (names.pn_length == 0xffffffff) - { - names.pn_length = byte_get (data, 8); - data += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - names.pn_version = byte_get (data, 2); - data += 2; - - names.pn_offset = byte_get (data, offset_size); - data += offset_size; - - if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE - && num_debug_info_entries > 0 - && find_debug_info_for_offset (names.pn_offset) == NULL) - warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"), - (unsigned long) names.pn_offset, section->name); - - names.pn_size = byte_get (data, offset_size); - data += offset_size; - - start += names.pn_length + initial_length_size; - - if (names.pn_version != 2 && names.pn_version != 3) - { - static int warned = 0; - - if (! warned) - { - warn (_("Only DWARF 2 and 3 pubnames are currently supported\n")); - warned = 1; - } - - continue; - } - - printf (_(" Length: %ld\n"), - (long) names.pn_length); - printf (_(" Version: %d\n"), - names.pn_version); - printf (_(" Offset into .debug_info section: 0x%lx\n"), - (unsigned long) names.pn_offset); - printf (_(" Size of area in .debug_info section: %ld\n"), - (long) names.pn_size); - - printf (_("\n Offset\tName\n")); - - do - { - offset = byte_get (data, offset_size); - - if (offset != 0) - { - data += offset_size; - printf (" %-6lx\t%s\n", offset, data); - data += strlen ((char *) data) + 1; - } - } - while (offset != 0); - } - - printf ("\n"); - return 1; -} - -static int -display_debug_macinfo (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - unsigned char *end = start + section->size; - unsigned char *curr = start; - unsigned int bytes_read; - enum dwarf_macinfo_record_type op; - - printf (_("Contents of the %s section:\n\n"), section->name); - - while (curr < end) - { - unsigned int lineno; - const char *string; - - op = (enum dwarf_macinfo_record_type) *curr; - curr++; - - switch (op) - { - case DW_MACINFO_start_file: - { - unsigned int filenum; - - lineno = read_leb128 (curr, & bytes_read, 0); - curr += bytes_read; - filenum = read_leb128 (curr, & bytes_read, 0); - curr += bytes_read; - - printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), - lineno, filenum); - } - break; - - case DW_MACINFO_end_file: - printf (_(" DW_MACINFO_end_file\n")); - break; - - case DW_MACINFO_define: - lineno = read_leb128 (curr, & bytes_read, 0); - curr += bytes_read; - string = (char *) curr; - curr += strlen (string) + 1; - printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACINFO_undef: - lineno = read_leb128 (curr, & bytes_read, 0); - curr += bytes_read; - string = (char *) curr; - curr += strlen (string) + 1; - printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACINFO_vendor_ext: - { - unsigned int constant; - - constant = read_leb128 (curr, & bytes_read, 0); - curr += bytes_read; - string = (char *) curr; - curr += strlen (string) + 1; - printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), - constant, string); - } - break; - } - } - - return 1; -} - -/* Given LINE_OFFSET into the .debug_line section, attempt to return - filename and dirname corresponding to file name table entry with index - FILEIDX. Return NULL on failure. */ - -static unsigned char * -get_line_filename_and_dirname (dwarf_vma line_offset, dwarf_vma fileidx, - unsigned char **dir_name) -{ - struct dwarf_section *section = &debug_displays [line].section; - unsigned char *hdrptr, *dirtable, *file_name; - unsigned int offset_size, initial_length_size; - unsigned int version, opcode_base, bytes_read; - dwarf_vma length, diridx; - - *dir_name = NULL; - if (section->start == NULL - || line_offset >= section->size - || fileidx == 0) - return NULL; - - hdrptr = section->start + line_offset; - length = byte_get (hdrptr, 4); - hdrptr += 4; - if (length == 0xffffffff) - { - /* This section is 64-bit DWARF 3. */ - length = byte_get (hdrptr, 8); - hdrptr += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - if (length + initial_length_size > section->size) - return NULL; - version = byte_get (hdrptr, 2); - hdrptr += 2; - if (version != 2 && version != 3 && version != 4) - return NULL; - hdrptr += offset_size + 1;/* Skip prologue_length and min_insn_length. */ - if (version >= 4) - hdrptr++; /* Skip max_ops_per_insn. */ - hdrptr += 3; /* Skip default_is_stmt, line_base, line_range. */ - opcode_base = byte_get (hdrptr, 1); - if (opcode_base == 0) - return NULL; - hdrptr++; - hdrptr += opcode_base - 1; - dirtable = hdrptr; - /* Skip over dirname table. */ - while (*hdrptr != '\0') - hdrptr += strlen ((char *) hdrptr) + 1; - hdrptr++; /* Skip the NUL at the end of the table. */ - /* Now skip over preceding filename table entries. */ - for (; *hdrptr != '\0' && fileidx > 1; fileidx--) - { - hdrptr += strlen ((char *) hdrptr) + 1; - read_leb128 (hdrptr, &bytes_read, 0); - hdrptr += bytes_read; - read_leb128 (hdrptr, &bytes_read, 0); - hdrptr += bytes_read; - read_leb128 (hdrptr, &bytes_read, 0); - hdrptr += bytes_read; - } - if (*hdrptr == '\0') - return NULL; - file_name = hdrptr; - hdrptr += strlen ((char *) hdrptr) + 1; - diridx = read_leb128 (hdrptr, &bytes_read, 0); - if (diridx == 0) - return file_name; - for (; *dirtable != '\0' && diridx > 1; diridx--) - dirtable += strlen ((char *) dirtable) + 1; - if (*dirtable == '\0') - return NULL; - *dir_name = dirtable; - return file_name; -} - -static int -display_debug_macro (struct dwarf_section *section, - void *file) -{ - unsigned char *start = section->start; - unsigned char *end = start + section->size; - unsigned char *curr = start; - unsigned char *extended_op_buf[256]; - unsigned int bytes_read; - - load_debug_section (str, file); - load_debug_section (line, file); - - printf (_("Contents of the %s section:\n\n"), section->name); - - while (curr < end) - { - unsigned int lineno, version, flags; - unsigned int offset_size = 4; - const char *string; - dwarf_vma line_offset = 0, sec_offset = curr - start, offset; - unsigned char **extended_ops = NULL; - - version = byte_get (curr, 2); - curr += 2; - - if (version != 4) - { - error (_("Only GNU extension to DWARF 4 of %s is currently supported.\n"), - section->name); - return 0; - } - - flags = byte_get (curr++, 1); - if (flags & 1) - offset_size = 8; - printf (_(" Offset: 0x%lx\n"), - (unsigned long) sec_offset); - printf (_(" Version: %d\n"), version); - printf (_(" Offset size: %d\n"), offset_size); - if (flags & 2) - { - line_offset = byte_get (curr, offset_size); - curr += offset_size; - printf (_(" Offset into .debug_line: 0x%lx\n"), - (unsigned long) line_offset); - } - if (flags & 4) - { - unsigned int i, count = byte_get (curr++, 1), op; - dwarf_vma nargs, n; - memset (extended_op_buf, 0, sizeof (extended_op_buf)); - extended_ops = extended_op_buf; - if (count) - { - printf (_(" Extension opcode arguments:\n")); - for (i = 0; i < count; i++) - { - op = byte_get (curr++, 1); - extended_ops[op] = curr; - nargs = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - if (nargs == 0) - printf (_(" DW_MACRO_GNU_%02x has no arguments\n"), op); - else - { - printf (_(" DW_MACRO_GNU_%02x arguments: "), op); - for (n = 0; n < nargs; n++) - { - unsigned int form = byte_get (curr++, 1); - printf ("%s%s", get_FORM_name (form), - n == nargs - 1 ? "\n" : ", "); - switch (form) - { - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - case DW_FORM_flag: - case DW_FORM_string: - case DW_FORM_strp: - case DW_FORM_sec_offset: - break; - default: - error (_("Invalid extension opcode form %s\n"), - get_FORM_name (form)); - return 0; - } - } - } - } - } - } - printf ("\n"); - - while (1) - { - unsigned int op; - - if (curr >= end) - { - error (_(".debug_macro section not zero terminated\n")); - return 0; - } - - op = byte_get (curr++, 1); - if (op == 0) - break; - - switch (op) - { - case DW_MACRO_GNU_start_file: - { - unsigned int filenum; - unsigned char *file_name = NULL, *dir_name = NULL; - - lineno = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - filenum = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - - if ((flags & 2) == 0) - error (_("DW_MACRO_GNU_start_file used, but no .debug_line offset provided.\n")); - else - file_name - = get_line_filename_and_dirname (line_offset, filenum, - &dir_name); - if (file_name == NULL) - printf (_(" DW_MACRO_GNU_start_file - lineno: %d filenum: %d\n"), - lineno, filenum); - else - printf (_(" DW_MACRO_GNU_start_file - lineno: %d filenum: %d filename: %s%s%s\n"), - lineno, filenum, - dir_name != NULL ? (const char *) dir_name : "", - dir_name != NULL ? "/" : "", file_name); - } - break; - - case DW_MACRO_GNU_end_file: - printf (_(" DW_MACRO_GNU_end_file\n")); - break; - - case DW_MACRO_GNU_define: - lineno = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - string = (char *) curr; - curr += strlen (string) + 1; - printf (_(" DW_MACRO_GNU_define - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACRO_GNU_undef: - lineno = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - string = (char *) curr; - curr += strlen (string) + 1; - printf (_(" DW_MACRO_GNU_undef - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACRO_GNU_define_indirect: - lineno = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - offset = byte_get (curr, offset_size); - curr += offset_size; - string = fetch_indirect_string (offset); - printf (_(" DW_MACRO_GNU_define_indirect - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACRO_GNU_undef_indirect: - lineno = read_leb128 (curr, &bytes_read, 0); - curr += bytes_read; - offset = byte_get (curr, offset_size); - curr += offset_size; - string = fetch_indirect_string (offset); - printf (_(" DW_MACRO_GNU_undef_indirect - lineno : %d macro : %s\n"), - lineno, string); - break; - - case DW_MACRO_GNU_transparent_include: - offset = byte_get (curr, offset_size); - curr += offset_size; - printf (_(" DW_MACRO_GNU_transparent_include - offset : 0x%lx\n"), - (unsigned long) offset); - break; - - default: - if (extended_ops == NULL || extended_ops[op] == NULL) - { - error (_(" Unknown macro opcode %02x seen\n"), op); - return 0; - } - else - { - /* Skip over unhandled opcodes. */ - dwarf_vma nargs, n; - unsigned char *desc = extended_ops[op]; - nargs = read_leb128 (desc, &bytes_read, 0); - desc += bytes_read; - if (nargs == 0) - { - printf (_(" DW_MACRO_GNU_%02x\n"), op); - break; - } - printf (_(" DW_MACRO_GNU_%02x -"), op); - for (n = 0; n < nargs; n++) - { - curr - = read_and_display_attr_value (0, byte_get (desc++, 1), - curr, 0, 0, offset_size, - version, NULL, 0, NULL); - if (n != nargs - 1) - printf (","); - } - printf ("\n"); - } - break; - } - } - - printf ("\n"); - } - - return 1; -} - -static int -display_debug_abbrev (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - abbrev_entry *entry; - unsigned char *start = section->start; - unsigned char *end = start + section->size; - - printf (_("Contents of the %s section:\n\n"), section->name); - - do - { - free_abbrevs (); - - start = process_abbrev_section (start, end); - - if (first_abbrev == NULL) - continue; - - printf (_(" Number TAG\n")); - - for (entry = first_abbrev; entry; entry = entry->next) - { - abbrev_attr *attr; - - printf (" %ld %s [%s]\n", - entry->entry, - get_TAG_name (entry->tag), - entry->children ? _("has children") : _("no children")); - - for (attr = entry->first_attr; attr; attr = attr->next) - printf (" %-18s %s\n", - get_AT_name (attr->attribute), - get_FORM_name (attr->form)); - } - } - while (start); - - printf ("\n"); - - return 1; -} - -/* Sort array of indexes in ascending order of loc_offsets[idx]. */ - -static dwarf_vma *loc_offsets; - -static int -loc_offsets_compar (const void *ap, const void *bp) -{ - dwarf_vma a = loc_offsets[*(const unsigned int *) ap]; - dwarf_vma b = loc_offsets[*(const unsigned int *) bp]; - - return (a > b) - (b > a); -} - -static int -display_debug_loc (struct dwarf_section *section, void *file) -{ - unsigned char *start = section->start; - unsigned char *section_end; - unsigned long bytes; - unsigned char *section_begin = start; - unsigned int num_loc_list = 0; - unsigned long last_offset = 0; - unsigned int first = 0; - unsigned int i; - unsigned int j; - unsigned int k; - int seen_first_offset = 0; - int locs_sorted = 1; - unsigned char *next; - unsigned int *array = NULL; - - bytes = section->size; - section_end = start + bytes; - - if (bytes == 0) - { - printf (_("\nThe %s section is empty.\n"), section->name); - return 0; - } - - if (load_debug_info (file) == 0) - { - warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"), - section->name); - return 0; - } - - /* Check the order of location list in .debug_info section. If - offsets of location lists are in the ascending order, we can - use `debug_information' directly. */ - for (i = 0; i < num_debug_info_entries; i++) - { - unsigned int num; - - num = debug_information [i].num_loc_offsets; - if (num > num_loc_list) - num_loc_list = num; - - /* Check if we can use `debug_information' directly. */ - if (locs_sorted && num != 0) - { - if (!seen_first_offset) - { - /* This is the first location list. */ - last_offset = debug_information [i].loc_offsets [0]; - first = i; - seen_first_offset = 1; - j = 1; - } - else - j = 0; - - for (; j < num; j++) - { - if (last_offset > - debug_information [i].loc_offsets [j]) - { - locs_sorted = 0; - break; - } - last_offset = debug_information [i].loc_offsets [j]; - } - } - } - - if (!seen_first_offset) - error (_("No location lists in .debug_info section!\n")); - - /* DWARF sections under Mach-O have non-zero addresses. */ - if (debug_information [first].num_loc_offsets > 0 - && debug_information [first].loc_offsets [0] != section->address) - warn (_("Location lists in %s section start at 0x%s\n"), - section->name, - dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); - - if (!locs_sorted) - array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int)); - printf (_("Contents of the %s section:\n\n"), section->name); - printf (_(" Offset Begin End Expression\n")); - - seen_first_offset = 0; - for (i = first; i < num_debug_info_entries; i++) - { - dwarf_vma begin; - dwarf_vma end; - unsigned short length; - unsigned long offset; - unsigned int pointer_size; - unsigned int offset_size; - int dwarf_version; - unsigned long cu_offset; - unsigned long base_address; - int need_frame_base; - int has_frame_base; - - pointer_size = debug_information [i].pointer_size; - cu_offset = debug_information [i].cu_offset; - offset_size = debug_information [i].offset_size; - dwarf_version = debug_information [i].dwarf_version; - if (!locs_sorted) - { - for (k = 0; k < debug_information [i].num_loc_offsets; k++) - array[k] = k; - loc_offsets = debug_information [i].loc_offsets; - qsort (array, debug_information [i].num_loc_offsets, - sizeof (*array), loc_offsets_compar); - } - - for (k = 0; k < debug_information [i].num_loc_offsets; k++) - { - j = locs_sorted ? k : array[k]; - if (k - && debug_information [i].loc_offsets [locs_sorted - ? k - 1 : array [k - 1]] - == debug_information [i].loc_offsets [j]) - continue; - has_frame_base = debug_information [i].have_frame_base [j]; - /* DWARF sections under Mach-O have non-zero addresses. */ - offset = debug_information [i].loc_offsets [j] - section->address; - next = section_begin + offset; - base_address = debug_information [i].base_address; - - if (!seen_first_offset) - seen_first_offset = 1; - else - { - if (start < next) - warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"), - (unsigned long) (start - section_begin), - (unsigned long) (next - section_begin)); - else if (start > next) - warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"), - (unsigned long) (start - section_begin), - (unsigned long) (next - section_begin)); - } - start = next; - - if (offset >= bytes) - { - warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"), - offset); - continue; - } - - while (1) - { - if (start + 2 * pointer_size > section_end) - { - warn (_("Location list starting at offset 0x%lx is not terminated.\n"), - offset); - break; - } - - /* Note: we use sign extension here in order to be sure that - we can detect the -1 escape value. Sign extension into the - top 32 bits of a 32-bit address will not affect the values - that we display since we always show hex values, and always - the bottom 32-bits. */ - begin = byte_get_signed (start, pointer_size); - start += pointer_size; - end = byte_get_signed (start, pointer_size); - start += pointer_size; - - printf (" %8.8lx ", offset); - - if (begin == 0 && end == 0) - { - printf (_("\n")); - break; - } - - /* Check base address specifiers. */ - if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1) - { - base_address = end; - print_dwarf_vma (begin, pointer_size); - print_dwarf_vma (end, pointer_size); - printf (_("(base address)\n")); - continue; - } - - if (start + 2 > section_end) - { - warn (_("Location list starting at offset 0x%lx is not terminated.\n"), - offset); - break; - } - - length = byte_get (start, 2); - start += 2; - - if (start + length > section_end) - { - warn (_("Location list starting at offset 0x%lx is not terminated.\n"), - offset); - break; - } - - print_dwarf_vma (begin + base_address, pointer_size); - print_dwarf_vma (end + base_address, pointer_size); - - putchar ('('); - need_frame_base = decode_location_expression (start, - pointer_size, - offset_size, - dwarf_version, - length, - cu_offset, section); - putchar (')'); - - if (need_frame_base && !has_frame_base) - printf (_(" [without DW_AT_frame_base]")); - - if (begin == end) - fputs (_(" (start == end)"), stdout); - else if (begin > end) - fputs (_(" (start > end)"), stdout); - - putchar ('\n'); - - start += length; - } - } - } - - if (start < section_end) - warn (_("There are %ld unused bytes at the end of section %s\n"), - (long) (section_end - start), section->name); - putchar ('\n'); - free (array); - return 1; -} - -static int -display_debug_str (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - unsigned long bytes = section->size; - dwarf_vma addr = section->address; - - if (bytes == 0) - { - printf (_("\nThe %s section is empty.\n"), section->name); - return 0; - } - - printf (_("Contents of the %s section:\n\n"), section->name); - - while (bytes) - { - int j; - int k; - int lbytes; - - lbytes = (bytes > 16 ? 16 : bytes); - - printf (" 0x%8.8lx ", (unsigned long) addr); - - for (j = 0; j < 16; j++) - { - if (j < lbytes) - printf ("%2.2x", start[j]); - else - printf (" "); - - if ((j & 3) == 3) - printf (" "); - } - - for (j = 0; j < lbytes; j++) - { - k = start[j]; - if (k >= ' ' && k < 0x80) - printf ("%c", k); - else - printf ("."); - } - - putchar ('\n'); - - start += lbytes; - addr += lbytes; - bytes -= lbytes; - } - - putchar ('\n'); - - return 1; -} - -static int -display_debug_info (struct dwarf_section *section, void *file) -{ - return process_debug_info (section, file, abbrev, 0, 0); -} - -static int -display_debug_types (struct dwarf_section *section, void *file) -{ - return process_debug_info (section, file, abbrev, 0, 1); -} - -static int -display_trace_info (struct dwarf_section *section, void *file) -{ - return process_debug_info (section, file, trace_abbrev, 0, 0); -} - -static int -display_debug_aranges (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - unsigned char *end = start + section->size; - - printf (_("Contents of the %s section:\n\n"), section->name); - - /* It does not matter if this load fails, - we test for that later on. */ - load_debug_info (file); - - while (start < end) - { - unsigned char *hdrptr; - DWARF2_Internal_ARange arange; - unsigned char *addr_ranges; - dwarf_vma length; - dwarf_vma address; - unsigned char address_size; - int excess; - int offset_size; - int initial_length_size; - - hdrptr = start; - - arange.ar_length = byte_get (hdrptr, 4); - hdrptr += 4; - - if (arange.ar_length == 0xffffffff) - { - arange.ar_length = byte_get (hdrptr, 8); - hdrptr += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - arange.ar_version = byte_get (hdrptr, 2); - hdrptr += 2; - - arange.ar_info_offset = byte_get (hdrptr, offset_size); - hdrptr += offset_size; - - if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE - && num_debug_info_entries > 0 - && find_debug_info_for_offset (arange.ar_info_offset) == NULL) - warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"), - (unsigned long) arange.ar_info_offset, section->name); - - arange.ar_pointer_size = byte_get (hdrptr, 1); - hdrptr += 1; - - arange.ar_segment_size = byte_get (hdrptr, 1); - hdrptr += 1; - - if (arange.ar_version != 2 && arange.ar_version != 3) - { - warn (_("Only DWARF 2 and 3 aranges are currently supported.\n")); - break; - } - - printf (_(" Length: %ld\n"), - (long) arange.ar_length); - printf (_(" Version: %d\n"), arange.ar_version); - printf (_(" Offset into .debug_info: 0x%lx\n"), - (unsigned long) arange.ar_info_offset); - printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size); - printf (_(" Segment Size: %d\n"), arange.ar_segment_size); - - address_size = arange.ar_pointer_size + arange.ar_segment_size; - - if (address_size == 0) - { - error (_("Invalid address size in %s section!\n"), - section->name); - break; - } - - /* The DWARF spec does not require that the address size be a power - of two, but we do. This will have to change if we ever encounter - an uneven architecture. */ - if ((address_size & (address_size - 1)) != 0) - { - warn (_("Pointer size + Segment size is not a power of two.\n")); - break; - } - - if (address_size > 4) - printf (_("\n Address Length\n")); - else - printf (_("\n Address Length\n")); - - addr_ranges = hdrptr; - - /* Must pad to an alignment boundary that is twice the address size. */ - excess = (hdrptr - start) % (2 * address_size); - if (excess) - addr_ranges += (2 * address_size) - excess; - - start += arange.ar_length + initial_length_size; - - while (addr_ranges + 2 * address_size <= start) - { - address = byte_get (addr_ranges, address_size); - - addr_ranges += address_size; - - length = byte_get (addr_ranges, address_size); - - addr_ranges += address_size; - - printf (" "); - print_dwarf_vma (address, address_size); - print_dwarf_vma (length, address_size); - putchar ('\n'); - } - } - - printf ("\n"); - - return 1; -} - -/* Each debug_information[x].range_lists[y] gets this representation for - sorting purposes. */ - -struct range_entry -{ - /* The debug_information[x].range_lists[y] value. */ - unsigned long ranges_offset; - - /* Original debug_information to find parameters of the data. */ - debug_info *debug_info_p; -}; - -/* Sort struct range_entry in ascending order of its RANGES_OFFSET. */ - -static int -range_entry_compar (const void *ap, const void *bp) -{ - const struct range_entry *a_re = (const struct range_entry *) ap; - const struct range_entry *b_re = (const struct range_entry *) bp; - const unsigned long a = a_re->ranges_offset; - const unsigned long b = b_re->ranges_offset; - - return (a > b) - (b > a); -} - -static int -display_debug_ranges (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - unsigned long bytes; - unsigned char *section_begin = start; - unsigned int num_range_list, i; - struct range_entry *range_entries, *range_entry_fill; - - bytes = section->size; - - if (bytes == 0) - { - printf (_("\nThe %s section is empty.\n"), section->name); - return 0; - } - - if (load_debug_info (file) == 0) - { - warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"), - section->name); - return 0; - } - - num_range_list = 0; - for (i = 0; i < num_debug_info_entries; i++) - num_range_list += debug_information [i].num_range_lists; - - if (num_range_list == 0) - error (_("No range lists in .debug_info section!\n")); - - range_entries = (struct range_entry *) - xmalloc (sizeof (*range_entries) * num_range_list); - range_entry_fill = range_entries; - - for (i = 0; i < num_debug_info_entries; i++) - { - debug_info *debug_info_p = &debug_information[i]; - unsigned int j; - - for (j = 0; j < debug_info_p->num_range_lists; j++) - { - range_entry_fill->ranges_offset = debug_info_p->range_lists[j]; - range_entry_fill->debug_info_p = debug_info_p; - range_entry_fill++; - } - } - - qsort (range_entries, num_range_list, sizeof (*range_entries), - range_entry_compar); - - /* DWARF sections under Mach-O have non-zero addresses. */ - if (range_entries[0].ranges_offset != section->address) - warn (_("Range lists in %s section start at 0x%lx\n"), - section->name, range_entries[0].ranges_offset); - - printf (_("Contents of the %s section:\n\n"), section->name); - printf (_(" Offset Begin End\n")); - - for (i = 0; i < num_range_list; i++) - { - struct range_entry *range_entry = &range_entries[i]; - debug_info *debug_info_p = range_entry->debug_info_p; - unsigned int pointer_size; - unsigned long offset; - unsigned char *next; - unsigned long base_address; - - pointer_size = debug_info_p->pointer_size; - - /* DWARF sections under Mach-O have non-zero addresses. */ - offset = range_entry->ranges_offset - section->address; - next = section_begin + offset; - base_address = debug_info_p->base_address; - - if (i > 0) - { - if (start < next) - warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"), - (unsigned long) (start - section_begin), - (unsigned long) (next - section_begin), section->name); - else if (start > next) - warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"), - (unsigned long) (start - section_begin), - (unsigned long) (next - section_begin), section->name); - } - start = next; - - while (1) - { - dwarf_vma begin; - dwarf_vma end; - - /* Note: we use sign extension here in order to be sure that - we can detect the -1 escape value. Sign extension into the - top 32 bits of a 32-bit address will not affect the values - that we display since we always show hex values, and always - the bottom 32-bits. */ - begin = byte_get_signed (start, pointer_size); - start += pointer_size; - end = byte_get_signed (start, pointer_size); - start += pointer_size; - - printf (" %8.8lx ", offset); - - if (begin == 0 && end == 0) - { - printf (_("\n")); - break; - } - - /* Check base address specifiers. */ - if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1) - { - base_address = end; - print_dwarf_vma (begin, pointer_size); - print_dwarf_vma (end, pointer_size); - printf ("(base address)\n"); - continue; - } - - print_dwarf_vma (begin + base_address, pointer_size); - print_dwarf_vma (end + base_address, pointer_size); - - if (begin == end) - fputs (_("(start == end)"), stdout); - else if (begin > end) - fputs (_("(start > end)"), stdout); - - putchar ('\n'); - } - } - putchar ('\n'); - - free (range_entries); - - return 1; -} - -typedef struct Frame_Chunk -{ - struct Frame_Chunk *next; - unsigned char *chunk_start; - int ncols; - /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */ - short int *col_type; - int *col_offset; - char *augmentation; - unsigned int code_factor; - int data_factor; - unsigned long pc_begin; - unsigned long pc_range; - int cfa_reg; - int cfa_offset; - int ra; - unsigned char fde_encoding; - unsigned char cfa_exp; - unsigned char ptr_size; - unsigned char segment_size; -} -Frame_Chunk; - -static const char *const *dwarf_regnames; -static unsigned int dwarf_regnames_count; - -/* A marker for a col_type that means this column was never referenced - in the frame info. */ -#define DW_CFA_unreferenced (-1) - -/* Return 0 if not more space is needed, 1 if more space is needed, - -1 for invalid reg. */ - -static int -frame_need_space (Frame_Chunk *fc, unsigned int reg) -{ - int prev = fc->ncols; - - if (reg < (unsigned int) fc->ncols) - return 0; - - if (dwarf_regnames_count - && reg > dwarf_regnames_count) - return -1; - - fc->ncols = reg + 1; - fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols, - sizeof (short int)); - fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int)); - - while (prev < fc->ncols) - { - fc->col_type[prev] = DW_CFA_unreferenced; - fc->col_offset[prev] = 0; - prev++; - } - return 1; -} - -static const char *const dwarf_regnames_i386[] = -{ - "eax", "ecx", "edx", "ebx", - "esp", "ebp", "esi", "edi", - "eip", "eflags", NULL, - "st0", "st1", "st2", "st3", - "st4", "st5", "st6", "st7", - NULL, NULL, - "xmm0", "xmm1", "xmm2", "xmm3", - "xmm4", "xmm5", "xmm6", "xmm7", - "mm0", "mm1", "mm2", "mm3", - "mm4", "mm5", "mm6", "mm7", - "fcw", "fsw", "mxcsr", - "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL, - "tr", "ldtr" -}; - -void -init_dwarf_regnames_i386 (void) -{ - dwarf_regnames = dwarf_regnames_i386; - dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_i386); -} - -static const char *const dwarf_regnames_x86_64[] = -{ - "rax", "rdx", "rcx", "rbx", - "rsi", "rdi", "rbp", "rsp", - "r8", "r9", "r10", "r11", - "r12", "r13", "r14", "r15", - "rip", - "xmm0", "xmm1", "xmm2", "xmm3", - "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", - "xmm12", "xmm13", "xmm14", "xmm15", - "st0", "st1", "st2", "st3", - "st4", "st5", "st6", "st7", - "mm0", "mm1", "mm2", "mm3", - "mm4", "mm5", "mm6", "mm7", - "rflags", - "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL, - "fs.base", "gs.base", NULL, NULL, - "tr", "ldtr", - "mxcsr", "fcw", "fsw" -}; - -void -init_dwarf_regnames_x86_64 (void) -{ - dwarf_regnames = dwarf_regnames_x86_64; - dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_x86_64); -} - -void -init_dwarf_regnames (unsigned int e_machine) -{ - switch (e_machine) - { - case EM_386: - case EM_486: - init_dwarf_regnames_i386 (); - break; - - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - init_dwarf_regnames_x86_64 (); - break; - - default: - break; - } -} - -static const char * -regname (unsigned int regno, int row) -{ - static char reg[64]; - if (dwarf_regnames - && regno < dwarf_regnames_count - && dwarf_regnames [regno] != NULL) - { - if (row) - return dwarf_regnames [regno]; - snprintf (reg, sizeof (reg), "r%d (%s)", regno, - dwarf_regnames [regno]); - } - else - snprintf (reg, sizeof (reg), "r%d", regno); - return reg; -} - -static void -frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs) -{ - int r; - char tmp[100]; - - if (*max_regs < fc->ncols) - *max_regs = fc->ncols; - - if (*need_col_headers) - { - static const char *sloc = " LOC"; - - *need_col_headers = 0; - - printf ("%-*s CFA ", eh_addr_size * 2, sloc); - - for (r = 0; r < *max_regs; r++) - if (fc->col_type[r] != DW_CFA_unreferenced) - { - if (r == fc->ra) - printf ("ra "); - else - printf ("%-5s ", regname (r, 1)); - } - - printf ("\n"); - } - - printf ("%0*lx ", eh_addr_size * 2, fc->pc_begin); - if (fc->cfa_exp) - strcpy (tmp, "exp"); - else - sprintf (tmp, "%s%+d", regname (fc->cfa_reg, 1), fc->cfa_offset); - printf ("%-8s ", tmp); - - for (r = 0; r < fc->ncols; r++) - { - if (fc->col_type[r] != DW_CFA_unreferenced) - { - switch (fc->col_type[r]) - { - case DW_CFA_undefined: - strcpy (tmp, "u"); - break; - case DW_CFA_same_value: - strcpy (tmp, "s"); - break; - case DW_CFA_offset: - sprintf (tmp, "c%+d", fc->col_offset[r]); - break; - case DW_CFA_val_offset: - sprintf (tmp, "v%+d", fc->col_offset[r]); - break; - case DW_CFA_register: - sprintf (tmp, "%s", regname (fc->col_offset[r], 0)); - break; - case DW_CFA_expression: - strcpy (tmp, "exp"); - break; - case DW_CFA_val_expression: - strcpy (tmp, "vexp"); - break; - default: - strcpy (tmp, "n/a"); - break; - } - printf ("%-5s ", tmp); - } - } - printf ("\n"); -} - -#define GET(N) byte_get (start, N); start += N -#define LEB() read_leb128 (start, & length_return, 0); start += length_return -#define SLEB() read_sleb128 (start, & length_return); start += length_return - -static int -display_debug_frames (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - unsigned char *end = start + section->size; - unsigned char *section_start = start; - Frame_Chunk *chunks = 0; - Frame_Chunk *remembered_state = 0; - Frame_Chunk *rs; - int is_eh = strcmp (section->name, ".eh_frame") == 0; - unsigned int length_return; - int max_regs = 0; - const char *bad_reg = _("bad register: "); - int saved_eh_addr_size = eh_addr_size; - - printf (_("Contents of the %s section:\n"), section->name); - - while (start < end) - { - unsigned char *saved_start; - unsigned char *block_end; - unsigned long length; - unsigned long cie_id; - Frame_Chunk *fc; - Frame_Chunk *cie; - int need_col_headers = 1; - unsigned char *augmentation_data = NULL; - unsigned long augmentation_data_len = 0; - int encoded_ptr_size = saved_eh_addr_size; - int offset_size; - int initial_length_size; - - saved_start = start; - length = byte_get (start, 4); start += 4; - - if (length == 0) - { - printf ("\n%08lx ZERO terminator\n\n", - (unsigned long)(saved_start - section_start)); - continue; - } - - if (length == 0xffffffff) - { - length = byte_get (start, 8); - start += 8; - offset_size = 8; - initial_length_size = 12; - } - else - { - offset_size = 4; - initial_length_size = 4; - } - - block_end = saved_start + length + initial_length_size; - if (block_end > end) - { - warn ("Invalid length %#08lx in FDE at %#08lx\n", - length, (unsigned long)(saved_start - section_start)); - block_end = end; - } - cie_id = byte_get (start, offset_size); start += offset_size; - - if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID)) - { - int version; - - fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); - memset (fc, 0, sizeof (Frame_Chunk)); - - fc->next = chunks; - chunks = fc; - fc->chunk_start = saved_start; - fc->ncols = 0; - fc->col_type = (short int *) xmalloc (sizeof (short int)); - fc->col_offset = (int *) xmalloc (sizeof (int)); - frame_need_space (fc, max_regs - 1); - - version = *start++; - - fc->augmentation = (char *) start; - start = (unsigned char *) strchr ((char *) start, '\0') + 1; - - if (strcmp (fc->augmentation, "eh") == 0) - start += eh_addr_size; - - if (version >= 4) - { - fc->ptr_size = GET (1); - fc->segment_size = GET (1); - eh_addr_size = fc->ptr_size; - } - else - { - fc->ptr_size = eh_addr_size; - fc->segment_size = 0; - } - fc->code_factor = LEB (); - fc->data_factor = SLEB (); - if (version == 1) - { - fc->ra = GET (1); - } - else - { - fc->ra = LEB (); - } - - if (fc->augmentation[0] == 'z') - { - augmentation_data_len = LEB (); - augmentation_data = start; - start += augmentation_data_len; - } - cie = fc; - - if (do_debug_frames_interp) - printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n", - (unsigned long)(saved_start - section_start), length, cie_id, - fc->augmentation, fc->code_factor, fc->data_factor, - fc->ra); - else - { - printf ("\n%08lx %08lx %08lx CIE\n", - (unsigned long)(saved_start - section_start), length, cie_id); - printf (" Version: %d\n", version); - printf (" Augmentation: \"%s\"\n", fc->augmentation); - if (version >= 4) - { - printf (" Pointer Size: %u\n", fc->ptr_size); - printf (" Segment Size: %u\n", fc->segment_size); - } - printf (" Code alignment factor: %u\n", fc->code_factor); - printf (" Data alignment factor: %d\n", fc->data_factor); - printf (" Return address column: %d\n", fc->ra); - - if (augmentation_data_len) - { - unsigned long i; - printf (" Augmentation data: "); - for (i = 0; i < augmentation_data_len; ++i) - printf (" %02x", augmentation_data[i]); - putchar ('\n'); - } - putchar ('\n'); - } - - if (augmentation_data_len) - { - unsigned char *p, *q; - p = (unsigned char *) fc->augmentation + 1; - q = augmentation_data; - - while (1) - { - if (*p == 'L') - q++; - else if (*p == 'P') - q += 1 + size_of_encoded_value (*q); - else if (*p == 'R') - fc->fde_encoding = *q++; - else if (*p == 'S') - ; - else - break; - p++; - } - - if (fc->fde_encoding) - encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); - } - - frame_need_space (fc, fc->ra); - } - else - { - unsigned char *look_for; - static Frame_Chunk fde_fc; - unsigned long segment_selector; - - fc = & fde_fc; - memset (fc, 0, sizeof (Frame_Chunk)); - - look_for = is_eh ? start - 4 - cie_id : section_start + cie_id; - - for (cie = chunks; cie ; cie = cie->next) - if (cie->chunk_start == look_for) - break; - - if (!cie) - { - warn ("Invalid CIE pointer %#08lx in FDE at %#08lx\n", - cie_id, (unsigned long)(saved_start - section_start)); - fc->ncols = 0; - fc->col_type = (short int *) xmalloc (sizeof (short int)); - fc->col_offset = (int *) xmalloc (sizeof (int)); - frame_need_space (fc, max_regs - 1); - cie = fc; - fc->augmentation = ""; - fc->fde_encoding = 0; - fc->ptr_size = eh_addr_size; - fc->segment_size = 0; - } - else - { - fc->ncols = cie->ncols; - fc->col_type = (short int *) xcmalloc (fc->ncols, sizeof (short int)); - fc->col_offset = (int *) xcmalloc (fc->ncols, sizeof (int)); - memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); - memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); - fc->augmentation = cie->augmentation; - fc->ptr_size = cie->ptr_size; - eh_addr_size = cie->ptr_size; - fc->segment_size = cie->segment_size; - fc->code_factor = cie->code_factor; - fc->data_factor = cie->data_factor; - fc->cfa_reg = cie->cfa_reg; - fc->cfa_offset = cie->cfa_offset; - fc->ra = cie->ra; - frame_need_space (fc, max_regs - 1); - fc->fde_encoding = cie->fde_encoding; - } - - if (fc->fde_encoding) - encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); - - segment_selector = 0; - if (fc->segment_size) - { - segment_selector = byte_get (start, fc->segment_size); - start += fc->segment_size; - } - fc->pc_begin = get_encoded_value (start, fc->fde_encoding, section); - start += encoded_ptr_size; - fc->pc_range = byte_get (start, encoded_ptr_size); - start += encoded_ptr_size; - - if (cie->augmentation[0] == 'z') - { - augmentation_data_len = LEB (); - augmentation_data = start; - start += augmentation_data_len; - } - - printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=", - (unsigned long)(saved_start - section_start), length, cie_id, - (unsigned long)(cie->chunk_start - section_start)); - if (fc->segment_size) - printf ("%04lx:", segment_selector); - printf ("%08lx..%08lx\n", fc->pc_begin, fc->pc_begin + fc->pc_range); - if (! do_debug_frames_interp && augmentation_data_len) - { - unsigned long i; - - printf (" Augmentation data: "); - for (i = 0; i < augmentation_data_len; ++i) - printf (" %02x", augmentation_data[i]); - putchar ('\n'); - putchar ('\n'); - } - } - - /* At this point, fc is the current chunk, cie (if any) is set, and - we're about to interpret instructions for the chunk. */ - /* ??? At present we need to do this always, since this sizes the - fc->col_type and fc->col_offset arrays, which we write into always. - We should probably split the interpreted and non-interpreted bits - into two different routines, since there's so much that doesn't - really overlap between them. */ - if (1 || do_debug_frames_interp) - { - /* Start by making a pass over the chunk, allocating storage - and taking note of what registers are used. */ - unsigned char *tmp = start; - - while (start < block_end) - { - unsigned op, opa; - unsigned long reg, temp; - - op = *start++; - opa = op & 0x3f; - if (op & 0xc0) - op &= 0xc0; - - /* Warning: if you add any more cases to this switch, be - sure to add them to the corresponding switch below. */ - switch (op) - { - case DW_CFA_advance_loc: - break; - case DW_CFA_offset: - LEB (); - if (frame_need_space (fc, opa) >= 0) - fc->col_type[opa] = DW_CFA_undefined; - break; - case DW_CFA_restore: - if (frame_need_space (fc, opa) >= 0) - fc->col_type[opa] = DW_CFA_undefined; - 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: - reg = LEB (); LEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_restore_extended: - reg = LEB (); - frame_need_space (fc, reg); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_undefined: - reg = LEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_same_value: - reg = LEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_register: - reg = LEB (); LEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_def_cfa: - LEB (); LEB (); - break; - case DW_CFA_def_cfa_register: - LEB (); - break; - case DW_CFA_def_cfa_offset: - LEB (); - break; - case DW_CFA_def_cfa_expression: - temp = LEB (); - start += temp; - break; - case DW_CFA_expression: - case DW_CFA_val_expression: - reg = LEB (); - temp = LEB (); - start += temp; - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_offset_extended_sf: - case DW_CFA_val_offset_sf: - reg = LEB (); SLEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - case DW_CFA_def_cfa_sf: - LEB (); SLEB (); - break; - case DW_CFA_def_cfa_offset_sf: - SLEB (); - break; - case DW_CFA_MIPS_advance_loc8: - start += 8; - break; - case DW_CFA_GNU_args_size: - LEB (); - break; - case DW_CFA_GNU_negative_offset_extended: - reg = LEB (); LEB (); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; - break; - default: - break; - } - } - start = tmp; - } - - /* Now we know what registers are used, make a second pass over - the chunk, this time actually printing out the info. */ - - while (start < block_end) - { - unsigned op, opa; - unsigned long ul, reg, roffs; - long l, ofs; - dwarf_vma vma; - const char *reg_prefix = ""; - - op = *start++; - opa = op & 0x3f; - if (op & 0xc0) - op &= 0xc0; - - /* Warning: if you add any more cases to this switch, be - sure to add them to the corresponding switch above. */ - switch (op) - { - case DW_CFA_advance_loc: - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_advance_loc: %d to %08lx\n", - opa * fc->code_factor, - fc->pc_begin + opa * fc->code_factor); - fc->pc_begin += opa * fc->code_factor; - break; - - case DW_CFA_offset: - roffs = LEB (); - if (opa >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_offset: %s%s at cfa%+ld\n", - reg_prefix, regname (opa, 0), - roffs * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[opa] = DW_CFA_offset; - fc->col_offset[opa] = roffs * fc->data_factor; - } - break; - - case DW_CFA_restore: - if (opa >= (unsigned int) cie->ncols - || opa >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_restore: %s%s\n", - reg_prefix, regname (opa, 0)); - if (*reg_prefix == '\0') - { - fc->col_type[opa] = cie->col_type[opa]; - fc->col_offset[opa] = cie->col_offset[opa]; - } - break; - - case DW_CFA_set_loc: - vma = get_encoded_value (start, fc->fde_encoding, section); - start += encoded_ptr_size; - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); - fc->pc_begin = vma; - break; - - case DW_CFA_advance_loc1: - ofs = byte_get (start, 1); start += 1; - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_advance_loc1: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); - fc->pc_begin += ofs * fc->code_factor; - break; - - case DW_CFA_advance_loc2: - ofs = byte_get (start, 2); start += 2; - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_advance_loc2: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); - fc->pc_begin += ofs * fc->code_factor; - break; - - case DW_CFA_advance_loc4: - ofs = byte_get (start, 4); start += 4; - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_advance_loc4: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); - fc->pc_begin += ofs * fc->code_factor; - break; - - case DW_CFA_offset_extended: - reg = LEB (); - roffs = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_offset_extended: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - roffs * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = roffs * fc->data_factor; - } - break; - - case DW_CFA_val_offset: - reg = LEB (); - roffs = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_val_offset: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - roffs * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_val_offset; - fc->col_offset[reg] = roffs * fc->data_factor; - } - break; - - case DW_CFA_restore_extended: - reg = LEB (); - if (reg >= (unsigned int) cie->ncols - || reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_restore_extended: %s%s\n", - reg_prefix, regname (reg, 0)); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = cie->col_type[reg]; - fc->col_offset[reg] = cie->col_offset[reg]; - } - break; - - case DW_CFA_undefined: - reg = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_undefined: %s%s\n", - reg_prefix, regname (reg, 0)); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_undefined; - fc->col_offset[reg] = 0; - } - break; - - case DW_CFA_same_value: - reg = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_same_value: %s%s\n", - reg_prefix, regname (reg, 0)); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_same_value; - fc->col_offset[reg] = 0; - } - break; - - case DW_CFA_register: - reg = LEB (); - roffs = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - { - printf (" DW_CFA_register: %s%s in ", - reg_prefix, regname (reg, 0)); - puts (regname (roffs, 0)); - } - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_register; - fc->col_offset[reg] = roffs; - } - break; - - case DW_CFA_remember_state: - if (! do_debug_frames_interp) - printf (" DW_CFA_remember_state\n"); - rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); - rs->ncols = fc->ncols; - rs->col_type = (short int *) xcmalloc (rs->ncols, - sizeof (short int)); - rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (int)); - memcpy (rs->col_type, fc->col_type, rs->ncols); - memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); - rs->next = remembered_state; - remembered_state = rs; - break; - - case DW_CFA_restore_state: - if (! do_debug_frames_interp) - printf (" DW_CFA_restore_state\n"); - rs = remembered_state; - if (rs) - { - remembered_state = rs->next; - frame_need_space (fc, rs->ncols - 1); - memcpy (fc->col_type, rs->col_type, rs->ncols); - memcpy (fc->col_offset, rs->col_offset, - rs->ncols * sizeof (int)); - free (rs->col_type); - free (rs->col_offset); - free (rs); - } - else if (do_debug_frames_interp) - printf ("Mismatched DW_CFA_restore_state\n"); - break; - - case DW_CFA_def_cfa: - fc->cfa_reg = LEB (); - fc->cfa_offset = LEB (); - fc->cfa_exp = 0; - if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa: %s ofs %d\n", - regname (fc->cfa_reg, 0), fc->cfa_offset); - break; - - case DW_CFA_def_cfa_register: - fc->cfa_reg = LEB (); - fc->cfa_exp = 0; - if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_register: %s\n", - regname (fc->cfa_reg, 0)); - break; - - case DW_CFA_def_cfa_offset: - fc->cfa_offset = LEB (); - if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset); - break; - - case DW_CFA_nop: - if (! do_debug_frames_interp) - printf (" DW_CFA_nop\n"); - break; - - case DW_CFA_def_cfa_expression: - ul = LEB (); - if (! do_debug_frames_interp) - { - printf (" DW_CFA_def_cfa_expression ("); - decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); - printf (")\n"); - } - fc->cfa_exp = 1; - start += ul; - break; - - case DW_CFA_expression: - reg = LEB (); - ul = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - { - printf (" DW_CFA_expression: %s%s (", - reg_prefix, regname (reg, 0)); - decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); - printf (")\n"); - } - if (*reg_prefix == '\0') - fc->col_type[reg] = DW_CFA_expression; - start += ul; - break; - - case DW_CFA_val_expression: - reg = LEB (); - ul = LEB (); - if (reg >= (unsigned int) fc->ncols) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - { - printf (" DW_CFA_val_expression: %s%s (", - reg_prefix, regname (reg, 0)); - decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); - printf (")\n"); - } - if (*reg_prefix == '\0') - fc->col_type[reg] = DW_CFA_val_expression; - start += ul; - break; - - case DW_CFA_offset_extended_sf: - reg = LEB (); - l = SLEB (); - if (frame_need_space (fc, reg) < 0) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_offset_extended_sf: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = l * fc->data_factor; - } - break; - - case DW_CFA_val_offset_sf: - reg = LEB (); - l = SLEB (); - if (frame_need_space (fc, reg) < 0) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_val_offset_sf: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_val_offset; - fc->col_offset[reg] = l * fc->data_factor; - } - break; - - case DW_CFA_def_cfa_sf: - fc->cfa_reg = LEB (); - fc->cfa_offset = SLEB (); - fc->cfa_offset = fc->cfa_offset * fc->data_factor; - fc->cfa_exp = 0; - if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_sf: %s ofs %d\n", - regname (fc->cfa_reg, 0), fc->cfa_offset); - break; - - case DW_CFA_def_cfa_offset_sf: - fc->cfa_offset = SLEB (); - fc->cfa_offset = fc->cfa_offset * fc->data_factor; - if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset); - break; - - case DW_CFA_MIPS_advance_loc8: - ofs = byte_get (start, 8); start += 8; - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - else - printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); - fc->pc_begin += ofs * fc->code_factor; - break; - - case DW_CFA_GNU_window_save: - if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_window_save\n"); - break; - - case DW_CFA_GNU_args_size: - ul = LEB (); - if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_args_size: %ld\n", ul); - break; - - case DW_CFA_GNU_negative_offset_extended: - reg = LEB (); - l = - LEB (); - if (frame_need_space (fc, reg) < 0) - reg_prefix = bad_reg; - if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_GNU_negative_offset_extended: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); - if (*reg_prefix == '\0') - { - fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = l * fc->data_factor; - } - break; - - default: - if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user) - printf (_(" DW_CFA_??? (User defined call frame op: %#x)\n"), op); - else - warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op); - start = block_end; - } - } - - if (do_debug_frames_interp) - frame_display_row (fc, &need_col_headers, &max_regs); - - start = block_end; - eh_addr_size = saved_eh_addr_size; - } - - printf ("\n"); - - return 1; -} - -#undef GET -#undef LEB -#undef SLEB - -static int -display_gdb_index (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - unsigned char *start = section->start; - uint32_t version; - uint32_t cu_list_offset, tu_list_offset; - uint32_t address_table_offset, symbol_table_offset, constant_pool_offset; - unsigned int cu_list_elements, tu_list_elements; - unsigned int address_table_size, symbol_table_slots; - unsigned char *cu_list, *tu_list; - unsigned char *address_table, *symbol_table, *constant_pool; - unsigned int i; - - /* The documentation for the format of this file is in gdb/dwarf2read.c. */ - - printf (_("Contents of the %s section:\n"), section->name); - - if (section->size < 6 * sizeof (uint32_t)) - { - warn (_("Truncated header in the %s section.\n"), section->name); - return 0; - } - - version = byte_get_little_endian (start, 4); - printf (_("Version %ld\n"), (long) version); - - /* Prior versions are obsolete, and future versions may not be - backwards compatible. */ - switch (version) - { - case 3: - warn (_("The address table data in version 3 may be wrong.\n")); - break; - case 4: - warn (_("Version 4 does not support case insensitive lookups.\n")); - break; - case 5: - break; - default: - warn (_("Unsupported version %lu.\n"), (unsigned long) version); - return 0; - } - - cu_list_offset = byte_get_little_endian (start + 4, 4); - tu_list_offset = byte_get_little_endian (start + 8, 4); - address_table_offset = byte_get_little_endian (start + 12, 4); - symbol_table_offset = byte_get_little_endian (start + 16, 4); - constant_pool_offset = byte_get_little_endian (start + 20, 4); - - if (cu_list_offset > section->size - || tu_list_offset > section->size - || address_table_offset > section->size - || symbol_table_offset > section->size - || constant_pool_offset > section->size) - { - warn (_("Corrupt header in the %s section.\n"), section->name); - return 0; - } - - cu_list_elements = (tu_list_offset - cu_list_offset) / 8; - tu_list_elements = (address_table_offset - tu_list_offset) / 8; - address_table_size = symbol_table_offset - address_table_offset; - symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8; - - cu_list = start + cu_list_offset; - tu_list = start + tu_list_offset; - address_table = start + address_table_offset; - symbol_table = start + symbol_table_offset; - constant_pool = start + constant_pool_offset; - - printf (_("\nCU table:\n")); - for (i = 0; i < cu_list_elements; i += 2) - { - uint64_t cu_offset = byte_get_little_endian (cu_list + i * 8, 8); - uint64_t cu_length = byte_get_little_endian (cu_list + i * 8 + 8, 8); - - printf (_("[%3u] 0x%lx - 0x%lx\n"), i / 2, - (unsigned long) cu_offset, - (unsigned long) (cu_offset + cu_length - 1)); - } - - printf (_("\nTU table:\n")); - for (i = 0; i < tu_list_elements; i += 3) - { - uint64_t tu_offset = byte_get_little_endian (tu_list + i * 8, 8); - uint64_t type_offset = byte_get_little_endian (tu_list + i * 8 + 8, 8); - uint64_t signature = byte_get_little_endian (tu_list + i * 8 + 16, 8); - - printf (_("[%3u] 0x%lx 0x%lx "), i / 3, - (unsigned long) tu_offset, - (unsigned long) type_offset); - print_dwarf_vma (signature, 8); - printf ("\n"); - } - - printf (_("\nAddress table:\n")); - for (i = 0; i < address_table_size; i += 2 * 8 + 4) - { - uint64_t low = byte_get_little_endian (address_table + i, 8); - uint64_t high = byte_get_little_endian (address_table + i + 8, 8); - uint32_t cu_index = byte_get_little_endian (address_table + i + 16, 4); - - print_dwarf_vma (low, 8); - print_dwarf_vma (high, 8); - printf (_("%lu\n"), (unsigned long) cu_index); - } - - printf (_("\nSymbol table:\n")); - for (i = 0; i < symbol_table_slots; ++i) - { - uint32_t name_offset = byte_get_little_endian (symbol_table + i * 8, 4); - uint32_t cu_vector_offset = byte_get_little_endian (symbol_table + i * 8 + 4, 4); - uint32_t num_cus, cu; - - if (name_offset != 0 - || cu_vector_offset != 0) - { - unsigned int j; - - printf ("[%3u] %s:", i, constant_pool + name_offset); - num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4); - for (j = 0; j < num_cus; ++j) - { - cu = byte_get_little_endian (constant_pool + cu_vector_offset + 4 + j * 4, 4); - /* Convert to TU number if it's for a type unit. */ - if (cu >= cu_list_elements / 2) - printf (" T%lu", (unsigned long) (cu - cu_list_elements / 2)); - else - printf (" %lu", (unsigned long) cu); - } - printf ("\n"); - } - } - - return 1; -} - -static int -display_debug_not_supported (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) -{ - printf (_("Displaying the debug contents of section %s is not yet supported.\n"), - section->name); - - return 1; -} - -void * -cmalloc (size_t nmemb, size_t size) -{ - /* Check for overflow. */ - if (nmemb >= ~(size_t) 0 / size) - return NULL; - else - return malloc (nmemb * size); -} - -void * -xcmalloc (size_t nmemb, size_t size) -{ - /* Check for overflow. */ - if (nmemb >= ~(size_t) 0 / size) - return NULL; - else - return xmalloc (nmemb * size); -} - -void * -xcrealloc (void *ptr, size_t nmemb, size_t size) -{ - /* Check for overflow. */ - if (nmemb >= ~(size_t) 0 / size) - return NULL; - else - return xrealloc (ptr, nmemb * size); -} - -void -free_debug_memory (void) -{ - unsigned int i; - - free_abbrevs (); - - for (i = 0; i < max; i++) - free_debug_section ((enum dwarf_section_display_enum) i); - - if (debug_information != NULL) - { - if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE) - { - for (i = 0; i < num_debug_info_entries; i++) - { - if (!debug_information [i].max_loc_offsets) - { - free (debug_information [i].loc_offsets); - free (debug_information [i].have_frame_base); - } - if (!debug_information [i].max_range_lists) - free (debug_information [i].range_lists); - } - } - - free (debug_information); - debug_information = NULL; - num_debug_info_entries = 0; - } -} - -void -dwarf_select_sections_by_names (const char *names) -{ - typedef struct - { - const char * option; - int * variable; - int val; - } - debug_dump_long_opts; - - static const debug_dump_long_opts opts_table [] = - { - /* Please keep this table alpha- sorted. */ - { "Ranges", & do_debug_ranges, 1 }, - { "abbrev", & do_debug_abbrevs, 1 }, - { "aranges", & do_debug_aranges, 1 }, - { "frames", & do_debug_frames, 1 }, - { "frames-interp", & do_debug_frames_interp, 1 }, - { "info", & do_debug_info, 1 }, - { "line", & do_debug_lines, FLAG_DEBUG_LINES_RAW }, /* For backwards compatibility. */ - { "rawline", & do_debug_lines, FLAG_DEBUG_LINES_RAW }, - { "decodedline", & do_debug_lines, FLAG_DEBUG_LINES_DECODED }, - { "loc", & do_debug_loc, 1 }, - { "macro", & do_debug_macinfo, 1 }, - { "pubnames", & do_debug_pubnames, 1 }, - { "pubtypes", & do_debug_pubtypes, 1 }, - /* This entry is for compatability - with earlier versions of readelf. */ - { "ranges", & do_debug_aranges, 1 }, - { "str", & do_debug_str, 1 }, - /* The special .gdb_index section. */ - { "gdb_index", & do_gdb_index, 1 }, - /* These trace_* sections are used by Itanium VMS. */ - { "trace_abbrev", & do_trace_abbrevs, 1 }, - { "trace_aranges", & do_trace_aranges, 1 }, - { "trace_info", & do_trace_info, 1 }, - { NULL, NULL, 0 } - }; - - const char *p; - - p = names; - while (*p) - { - const debug_dump_long_opts * entry; - - for (entry = opts_table; entry->option; entry++) - { - size_t len = strlen (entry->option); - - if (strncmp (p, entry->option, len) == 0 - && (p[len] == ',' || p[len] == '\0')) - { - * entry->variable |= entry->val; - - /* The --debug-dump=frames-interp option also - enables the --debug-dump=frames option. */ - if (do_debug_frames_interp) - do_debug_frames = 1; - - p += len; - break; - } - } - - if (entry->option == NULL) - { - warn (_("Unrecognized debug option '%s'\n"), p); - p = strchr (p, ','); - if (p == NULL) - break; - } - - if (*p == ',') - p++; - } -} - -void -dwarf_select_sections_by_letters (const char *letters) -{ - unsigned int lindex = 0; - - while (letters[lindex]) - switch (letters[lindex++]) - { - case 'i': - do_debug_info = 1; - break; - - case 'a': - do_debug_abbrevs = 1; - break; - - case 'l': - do_debug_lines |= FLAG_DEBUG_LINES_RAW; - break; - - case 'L': - do_debug_lines |= FLAG_DEBUG_LINES_DECODED; - break; - - case 'p': - do_debug_pubnames = 1; - break; - - case 't': - do_debug_pubtypes = 1; - break; - - case 'r': - do_debug_aranges = 1; - break; - - case 'R': - do_debug_ranges = 1; - break; - - case 'F': - do_debug_frames_interp = 1; - case 'f': - do_debug_frames = 1; - break; - - case 'm': - do_debug_macinfo = 1; - break; - - case 's': - do_debug_str = 1; - break; - - case 'o': - do_debug_loc = 1; - break; - - default: - warn (_("Unrecognized debug option '%s'\n"), optarg); - break; - } -} - -void -dwarf_select_sections_all (void) -{ - do_debug_info = 1; - do_debug_abbrevs = 1; - do_debug_lines = FLAG_DEBUG_LINES_RAW; - do_debug_pubnames = 1; - do_debug_pubtypes = 1; - do_debug_aranges = 1; - do_debug_ranges = 1; - do_debug_frames = 1; - do_debug_macinfo = 1; - do_debug_str = 1; - do_debug_loc = 1; - do_gdb_index = 1; - do_trace_info = 1; - do_trace_abbrevs = 1; - do_trace_aranges = 1; -} - -struct dwarf_section_display debug_displays[] = -{ - { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0 }, - display_debug_abbrev, &do_debug_abbrevs, 0 }, - { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0 }, - display_debug_aranges, &do_debug_aranges, 1 }, - { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0 }, - display_debug_frames, &do_debug_frames, 1 }, - { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 }, - display_debug_info, &do_debug_info, 1 }, - { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0 }, - display_debug_lines, &do_debug_lines, 1 }, - { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0 }, - display_debug_pubnames, &do_debug_pubnames, 0 }, - { { ".eh_frame", "", NULL, NULL, 0, 0 }, - display_debug_frames, &do_debug_frames, 1 }, - { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0 }, - display_debug_macinfo, &do_debug_macinfo, 0 }, - { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0 }, - display_debug_macro, &do_debug_macinfo, 1 }, - { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 }, - display_debug_str, &do_debug_str, 0 }, - { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 }, - display_debug_loc, &do_debug_loc, 1 }, - { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 }, - display_debug_pubnames, &do_debug_pubtypes, 0 }, - { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 }, - display_debug_ranges, &do_debug_ranges, 1 }, - { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0 }, - display_debug_not_supported, NULL, 0 }, - { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0 }, - display_debug_not_supported, NULL, 0 }, - { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0 }, - display_debug_types, &do_debug_info, 1 }, - { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0 }, - display_debug_not_supported, NULL, 0 }, - { { ".gdb_index", "", NULL, NULL, 0, 0 }, - display_gdb_index, &do_gdb_index, 0 }, - { { ".trace_info", "", NULL, NULL, 0, 0 }, - display_trace_info, &do_trace_info, 1 }, - { { ".trace_abbrev", "", NULL, NULL, 0, 0 }, - display_debug_abbrev, &do_trace_abbrevs, 0 }, - { { ".trace_aranges", "", NULL, NULL, 0, 0 }, - display_debug_aranges, &do_trace_aranges, 0 } -}; diff --git a/contrib/binutils-2.22/binutils/dwarf.h b/contrib/binutils-2.22/binutils/dwarf.h deleted file mode 100644 index 7a755c9a28..0000000000 --- a/contrib/binutils-2.22/binutils/dwarf.h +++ /dev/null @@ -1,224 +0,0 @@ -/* dwarf.h - DWARF support header file - Copyright 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -typedef unsigned HOST_WIDEST_INT dwarf_vma; -typedef HOST_WIDEST_INT dwarf_signed_vma; -typedef unsigned HOST_WIDEST_INT dwarf_size_type; - -/* Structure found in the .debug_line section. */ -typedef struct -{ - unsigned char li_length [4]; - unsigned char li_version [2]; - unsigned char li_prologue_length [4]; - unsigned char li_min_insn_length [1]; - unsigned char li_default_is_stmt [1]; - unsigned char li_line_base [1]; - unsigned char li_line_range [1]; - unsigned char li_opcode_base [1]; -} -DWARF2_External_LineInfo; - -typedef struct -{ - dwarf_vma li_length; - unsigned short li_version; - unsigned int li_prologue_length; - unsigned char li_min_insn_length; - unsigned char li_max_ops_per_insn; - unsigned char li_default_is_stmt; - int li_line_base; - unsigned char li_line_range; - unsigned char li_opcode_base; -} -DWARF2_Internal_LineInfo; - -/* Structure found in .debug_pubnames section. */ -typedef struct -{ - unsigned char pn_length [4]; - unsigned char pn_version [2]; - unsigned char pn_offset [4]; - unsigned char pn_size [4]; -} -DWARF2_External_PubNames; - -typedef struct -{ - dwarf_vma pn_length; - unsigned short pn_version; - dwarf_vma pn_offset; - dwarf_vma pn_size; -} -DWARF2_Internal_PubNames; - -/* Structure found in .debug_info section. */ -typedef struct -{ - unsigned char cu_length [4]; - unsigned char cu_version [2]; - unsigned char cu_abbrev_offset [4]; - unsigned char cu_pointer_size [1]; -} -DWARF2_External_CompUnit; - -typedef struct -{ - dwarf_vma cu_length; - unsigned short cu_version; - dwarf_vma cu_abbrev_offset; - unsigned char cu_pointer_size; -} -DWARF2_Internal_CompUnit; - -typedef struct -{ - unsigned char ar_length [4]; - unsigned char ar_version [2]; - unsigned char ar_info_offset [4]; - unsigned char ar_pointer_size [1]; - unsigned char ar_segment_size [1]; -} -DWARF2_External_ARange; - -typedef struct -{ - dwarf_vma ar_length; - unsigned short ar_version; - dwarf_vma ar_info_offset; - unsigned char ar_pointer_size; - unsigned char ar_segment_size; -} -DWARF2_Internal_ARange; - -struct dwarf_section -{ - /* A debug section has a different name when it's stored compressed - or not. COMPRESSED_NAME and UNCOMPRESSED_NAME are the two - possibilities. NAME is set to whichever one is used for this - input file, as determined by load_debug_section(). */ - const char *uncompressed_name; - const char *compressed_name; - const char *name; - unsigned char *start; - dwarf_vma address; - dwarf_size_type size; -}; - -/* A structure containing the name of a debug section - and a pointer to a function that can decode it. */ -struct dwarf_section_display -{ - struct dwarf_section section; - int (*display) (struct dwarf_section *, void *); - int *enabled; - unsigned int relocate : 1; -}; - -enum dwarf_section_display_enum -{ - abbrev = 0, - aranges, - frame, - info, - line, - pubnames, - eh_frame, - macinfo, - macro, - str, - loc, - pubtypes, - ranges, - static_func, - static_vars, - types, - weaknames, - trace_info, - trace_abbrev, - trace_aranges, - max -}; - -extern struct dwarf_section_display debug_displays []; - -/* This structure records the information that - we extract from the.debug_info section. */ -typedef struct -{ - unsigned int pointer_size; - unsigned int offset_size; - int dwarf_version; - dwarf_vma cu_offset; - dwarf_vma base_address; - /* This is an array of offsets to the location list table. */ - dwarf_vma * loc_offsets; - int * have_frame_base; - unsigned int num_loc_offsets; - unsigned int max_loc_offsets; - /* List of .debug_ranges offsets seen in this .debug_info. */ - dwarf_vma * range_lists; - unsigned int num_range_lists; - unsigned int max_range_lists; -} -debug_info; - -extern int eh_addr_size; - -extern int do_debug_info; -extern int do_debug_abbrevs; -extern int do_debug_lines; -extern int do_debug_pubnames; -extern int do_debug_pubtypes; -extern int do_debug_aranges; -extern int do_debug_ranges; -extern int do_debug_frames; -extern int do_debug_frames_interp; -extern int do_debug_macinfo; -extern int do_debug_str; -extern int do_debug_loc; -extern int do_gdb_index; -extern int do_trace_info; -extern int do_trace_abbrevs; -extern int do_trace_aranges; -extern int do_wide; - -extern int dwarf_cutoff_level; -extern unsigned long dwarf_start_die; - -extern void init_dwarf_regnames (unsigned int); -extern void init_dwarf_regnames_i386 (void); -extern void init_dwarf_regnames_x86_64 (void); - -extern int load_debug_section (enum dwarf_section_display_enum, void *); -extern void free_debug_section (enum dwarf_section_display_enum); - -extern void free_debug_memory (void); - -extern void dwarf_select_sections_by_names (const char *); -extern void dwarf_select_sections_by_letters (const char *); -extern void dwarf_select_sections_all (void); - -void * cmalloc (size_t, size_t); -void * xcmalloc (size_t, size_t); -void * xcrealloc (void *, size_t, size_t); - -dwarf_vma read_leb128 (unsigned char *, unsigned int *, int); diff --git a/contrib/binutils-2.22/binutils/elfcomm.c b/contrib/binutils-2.22/binutils/elfcomm.c deleted file mode 100644 index e44dee8348..0000000000 --- a/contrib/binutils-2.22/binutils/elfcomm.c +++ /dev/null @@ -1,658 +0,0 @@ -/* elfcomm.c -- common code for ELF format file. - Copyright 2010 - Free Software Foundation, Inc. - - Originally developed by Eric Youngdale - Modifications by Nick Clifton - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "libiberty.h" -#include "filenames.h" -#include "bfd.h" -#include "aout/ar.h" -#include "bucomm.h" -#include "elfcomm.h" - -void -error (const char *message, ...) -{ - va_list args; - - va_start (args, message); - fprintf (stderr, _("%s: Error: "), program_name); - vfprintf (stderr, message, args); - va_end (args); -} - -void -warn (const char *message, ...) -{ - va_list args; - - va_start (args, message); - fprintf (stderr, _("%s: Warning: "), program_name); - vfprintf (stderr, message, args); - va_end (args); -} - -void (*byte_put) (unsigned char *, elf_vma, int); - -void -byte_put_little_endian (unsigned char * field, elf_vma value, int size) -{ - switch (size) - { - case 8: - field[7] = (((value >> 24) >> 24) >> 8) & 0xff; - field[6] = ((value >> 24) >> 24) & 0xff; - field[5] = ((value >> 24) >> 16) & 0xff; - field[4] = ((value >> 24) >> 8) & 0xff; - /* Fall through. */ - case 4: - field[3] = (value >> 24) & 0xff; - /* Fall through. */ - case 3: - field[2] = (value >> 16) & 0xff; - /* Fall through. */ - case 2: - field[1] = (value >> 8) & 0xff; - /* Fall through. */ - case 1: - field[0] = value & 0xff; - break; - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - -void -byte_put_big_endian (unsigned char * field, elf_vma value, int size) -{ - switch (size) - { - case 8: - field[7] = value & 0xff; - field[6] = (value >> 8) & 0xff; - field[5] = (value >> 16) & 0xff; - field[4] = (value >> 24) & 0xff; - value >>= 16; - value >>= 16; - /* Fall through. */ - case 4: - field[3] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 3: - field[2] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 2: - field[1] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 1: - field[0] = value & 0xff; - break; - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - -elf_vma (*byte_get) (unsigned char *, int); - -elf_vma -byte_get_little_endian (unsigned char *field, int size) -{ - switch (size) - { - case 1: - return *field; - - case 2: - return ((unsigned int) (field[0])) - | (((unsigned int) (field[1])) << 8); - - case 3: - return ((unsigned long) (field[0])) - | (((unsigned long) (field[1])) << 8) - | (((unsigned long) (field[2])) << 16); - - case 4: - return ((unsigned long) (field[0])) - | (((unsigned long) (field[1])) << 8) - | (((unsigned long) (field[2])) << 16) - | (((unsigned long) (field[3])) << 24); - - case 8: - if (sizeof (elf_vma) == 8) - return ((elf_vma) (field[0])) - | (((elf_vma) (field[1])) << 8) - | (((elf_vma) (field[2])) << 16) - | (((elf_vma) (field[3])) << 24) - | (((elf_vma) (field[4])) << 32) - | (((elf_vma) (field[5])) << 40) - | (((elf_vma) (field[6])) << 48) - | (((elf_vma) (field[7])) << 56); - else if (sizeof (elf_vma) == 4) - /* We want to extract data from an 8 byte wide field and - place it into a 4 byte wide field. Since this is a little - endian source we can just use the 4 byte extraction code. */ - return ((unsigned long) (field[0])) - | (((unsigned long) (field[1])) << 8) - | (((unsigned long) (field[2])) << 16) - | (((unsigned long) (field[3])) << 24); - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - -elf_vma -byte_get_big_endian (unsigned char *field, int size) -{ - switch (size) - { - case 1: - return *field; - - case 2: - return ((unsigned int) (field[1])) | (((int) (field[0])) << 8); - - case 3: - return ((unsigned long) (field[2])) - | (((unsigned long) (field[1])) << 8) - | (((unsigned long) (field[0])) << 16); - - case 4: - return ((unsigned long) (field[3])) - | (((unsigned long) (field[2])) << 8) - | (((unsigned long) (field[1])) << 16) - | (((unsigned long) (field[0])) << 24); - - case 8: - if (sizeof (elf_vma) == 8) - return ((elf_vma) (field[7])) - | (((elf_vma) (field[6])) << 8) - | (((elf_vma) (field[5])) << 16) - | (((elf_vma) (field[4])) << 24) - | (((elf_vma) (field[3])) << 32) - | (((elf_vma) (field[2])) << 40) - | (((elf_vma) (field[1])) << 48) - | (((elf_vma) (field[0])) << 56); - else if (sizeof (elf_vma) == 4) - { - /* Although we are extracing data from an 8 byte wide field, - we are returning only 4 bytes of data. */ - field += 4; - return ((unsigned long) (field[3])) - | (((unsigned long) (field[2])) << 8) - | (((unsigned long) (field[1])) << 16) - | (((unsigned long) (field[0])) << 24); - } - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - -elf_vma -byte_get_signed (unsigned char *field, int size) -{ - elf_vma x = byte_get (field, size); - - switch (size) - { - case 1: - return (x ^ 0x80) - 0x80; - case 2: - return (x ^ 0x8000) - 0x8000; - case 4: - return (x ^ 0x80000000) - 0x80000000; - case 8: - return x; - default: - abort (); - } -} - -/* Return the path name for a proxy entry in a thin archive, adjusted - relative to the path name of the thin archive itself if necessary. - Always returns a pointer to malloc'ed memory. */ - -char * -adjust_relative_path (const char *file_name, const char *name, - int name_len) -{ - char * member_file_name; - const char * base_name = lbasename (file_name); - - /* This is a proxy entry for a thin archive member. - If the extended name table contains an absolute path - name, or if the archive is in the current directory, - use the path name as given. Otherwise, we need to - find the member relative to the directory where the - archive is located. */ - if (IS_ABSOLUTE_PATH (name) || base_name == file_name) - { - member_file_name = (char *) malloc (name_len + 1); - if (member_file_name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - memcpy (member_file_name, name, name_len); - member_file_name[name_len] = '\0'; - } - else - { - /* Concatenate the path components of the archive file name - to the relative path name from the extended name table. */ - size_t prefix_len = base_name - file_name; - member_file_name = (char *) malloc (prefix_len + name_len + 1); - if (member_file_name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - memcpy (member_file_name, file_name, prefix_len); - memcpy (member_file_name + prefix_len, name, name_len); - member_file_name[prefix_len + name_len] = '\0'; - } - return member_file_name; -} - -/* Read the symbol table and long-name table from an archive. */ - -int -setup_archive (struct archive_info *arch, const char *file_name, - FILE *file, bfd_boolean is_thin_archive, - bfd_boolean read_symbols) -{ - size_t got; - unsigned long size; - - arch->file_name = strdup (file_name); - arch->file = file; - arch->index_num = 0; - arch->index_array = NULL; - arch->sym_table = NULL; - arch->sym_size = 0; - arch->longnames = NULL; - arch->longnames_size = 0; - arch->nested_member_origin = 0; - arch->is_thin_archive = is_thin_archive; - arch->next_arhdr_offset = SARMAG; - - /* Read the first archive member header. */ - if (fseek (file, SARMAG, SEEK_SET) != 0) - { - error (_("%s: failed to seek to first archive header\n"), file_name); - return 1; - } - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file); - if (got != sizeof arch->arhdr) - { - if (got == 0) - return 0; - - error (_("%s: failed to read archive header\n"), file_name); - return 1; - } - - /* See if this is the archive symbol table. */ - if (const_strneq (arch->arhdr.ar_name, "/ ") - || const_strneq (arch->arhdr.ar_name, "/SYM64/ ")) - { - size = strtoul (arch->arhdr.ar_size, NULL, 10); - size = size + (size & 1); - - arch->next_arhdr_offset += sizeof arch->arhdr + size; - - if (read_symbols) - { - unsigned long i; - /* A buffer used to hold numbers read in from an archive index. - These are always 4 bytes long and stored in big-endian - format. */ -#define SIZEOF_AR_INDEX_NUMBERS 4 - unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS]; - unsigned char * index_buffer; - - /* Check the size of the archive index. */ - if (size < SIZEOF_AR_INDEX_NUMBERS) - { - error (_("%s: the archive index is empty\n"), file_name); - return 1; - } - - /* Read the numer of entries in the archive index. */ - got = fread (integer_buffer, 1, sizeof integer_buffer, file); - if (got != sizeof (integer_buffer)) - { - error (_("%s: failed to read archive index\n"), file_name); - return 1; - } - arch->index_num = byte_get_big_endian (integer_buffer, - sizeof integer_buffer); - size -= SIZEOF_AR_INDEX_NUMBERS; - - /* Read in the archive index. */ - if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS) - { - error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"), - file_name, arch->index_num); - return 1; - } - index_buffer = (unsigned char *) - malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS); - if (index_buffer == NULL) - { - error (_("Out of memory whilst trying to read archive symbol index\n")); - return 1; - } - got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, - arch->index_num, file); - if (got != arch->index_num) - { - free (index_buffer); - error (_("%s: failed to read archive index\n"), file_name); - return 1; - } - size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS; - - /* Convert the index numbers into the host's numeric format. */ - arch->index_array = (long unsigned int *) - malloc (arch->index_num * sizeof (* arch->index_array)); - if (arch->index_array == NULL) - { - free (index_buffer); - error (_("Out of memory whilst trying to convert the archive symbol index\n")); - return 1; - } - - for (i = 0; i < arch->index_num; i++) - arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)), - SIZEOF_AR_INDEX_NUMBERS); - free (index_buffer); - - /* The remaining space in the header is taken up by the symbol - table. */ - if (size < 1) - { - error (_("%s: the archive has an index but no symbols\n"), - file_name); - return 1; - } - arch->sym_table = (char *) malloc (size); - arch->sym_size = size; - if (arch->sym_table == NULL) - { - error (_("Out of memory whilst trying to read archive index symbol table\n")); - return 1; - } - got = fread (arch->sym_table, 1, size, file); - if (got != size) - { - error (_("%s: failed to read archive index symbol table\n"), - file_name); - return 1; - } - } - else - { - if (fseek (file, size, SEEK_CUR) != 0) - { - error (_("%s: failed to skip archive symbol table\n"), - file_name); - return 1; - } - } - - /* Read the next archive header. */ - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file); - if (got != sizeof arch->arhdr) - { - if (got == 0) - return 0; - error (_("%s: failed to read archive header following archive index\n"), - file_name); - return 1; - } - } - else if (read_symbols) - printf (_("%s has no archive index\n"), file_name); - - if (const_strneq (arch->arhdr.ar_name, "// ")) - { - /* This is the archive string table holding long member names. */ - arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10); - arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size; - - arch->longnames = (char *) malloc (arch->longnames_size); - if (arch->longnames == NULL) - { - error (_("Out of memory reading long symbol names in archive\n")); - return 1; - } - - if (fread (arch->longnames, arch->longnames_size, 1, file) != 1) - { - free (arch->longnames); - arch->longnames = NULL; - error (_("%s: failed to read long symbol name string table\n"), - file_name); - return 1; - } - - if ((arch->longnames_size & 1) != 0) - getc (file); - } - - return 0; -} - -/* Open and setup a nested archive, if not already open. */ - -int -setup_nested_archive (struct archive_info *nested_arch, - const char *member_file_name) -{ - FILE * member_file; - - /* Have we already setup this archive? */ - if (nested_arch->file_name != NULL - && streq (nested_arch->file_name, member_file_name)) - return 0; - - /* Close previous file and discard cached information. */ - if (nested_arch->file != NULL) - fclose (nested_arch->file); - release_archive (nested_arch); - - member_file = fopen (member_file_name, "rb"); - if (member_file == NULL) - return 1; - return setup_archive (nested_arch, member_file_name, member_file, - FALSE, FALSE); -} - -/* Release the memory used for the archive information. */ - -void -release_archive (struct archive_info * arch) -{ - if (arch->file_name != NULL) - free (arch->file_name); - if (arch->index_array != NULL) - free (arch->index_array); - if (arch->sym_table != NULL) - free (arch->sym_table); - if (arch->longnames != NULL) - free (arch->longnames); -} - -/* Get the name of an archive member from the current archive header. - For simple names, this will modify the ar_name field of the current - archive header. For long names, it will return a pointer to the - longnames table. For nested archives, it will open the nested archive - and get the name recursively. NESTED_ARCH is a single-entry cache so - we don't keep rereading the same information from a nested archive. */ - -char * -get_archive_member_name (struct archive_info *arch, - struct archive_info *nested_arch) -{ - unsigned long j, k; - - if (arch->arhdr.ar_name[0] == '/') - { - /* We have a long name. */ - char *endp; - char *member_file_name; - char *member_name; - - arch->nested_member_origin = 0; - k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10); - if (arch->is_thin_archive && endp != NULL && * endp == ':') - arch->nested_member_origin = strtoul (endp + 1, NULL, 10); - - while ((j < arch->longnames_size) - && (arch->longnames[j] != '\n') - && (arch->longnames[j] != '\0')) - j++; - if (arch->longnames[j-1] == '/') - j--; - arch->longnames[j] = '\0'; - - if (!arch->is_thin_archive || arch->nested_member_origin == 0) - return arch->longnames + k; - - /* This is a proxy for a member of a nested archive. - Find the name of the member in that archive. */ - member_file_name = adjust_relative_path (arch->file_name, - arch->longnames + k, j - k); - if (member_file_name != NULL - && setup_nested_archive (nested_arch, member_file_name) == 0) - { - member_name = get_archive_member_name_at (nested_arch, - arch->nested_member_origin, - NULL); - if (member_name != NULL) - { - free (member_file_name); - return member_name; - } - } - free (member_file_name); - - /* Last resort: just return the name of the nested archive. */ - return arch->longnames + k; - } - - /* We have a normal (short) name. */ - for (j = 0; j < sizeof (arch->arhdr.ar_name); j++) - if (arch->arhdr.ar_name[j] == '/') - { - arch->arhdr.ar_name[j] = '\0'; - return arch->arhdr.ar_name; - } - - /* The full ar_name field is used. Don't rely on ar_date starting - with a zero byte. */ - { - char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1); - memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name)); - name[sizeof (arch->arhdr.ar_name)] = '\0'; - return name; - } -} - -/* Get the name of an archive member at a given OFFSET within an archive - ARCH. */ - -char * -get_archive_member_name_at (struct archive_info *arch, - unsigned long offset, - struct archive_info *nested_arch) -{ - size_t got; - - if (fseek (arch->file, offset, SEEK_SET) != 0) - { - error (_("%s: failed to seek to next file name\n"), arch->file_name); - return NULL; - } - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file); - if (got != sizeof arch->arhdr) - { - error (_("%s: failed to read archive header\n"), arch->file_name); - return NULL; - } - if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0) - { - error (_("%s: did not find a valid archive header\n"), - arch->file_name); - return NULL; - } - - return get_archive_member_name (arch, nested_arch); -} - -/* Construct a string showing the name of the archive member, qualified - with the name of the containing archive file. For thin archives, we - use square brackets to denote the indirection. For nested archives, - we show the qualified name of the external member inside the square - brackets (e.g., "thin.a[normal.a(foo.o)]"). */ - -char * -make_qualified_name (struct archive_info * arch, - struct archive_info * nested_arch, - const char *member_name) -{ - size_t len; - char * name; - - len = strlen (arch->file_name) + strlen (member_name) + 3; - if (arch->is_thin_archive && arch->nested_member_origin != 0) - len += strlen (nested_arch->file_name) + 2; - - name = (char *) malloc (len); - if (name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - - if (arch->is_thin_archive && arch->nested_member_origin != 0) - snprintf (name, len, "%s[%s(%s)]", arch->file_name, - nested_arch->file_name, member_name); - else if (arch->is_thin_archive) - snprintf (name, len, "%s[%s]", arch->file_name, member_name); - else - snprintf (name, len, "%s(%s)", arch->file_name, member_name); - - return name; -} diff --git a/contrib/binutils-2.22/binutils/elfcomm.h b/contrib/binutils-2.22/binutils/elfcomm.h deleted file mode 100644 index 3f9727e5cb..0000000000 --- a/contrib/binutils-2.22/binutils/elfcomm.h +++ /dev/null @@ -1,110 +0,0 @@ -/* elfcomm.h -- include file of common code for ELF format file. - Copyright 2010 - Free Software Foundation, Inc. - - Originally developed by Eric Youngdale - Modifications by Nick Clifton - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef _ELFCOMM_H -#define _ELFCOMM_H - -#include "aout/ar.h" - -void error (const char *, ...) ATTRIBUTE_PRINTF_1; -void warn (const char *, ...) ATTRIBUTE_PRINTF_1; - -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) -/* We can't use any bfd types here since readelf may define BFD64 and - objdump may not. */ -#define HOST_WIDEST_INT long long -#else -#define HOST_WIDEST_INT long -#endif -typedef unsigned HOST_WIDEST_INT elf_vma; - -extern void (*byte_put) (unsigned char *, elf_vma, int); -extern void byte_put_little_endian (unsigned char *, elf_vma, int); -extern void byte_put_big_endian (unsigned char *, elf_vma, int); - -extern elf_vma (*byte_get) (unsigned char *, int); -extern elf_vma byte_get_signed (unsigned char *, int); -extern elf_vma byte_get_little_endian (unsigned char *, int); -extern elf_vma byte_get_big_endian (unsigned char *, int); - -#define BYTE_PUT(field, val) byte_put (field, val, sizeof (field)) -#define BYTE_GET(field) byte_get (field, sizeof (field)) -#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field)) - -/* This is just a bit of syntatic sugar. */ -#define streq(a,b) (strcmp ((a), (b)) == 0) -#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) -#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0) - -/* Structure to hold information about an archive file. */ - -struct archive_info -{ - char * file_name; /* Archive file name. */ - FILE * file; /* Open file descriptor. */ - unsigned long index_num; /* Number of symbols in table. */ - unsigned long * index_array; /* The array of member offsets. */ - char * sym_table; /* The symbol table. */ - unsigned long sym_size; /* Size of the symbol table. */ - char * longnames; /* The long file names table. */ - unsigned long longnames_size; /* Size of the long file names table. */ - unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */ - unsigned long next_arhdr_offset; /* Offset of the next archive header. */ - bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */ - struct ar_hdr arhdr; /* Current archive header. */ -}; - -/* Return the path name for a proxy entry in a thin archive. */ -extern char *adjust_relative_path (const char *, const char *, int); - -/* Read the symbol table and long-name table from an archive. */ -extern int setup_archive (struct archive_info *, const char *, FILE *, - bfd_boolean, bfd_boolean); - -/* Open and setup a nested archive, if not already open. */ -extern int setup_nested_archive (struct archive_info *, const char *); - -/* Release the memory used for the archive information. */ -extern void release_archive (struct archive_info *); - -/* Get the name of an archive member from the current archive header. */ - -extern char *get_archive_member_name (struct archive_info *, - struct archive_info *); - -/* Get the name of an archive member at a given offset within an - archive. */ - -extern char *get_archive_member_name_at (struct archive_info *, - unsigned long, - struct archive_info *); - -/* Construct a string showing the name of the archive member, qualified - with the name of the containing archive file. */ - -extern char *make_qualified_name (struct archive_info *, - struct archive_info *, - const char *); - -#endif /* _ELFCOMM_H */ diff --git a/contrib/binutils-2.22/binutils/elfedit.c b/contrib/binutils-2.22/binutils/elfedit.c deleted file mode 100644 index f7bf9e99e7..0000000000 --- a/contrib/binutils-2.22/binutils/elfedit.c +++ /dev/null @@ -1,740 +0,0 @@ -/* elfedit.c -- Update the ELF header of an ELF format file - Copyright 2010 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "config.h" -#include "sysdep.h" -#include -#include - -#if __GNUC__ >= 2 -/* Define BFD64 here, even if our default architecture is 32 bit ELF - as this will allow us to read in and parse 64bit and 32bit ELF files. - Only do this if we believe that the compiler can support a 64 bit - data type. For now we only rely on GCC being able to do this. */ -#define BFD64 -#endif - -#include "bfd.h" -#include "elfcomm.h" -#include "bucomm.h" - -#include "elf/common.h" -#include "elf/external.h" -#include "elf/internal.h" - -#include "getopt.h" -#include "libiberty.h" -#include "safe-ctype.h" -#include "filenames.h" - -char * program_name = "elfedit"; -static long archive_file_offset; -static unsigned long archive_file_size; -static Elf_Internal_Ehdr elf_header; -static Elf32_External_Ehdr ehdr32; -static Elf64_External_Ehdr ehdr64; -static int input_elf_machine = -1; -static int output_elf_machine = -1; -static int input_elf_type = -1; -static int output_elf_type = -1; -static int input_elf_osabi = -1; -static int output_elf_osabi = -1; -static int input_elf_class = -1; - -static int -update_elf_header (const char *file_name, FILE *file) -{ - int class, machine, type, status, osabi; - - if (elf_header.e_ident[EI_MAG0] != ELFMAG0 - || elf_header.e_ident[EI_MAG1] != ELFMAG1 - || elf_header.e_ident[EI_MAG2] != ELFMAG2 - || elf_header.e_ident[EI_MAG3] != ELFMAG3) - { - error - (_("%s: Not an ELF file - wrong magic bytes at the start\n"), - file_name); - return 0; - } - - if (elf_header.e_ident[EI_VERSION] != EV_CURRENT) - { - error - (_("%s: Unsupported EI_VERSION: %d is not %d\n"), - file_name, elf_header.e_ident[EI_VERSION], - EV_CURRENT); - return 0; - } - - /* Return if e_machine is the same as output_elf_machine. */ - if (output_elf_machine == elf_header.e_machine) - return 1; - - class = elf_header.e_ident[EI_CLASS]; - - /* Skip if class doesn't match. */ - if (input_elf_class != -1 && class != input_elf_class) - { - error - (_("%s: Unmatched EI_CLASS: %d is not %d\n"), - file_name, class, input_elf_class); - return 0; - } - - machine = elf_header.e_machine; - - /* Skip if e_machine doesn't match. */ - if (input_elf_machine != -1 && machine != input_elf_machine) - { - error - (_("%s: Unmatched e_machine: %d is not %d\n"), - file_name, machine, input_elf_machine); - return 0; - } - - type = elf_header.e_type; - - /* Skip if e_type doesn't match. */ - if (input_elf_type != -1 && type != input_elf_type) - { - error - (_("%s: Unmatched e_type: %d is not %d\n"), - file_name, type, input_elf_type); - return 0; - } - - osabi = elf_header.e_ident[EI_OSABI]; - - /* Skip if OSABI doesn't match. */ - if (input_elf_osabi != -1 && osabi != input_elf_osabi) - { - error - (_("%s: Unmatched EI_OSABI: %d is not %d\n"), - file_name, osabi, input_elf_osabi); - return 0; - } - - /* Update e_machine, e_type and EI_OSABI. */ - switch (class) - { - default: - /* We should never get here. */ - abort (); - break; - case ELFCLASS32: - if (output_elf_machine != -1) - BYTE_PUT (ehdr32.e_machine, output_elf_machine); - if (output_elf_type != -1) - BYTE_PUT (ehdr32.e_type, output_elf_type); - if (output_elf_osabi != -1) - ehdr32.e_ident[EI_OSABI] = output_elf_osabi; - status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1; - break; - case ELFCLASS64: - if (output_elf_machine != -1) - BYTE_PUT (ehdr64.e_machine, output_elf_machine); - if (output_elf_type != -1) - BYTE_PUT (ehdr64.e_type, output_elf_type); - if (output_elf_osabi != -1) - ehdr64.e_ident[EI_OSABI] = output_elf_osabi; - status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1; - break; - } - - if (status != 1) - error (_("%s: Failed to update ELF header: %s\n"), - file_name, strerror (errno)); - - return status; -} - -static int -get_file_header (FILE * file) -{ - /* Read in the identity array. */ - if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1) - return 0; - - /* Determine how to read the rest of the header. */ - switch (elf_header.e_ident[EI_DATA]) - { - default: /* fall through */ - case ELFDATANONE: /* fall through */ - case ELFDATA2LSB: - byte_get = byte_get_little_endian; - byte_put = byte_put_little_endian; - break; - case ELFDATA2MSB: - byte_get = byte_get_big_endian; - byte_put = byte_put_big_endian; - break; - } - - /* Read in the rest of the header. For now we only support 32 bit - and 64 bit ELF files. */ - switch (elf_header.e_ident[EI_CLASS]) - { - default: - error (_("Unsupported EI_CLASS: %d\n"), - elf_header.e_ident[EI_CLASS]); - return 0; - - case ELFCLASS32: - if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, - 1, file) != 1) - return 0; - - elf_header.e_type = BYTE_GET (ehdr32.e_type); - elf_header.e_machine = BYTE_GET (ehdr32.e_machine); - elf_header.e_version = BYTE_GET (ehdr32.e_version); - elf_header.e_entry = BYTE_GET (ehdr32.e_entry); - elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff); - elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff); - elf_header.e_flags = BYTE_GET (ehdr32.e_flags); - elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize); - elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize); - elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum); - elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize); - elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum); - elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx); - - memcpy (&ehdr32, &elf_header, EI_NIDENT); - break; - - case ELFCLASS64: - /* If we have been compiled with sizeof (bfd_vma) == 4, then - we will not be able to cope with the 64bit data found in - 64 ELF files. Detect this now and abort before we start - overwriting things. */ - if (sizeof (bfd_vma) < 8) - { - error (_("This executable has been built without support for a\n\ -64 bit data type and so it cannot process 64 bit ELF files.\n")); - return 0; - } - - if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, - 1, file) != 1) - return 0; - - elf_header.e_type = BYTE_GET (ehdr64.e_type); - elf_header.e_machine = BYTE_GET (ehdr64.e_machine); - elf_header.e_version = BYTE_GET (ehdr64.e_version); - elf_header.e_entry = BYTE_GET (ehdr64.e_entry); - elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff); - elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff); - elf_header.e_flags = BYTE_GET (ehdr64.e_flags); - elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize); - elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize); - elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum); - elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize); - elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum); - elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx); - - memcpy (&ehdr64, &elf_header, EI_NIDENT); - break; - } - return 1; -} - -/* Process one ELF object file according to the command line options. - This file may actually be stored in an archive. The file is - positioned at the start of the ELF object. */ - -static int -process_object (const char *file_name, FILE *file) -{ - /* Rememeber where we are. */ - long offset = ftell (file); - - if (! get_file_header (file)) - { - error (_("%s: Failed to read ELF header\n"), file_name); - return 1; - } - - /* Go to the position of the ELF header. */ - if (fseek (file, offset, SEEK_SET) != 0) - { - error (_("%s: Failed to seek to ELF header\n"), file_name); - } - - if (! update_elf_header (file_name, file)) - return 1; - - return 0; -} - -/* Process an ELF archive. - On entry the file is positioned just after the ARMAG string. */ - -static int -process_archive (const char * file_name, FILE * file, - bfd_boolean is_thin_archive) -{ - struct archive_info arch; - struct archive_info nested_arch; - size_t got; - int ret; - - /* The ARCH structure is used to hold information about this archive. */ - arch.file_name = NULL; - arch.file = NULL; - arch.index_array = NULL; - arch.sym_table = NULL; - arch.longnames = NULL; - - /* The NESTED_ARCH structure is used as a single-item cache of information - about a nested archive (when members of a thin archive reside within - another regular archive file). */ - nested_arch.file_name = NULL; - nested_arch.file = NULL; - nested_arch.index_array = NULL; - nested_arch.sym_table = NULL; - nested_arch.longnames = NULL; - - if (setup_archive (&arch, file_name, file, is_thin_archive, FALSE) != 0) - { - ret = 1; - goto out; - } - - ret = 0; - - while (1) - { - char * name; - size_t namelen; - char * qualified_name; - - /* Read the next archive header. */ - if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0) - { - error (_("%s: failed to seek to next archive header\n"), - file_name); - return 1; - } - got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file); - if (got != sizeof arch.arhdr) - { - if (got == 0) - break; - error (_("%s: failed to read archive header\n"), - file_name); - ret = 1; - break; - } - if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0) - { - error (_("%s: did not find a valid archive header\n"), - arch.file_name); - ret = 1; - break; - } - - arch.next_arhdr_offset += sizeof arch.arhdr; - - archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10); - if (archive_file_size & 01) - ++archive_file_size; - - name = get_archive_member_name (&arch, &nested_arch); - if (name == NULL) - { - error (_("%s: bad archive file name\n"), file_name); - ret = 1; - break; - } - namelen = strlen (name); - - qualified_name = make_qualified_name (&arch, &nested_arch, name); - if (qualified_name == NULL) - { - error (_("%s: bad archive file name\n"), file_name); - ret = 1; - break; - } - - if (is_thin_archive && arch.nested_member_origin == 0) - { - /* This is a proxy for an external member of a thin archive. */ - FILE *member_file; - char *member_file_name = adjust_relative_path (file_name, - name, namelen); - if (member_file_name == NULL) - { - ret = 1; - break; - } - - member_file = fopen (member_file_name, "r+b"); - if (member_file == NULL) - { - error (_("Input file '%s' is not readable\n"), - member_file_name); - free (member_file_name); - ret = 1; - break; - } - - archive_file_offset = arch.nested_member_origin; - - ret |= process_object (qualified_name, member_file); - - fclose (member_file); - free (member_file_name); - } - else if (is_thin_archive) - { - /* This is a proxy for a member of a nested archive. */ - archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr; - - /* The nested archive file will have been opened and setup by - get_archive_member_name. */ - if (fseek (nested_arch.file, archive_file_offset, - SEEK_SET) != 0) - { - error (_("%s: failed to seek to archive member\n"), - nested_arch.file_name); - ret = 1; - break; - } - - ret |= process_object (qualified_name, nested_arch.file); - } - else - { - archive_file_offset = arch.next_arhdr_offset; - arch.next_arhdr_offset += archive_file_size; - - ret |= process_object (qualified_name, file); - } - - free (qualified_name); - } - - out: - if (nested_arch.file != NULL) - fclose (nested_arch.file); - release_archive (&nested_arch); - release_archive (&arch); - - return ret; -} - -static int -check_file (const char *file_name, struct stat *statbuf_p) -{ - struct stat statbuf; - - if (statbuf_p == NULL) - statbuf_p = &statbuf; - - if (stat (file_name, statbuf_p) < 0) - { - if (errno == ENOENT) - error (_("'%s': No such file\n"), file_name); - else - error (_("Could not locate '%s'. System error message: %s\n"), - file_name, strerror (errno)); - return 1; - } - - if (! S_ISREG (statbuf_p->st_mode)) - { - error (_("'%s' is not an ordinary file\n"), file_name); - return 1; - } - - return 0; -} - -static int -process_file (const char *file_name) -{ - FILE * file; - char armag[SARMAG]; - int ret; - - if (check_file (file_name, NULL)) - return 1; - - file = fopen (file_name, "r+b"); - if (file == NULL) - { - error (_("Input file '%s' is not readable\n"), file_name); - return 1; - } - - if (fread (armag, SARMAG, 1, file) != 1) - { - error (_("%s: Failed to read file's magic number\n"), - file_name); - fclose (file); - return 1; - } - - if (memcmp (armag, ARMAG, SARMAG) == 0) - ret = process_archive (file_name, file, FALSE); - else if (memcmp (armag, ARMAGT, SARMAG) == 0) - ret = process_archive (file_name, file, TRUE); - else - { - rewind (file); - archive_file_size = archive_file_offset = 0; - ret = process_object (file_name, file); - } - - fclose (file); - - return ret; -} - -static const struct -{ - int osabi; - const char *name; -} -osabis[] = -{ - { ELFOSABI_NONE, "none" }, - { ELFOSABI_HPUX, "HPUX" }, - { ELFOSABI_NETBSD, "NetBSD" }, - { ELFOSABI_GNU, "GNU" }, - { ELFOSABI_GNU, "Linux" }, - { ELFOSABI_SOLARIS, "Solaris" }, - { ELFOSABI_AIX, "AIX" }, - { ELFOSABI_IRIX, "Irix" }, - { ELFOSABI_FREEBSD, "FreeBSD" }, - { ELFOSABI_TRU64, "TRU64" }, - { ELFOSABI_MODESTO, "Modesto" }, - { ELFOSABI_OPENBSD, "OpenBSD" }, - { ELFOSABI_OPENVMS, "OpenVMS" }, - { ELFOSABI_NSK, "NSK" }, - { ELFOSABI_AROS, "AROS" }, - { ELFOSABI_FENIXOS, "FenixOS" } -}; - -/* Return ELFOSABI_XXX for an OSABI string, OSABI. */ - -static int -elf_osabi (const char *osabi) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE (osabis); i++) - if (strcasecmp (osabi, osabis[i].name) == 0) - return osabis[i].osabi; - - error (_("Unknown OSABI: %s\n"), osabi); - - return -1; -} - -/* Return EM_XXX for a machine string, MACH. */ - -static int -elf_machine (const char *mach) -{ - if (strcasecmp (mach, "l1om") == 0) - return EM_L1OM; - if (strcasecmp (mach, "k1om") == 0) - return EM_K1OM; - if (strcasecmp (mach, "x86_64") == 0) - return EM_X86_64; - if (strcasecmp (mach, "x86-64") == 0) - return EM_X86_64; - if (strcasecmp (mach, "none") == 0) - return EM_NONE; - - error (_("Unknown machine type: %s\n"), mach); - - return -1; -} - -/* Return ELF class for a machine type, MACH. */ - -static int -elf_class (int mach) -{ - switch (mach) - { - case EM_L1OM: - case EM_K1OM: - case EM_X86_64: - return ELFCLASS64; - case EM_NONE: - return ELFCLASSNONE; - default: - error (_("Unknown machine type: %d\n"), mach); - return -1; - } -} - -/* Return ET_XXX for a type string, TYPE. */ - -static int -elf_type (const char *type) -{ - if (strcasecmp (type, "rel") == 0) - return ET_REL; - if (strcasecmp (type, "exec") == 0) - return ET_EXEC; - if (strcasecmp (type, "dyn") == 0) - return ET_DYN; - if (strcasecmp (type, "none") == 0) - return ET_NONE; - - error (_("Unknown type: %s\n"), type); - - return -1; -} - -enum command_line_switch - { - OPTION_INPUT_MACH = 150, - OPTION_OUTPUT_MACH, - OPTION_INPUT_TYPE, - OPTION_OUTPUT_TYPE, - OPTION_INPUT_OSABI, - OPTION_OUTPUT_OSABI - }; - -static struct option options[] = -{ - {"input-mach", required_argument, 0, OPTION_INPUT_MACH}, - {"output-mach", required_argument, 0, OPTION_OUTPUT_MACH}, - {"input-type", required_argument, 0, OPTION_INPUT_TYPE}, - {"output-type", required_argument, 0, OPTION_OUTPUT_TYPE}, - {"input-osabi", required_argument, 0, OPTION_INPUT_OSABI}, - {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI}, - {"version", no_argument, 0, 'v'}, - {"help", no_argument, 0, 'h'}, - {0, no_argument, 0, 0} -}; - -static void -usage (FILE *stream, int exit_status) -{ - fprintf (stream, _("Usage: %s elffile(s)\n"), - program_name); - fprintf (stream, _(" Update the ELF header of ELF files\n")); - fprintf (stream, _(" The options are:\n")); - fprintf (stream, _("\ - --input-mach Set input machine type to \n\ - --output-mach Set output machine type to \n\ - --input-type Set input file type to \n\ - --output-type Set output file type to \n\ - --input-osabi Set input OSABI to \n\ - --output-osabi Set output OSABI to \n\ - -h --help Display this information\n\ - -v --version Display the version number of %s\n\ -"), - program_name); - if (REPORT_BUGS_TO[0] && exit_status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (exit_status); -} - -int -main (int argc, char ** argv) -{ - int c, status; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - expandargv (&argc, &argv); - - while ((c = getopt_long (argc, argv, "hv", - options, (int *) 0)) != EOF) - { - switch (c) - { - case OPTION_INPUT_MACH: - input_elf_machine = elf_machine (optarg); - if (input_elf_machine < 0) - return 1; - input_elf_class = elf_class (input_elf_machine); - if (input_elf_class < 0) - return 1; - break; - - case OPTION_OUTPUT_MACH: - output_elf_machine = elf_machine (optarg); - if (output_elf_machine < 0) - return 1; - break; - - case OPTION_INPUT_TYPE: - input_elf_type = elf_type (optarg); - if (input_elf_type < 0) - return 1; - break; - - case OPTION_OUTPUT_TYPE: - output_elf_type = elf_type (optarg); - if (output_elf_type < 0) - return 1; - break; - - case OPTION_INPUT_OSABI: - input_elf_osabi = elf_osabi (optarg); - if (input_elf_osabi < 0) - return 1; - break; - - case OPTION_OUTPUT_OSABI: - output_elf_osabi = elf_osabi (optarg); - if (output_elf_osabi < 0) - return 1; - break; - - case 'h': - usage (stdout, 0); - - case 'v': - print_version (program_name); - break; - - default: - usage (stderr, 1); - } - } - - if (optind == argc - || (output_elf_machine == -1 - && output_elf_type == -1 - && output_elf_osabi == -1)) - usage (stderr, 1); - - status = 0; - while (optind < argc) - status |= process_file (argv[optind++]); - - return status; -} diff --git a/contrib/binutils-2.22/binutils/emul_vanilla.c b/contrib/binutils-2.22/binutils/emul_vanilla.c deleted file mode 100644 index d15287d2fa..0000000000 --- a/contrib/binutils-2.22/binutils/emul_vanilla.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Binutils emulation layer. - Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc. - Written by Tom Rix, Red Hat Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "binemul.h" - -struct bin_emulation_xfer_struct bin_vanilla_emulation = -{ - ar_emul_default_usage, - ar_emul_default_append, - ar_emul_default_replace, - ar_emul_default_parse_arg, -}; diff --git a/contrib/binutils-2.22/binutils/filemode.c b/contrib/binutils-2.22/binutils/filemode.c deleted file mode 100644 index 8b29defc52..0000000000 --- a/contrib/binutils-2.22/binutils/filemode.c +++ /dev/null @@ -1,249 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright 1985, 1990, 1991, 1994, 1995, 1997, 1999, 2002, 2003, 2005, - 2007 Free Software Foundation, Inc. - - 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, 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. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bucomm.h" - -static char ftypelet (unsigned long); -static void setst (unsigned long, char *); - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -/* Get definitions for the file permission bits. */ - -#ifndef S_IRWXU -#define S_IRWXU 0700 -#endif -#ifndef S_IRUSR -#define S_IRUSR 0400 -#endif -#ifndef S_IWUSR -#define S_IWUSR 0200 -#endif -#ifndef S_IXUSR -#define S_IXUSR 0100 -#endif - -#ifndef S_IRWXG -#define S_IRWXG 0070 -#endif -#ifndef S_IRGRP -#define S_IRGRP 0040 -#endif -#ifndef S_IWGRP -#define S_IWGRP 0020 -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 -#endif - -#ifndef S_IRWXO -#define S_IRWXO 0007 -#endif -#ifndef S_IROTH -#define S_IROTH 0004 -#endif -#ifndef S_IWOTH -#define S_IWOTH 0002 -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 -#endif - -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ - -void -mode_string (unsigned long mode, char *str) -{ - str[0] = ftypelet ((unsigned long) mode); - str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-'; - str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-'; - str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-'; - str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-'; - str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-'; - str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-'; - str[7] = (mode & S_IROTH) != 0 ? 'r' : '-'; - str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-'; - str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-'; - setst ((unsigned long) mode, str); -} - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexer files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for any other file type. */ - -#ifndef S_ISDIR -#ifdef S_IFDIR -#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR) -#else /* ! defined (S_IFDIR) */ -#define S_ISDIR(i) (((i) & 0170000) == 040000) -#endif /* ! defined (S_IFDIR) */ -#endif /* ! defined (S_ISDIR) */ - -#ifndef S_ISBLK -#ifdef S_IFBLK -#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK) -#else /* ! defined (S_IFBLK) */ -#define S_ISBLK(i) 0 -#endif /* ! defined (S_IFBLK) */ -#endif /* ! defined (S_ISBLK) */ - -#ifndef S_ISCHR -#ifdef S_IFCHR -#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR) -#else /* ! defined (S_IFCHR) */ -#define S_ISCHR(i) 0 -#endif /* ! defined (S_IFCHR) */ -#endif /* ! defined (S_ISCHR) */ - -#ifndef S_ISFIFO -#ifdef S_IFIFO -#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO) -#else /* ! defined (S_IFIFO) */ -#define S_ISFIFO(i) 0 -#endif /* ! defined (S_IFIFO) */ -#endif /* ! defined (S_ISFIFO) */ - -#ifndef S_ISSOCK -#ifdef S_IFSOCK -#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK) -#else /* ! defined (S_IFSOCK) */ -#define S_ISSOCK(i) 0 -#endif /* ! defined (S_IFSOCK) */ -#endif /* ! defined (S_ISSOCK) */ - -#ifndef S_ISLNK -#ifdef S_IFLNK -#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK) -#else /* ! defined (S_IFLNK) */ -#define S_ISLNK(i) 0 -#endif /* ! defined (S_IFLNK) */ -#endif /* ! defined (S_ISLNK) */ - -static char -ftypelet (unsigned long bits) -{ - if (S_ISDIR (bits)) - return 'd'; - if (S_ISLNK (bits)) - return 'l'; - if (S_ISBLK (bits)) - return 'b'; - if (S_ISCHR (bits)) - return 'c'; - if (S_ISSOCK (bits)) - return 's'; - if (S_ISFIFO (bits)) - return 'p'; - -#ifdef S_IFMT -#ifdef S_IFMPC - if ((bits & S_IFMT) == S_IFMPC - || (bits & S_IFMT) == S_IFMPB) - return 'm'; -#endif -#ifdef S_IFNWK - if ((bits & S_IFMT) == S_IFNWK) - return 'n'; -#endif -#endif - - return '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (unsigned long bits ATTRIBUTE_UNUSED, char *chars ATTRIBUTE_UNUSED) -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} diff --git a/contrib/binutils-2.22/binutils/ieee.c b/contrib/binutils-2.22/binutils/ieee.c deleted file mode 100644 index 044da313dd..0000000000 --- a/contrib/binutils-2.22/binutils/ieee.c +++ /dev/null @@ -1,7411 +0,0 @@ -/* ieee.c -- Read and write IEEE-695 debugging information. - Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, - 2008, 2009, 2010, 2011 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This file reads and writes IEEE-695 debugging information. */ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "ieee.h" -#include "libiberty.h" -#include "debug.h" -#include "budbg.h" -#include "filenames.h" - -/* This structure holds an entry on the block stack. */ - -struct ieee_block -{ - /* The kind of block. */ - int kind; - /* The source file name, for a BB5 block. */ - const char *filename; - /* The index of the function type, for a BB4 or BB6 block. */ - unsigned int fnindx; - /* TRUE if this function is being skipped. */ - bfd_boolean skip; -}; - -/* This structure is the block stack. */ - -#define BLOCKSTACK_SIZE (16) - -struct ieee_blockstack -{ - /* The stack pointer. */ - struct ieee_block *bsp; - /* The stack. */ - struct ieee_block stack[BLOCKSTACK_SIZE]; -}; - -/* This structure holds information for a variable. */ - -enum ieee_var_kind - { - IEEE_UNKNOWN, - IEEE_EXTERNAL, - IEEE_GLOBAL, - IEEE_STATIC, - IEEE_LOCAL, - IEEE_FUNCTION - }; - -struct ieee_var -{ - /* Start of name. */ - const char *name; - /* Length of name. */ - unsigned long namlen; - /* Type. */ - debug_type type; - /* Slot if we make an indirect type. */ - debug_type *pslot; - /* Kind of variable or function. */ - enum ieee_var_kind kind; -}; - -/* This structure holds all the variables. */ - -struct ieee_vars -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Variables. */ - struct ieee_var *vars; -}; - -/* This structure holds information for a type. We need this because - we don't want to represent bitfields as real types. */ - -struct ieee_type -{ - /* Type. */ - debug_type type; - /* Slot if this is type is referenced before it is defined. */ - debug_type *pslot; - /* Slots for arguments if we make indirect types for them. */ - debug_type *arg_slots; - /* If this is a bitfield, this is the size in bits. If this is not - a bitfield, this is zero. */ - unsigned long bitsize; -}; - -/* This structure holds all the type information. */ - -struct ieee_types -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Types. */ - struct ieee_type *types; - /* Builtin types. */ -#define BUILTIN_TYPE_COUNT (60) - debug_type builtins[BUILTIN_TYPE_COUNT]; -}; - -/* This structure holds a linked last of structs with their tag names, - so that we can convert them to C++ classes if necessary. */ - -struct ieee_tag -{ - /* Next tag. */ - struct ieee_tag *next; - /* This tag name. */ - const char *name; - /* The type of the tag. */ - debug_type type; - /* The tagged type is an indirect type pointing at this slot. */ - debug_type slot; - /* This is an array of slots used when a field type is converted - into a indirect type, in case it needs to be later converted into - a reference type. */ - debug_type *fslots; -}; - -/* This structure holds the information we pass around to the parsing - functions. */ - -struct ieee_info -{ - /* The debugging handle. */ - void *dhandle; - /* The BFD. */ - bfd *abfd; - /* The start of the bytes to be parsed. */ - const bfd_byte *bytes; - /* The end of the bytes to be parsed. */ - const bfd_byte *pend; - /* The block stack. */ - struct ieee_blockstack blockstack; - /* Whether we have seen a BB1 or BB2. */ - bfd_boolean saw_filename; - /* The variables. */ - struct ieee_vars vars; - /* The global variables, after a global typedef block. */ - struct ieee_vars *global_vars; - /* The types. */ - struct ieee_types types; - /* The global types, after a global typedef block. */ - struct ieee_types *global_types; - /* The list of tagged structs. */ - struct ieee_tag *tags; -}; - -/* Basic builtin types, not including the pointers. */ - -enum builtin_types -{ - builtin_unknown = 0, - builtin_void = 1, - builtin_signed_char = 2, - builtin_unsigned_char = 3, - builtin_signed_short_int = 4, - builtin_unsigned_short_int = 5, - builtin_signed_long = 6, - builtin_unsigned_long = 7, - builtin_signed_long_long = 8, - builtin_unsigned_long_long = 9, - builtin_float = 10, - builtin_double = 11, - builtin_long_double = 12, - builtin_long_long_double = 13, - builtin_quoted_string = 14, - builtin_instruction_address = 15, - builtin_int = 16, - builtin_unsigned = 17, - builtin_unsigned_int = 18, - builtin_char = 19, - builtin_long = 20, - builtin_short = 21, - builtin_unsigned_short = 22, - builtin_short_int = 23, - builtin_signed_short = 24, - builtin_bcd_float = 25 -}; - -/* These are the values found in the derivation flags of a 'b' - component record of a 'T' type extension record in a C++ pmisc - record. These are bitmasks. */ - -/* Set for a private base class, clear for a public base class. - Protected base classes are not supported. */ -#define BASEFLAGS_PRIVATE (0x1) -/* Set for a virtual base class. */ -#define BASEFLAGS_VIRTUAL (0x2) -/* Set for a friend class, clear for a base class. */ -#define BASEFLAGS_FRIEND (0x10) - -/* These are the values found in the specs flags of a 'd', 'm', or 'v' - component record of a 'T' type extension record in a C++ pmisc - record. The same flags are used for a 'M' record in a C++ pmisc - record. */ - -/* The lower two bits hold visibility information. */ -#define CXXFLAGS_VISIBILITY (0x3) -/* This value in the lower two bits indicates a public member. */ -#define CXXFLAGS_VISIBILITY_PUBLIC (0x0) -/* This value in the lower two bits indicates a private member. */ -#define CXXFLAGS_VISIBILITY_PRIVATE (0x1) -/* This value in the lower two bits indicates a protected member. */ -#define CXXFLAGS_VISIBILITY_PROTECTED (0x2) -/* Set for a static member. */ -#define CXXFLAGS_STATIC (0x4) -/* Set for a virtual override. */ -#define CXXFLAGS_OVERRIDE (0x8) -/* Set for a friend function. */ -#define CXXFLAGS_FRIEND (0x10) -/* Set for a const function. */ -#define CXXFLAGS_CONST (0x20) -/* Set for a volatile function. */ -#define CXXFLAGS_VOLATILE (0x40) -/* Set for an overloaded function. */ -#define CXXFLAGS_OVERLOADED (0x80) -/* Set for an operator function. */ -#define CXXFLAGS_OPERATOR (0x100) -/* Set for a constructor or destructor. */ -#define CXXFLAGS_CTORDTOR (0x400) -/* Set for a constructor. */ -#define CXXFLAGS_CTOR (0x200) -/* Set for an inline function. */ -#define CXXFLAGS_INLINE (0x800) - -/* Local functions. */ - -static void ieee_error (struct ieee_info *, const bfd_byte *, const char *); -static void ieee_eof (struct ieee_info *); -static char *savestring (const char *, unsigned long); -static bfd_boolean ieee_read_number - (struct ieee_info *, const bfd_byte **, bfd_vma *); -static bfd_boolean ieee_read_optional_number - (struct ieee_info *, const bfd_byte **, bfd_vma *, bfd_boolean *); -static bfd_boolean ieee_read_id - (struct ieee_info *, const bfd_byte **, const char **, unsigned long *); -static bfd_boolean ieee_read_optional_id - (struct ieee_info *, const bfd_byte **, const char **, unsigned long *, - bfd_boolean *); -static bfd_boolean ieee_read_expression - (struct ieee_info *, const bfd_byte **, bfd_vma *); -static debug_type ieee_builtin_type - (struct ieee_info *, const bfd_byte *, unsigned int); -static bfd_boolean ieee_alloc_type - (struct ieee_info *, unsigned int, bfd_boolean); -static bfd_boolean ieee_read_type_index - (struct ieee_info *, const bfd_byte **, debug_type *); -static int ieee_regno_to_genreg (bfd *, int); -static int ieee_genreg_to_regno (bfd *, int); -static bfd_boolean parse_ieee_bb (struct ieee_info *, const bfd_byte **); -static bfd_boolean parse_ieee_be (struct ieee_info *, const bfd_byte **); -static bfd_boolean parse_ieee_nn (struct ieee_info *, const bfd_byte **); -static bfd_boolean parse_ieee_ty (struct ieee_info *, const bfd_byte **); -static bfd_boolean parse_ieee_atn (struct ieee_info *, const bfd_byte **); -static bfd_boolean ieee_read_cxx_misc - (struct ieee_info *, const bfd_byte **, unsigned long); -static bfd_boolean ieee_read_cxx_class - (struct ieee_info *, const bfd_byte **, unsigned long); -static bfd_boolean ieee_read_cxx_defaults - (struct ieee_info *, const bfd_byte **, unsigned long); -static bfd_boolean ieee_read_reference - (struct ieee_info *, const bfd_byte **); -static bfd_boolean ieee_require_asn - (struct ieee_info *, const bfd_byte **, bfd_vma *); -static bfd_boolean ieee_require_atn65 - (struct ieee_info *, const bfd_byte **, const char **, unsigned long *); - -/* Report an error in the IEEE debugging information. */ - -static void -ieee_error (struct ieee_info *info, const bfd_byte *p, const char *s) -{ - if (p != NULL) - fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd), - (unsigned long) (p - info->bytes), s, *p); - else - fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s); -} - -/* Report an unexpected EOF in the IEEE debugging information. */ - -static void -ieee_eof (struct ieee_info *info) -{ - ieee_error (info, (const bfd_byte *) NULL, - _("unexpected end of debugging information")); -} - -/* Save a string in memory. */ - -static char * -savestring (const char *start, unsigned long len) -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number which must be present in an IEEE file. */ - -static bfd_boolean -ieee_read_number (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv) -{ - return ieee_read_optional_number (info, pp, pv, (bfd_boolean *) NULL); -} - -/* Read a number in an IEEE file. If ppresent is not NULL, the number - need not be there. */ - -static bfd_boolean -ieee_read_optional_number (struct ieee_info *info, const bfd_byte **pp, - bfd_vma *pv, bfd_boolean *ppresent) -{ - ieee_record_enum_type b; - - if (*pp >= info->pend) - { - if (ppresent != NULL) - { - *ppresent = FALSE; - return TRUE; - } - ieee_eof (info); - return FALSE; - } - - b = (ieee_record_enum_type) **pp; - ++*pp; - - if (b <= ieee_number_end_enum) - { - *pv = (bfd_vma) b; - if (ppresent != NULL) - *ppresent = TRUE; - return TRUE; - } - - if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum) - { - unsigned int i; - - i = (int) b - (int) ieee_number_repeat_start_enum; - if (*pp + i - 1 >= info->pend) - { - ieee_eof (info); - return FALSE; - } - - *pv = 0; - for (; i > 0; i--) - { - *pv <<= 8; - *pv += **pp; - ++*pp; - } - - if (ppresent != NULL) - *ppresent = TRUE; - - return TRUE; - } - - if (ppresent != NULL) - { - --*pp; - *ppresent = FALSE; - return TRUE; - } - - ieee_error (info, *pp - 1, _("invalid number")); - return FALSE; -} - -/* Read a required string from an IEEE file. */ - -static bfd_boolean -ieee_read_id (struct ieee_info *info, const bfd_byte **pp, - const char **pname, unsigned long *pnamlen) -{ - return ieee_read_optional_id (info, pp, pname, pnamlen, (bfd_boolean *) NULL); -} - -/* Read a string from an IEEE file. If ppresent is not NULL, the - string is optional. */ - -static bfd_boolean -ieee_read_optional_id (struct ieee_info *info, const bfd_byte **pp, - const char **pname, unsigned long *pnamlen, - bfd_boolean *ppresent) -{ - bfd_byte b; - unsigned long len; - - if (*pp >= info->pend) - { - ieee_eof (info); - return FALSE; - } - - b = **pp; - ++*pp; - - if (b <= 0x7f) - len = b; - else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum) - { - len = **pp; - ++*pp; - } - else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum) - { - len = (**pp << 8) + (*pp)[1]; - *pp += 2; - } - else - { - if (ppresent != NULL) - { - --*pp; - *ppresent = FALSE; - return TRUE; - } - ieee_error (info, *pp - 1, _("invalid string length")); - return FALSE; - } - - if ((unsigned long) (info->pend - *pp) < len) - { - ieee_eof (info); - return FALSE; - } - - *pname = (const char *) *pp; - *pnamlen = len; - *pp += len; - - if (ppresent != NULL) - *ppresent = TRUE; - - return TRUE; -} - -/* Read an expression from an IEEE file. Since this code is only used - to parse debugging information, I haven't bothered to write a full - blown IEEE expression parser. I've only thrown in the things I've - seen in debugging information. This can be easily extended if - necessary. */ - -static bfd_boolean -ieee_read_expression (struct ieee_info *info, const bfd_byte **pp, - bfd_vma *pv) -{ - const bfd_byte *expr_start; -#define EXPR_STACK_SIZE (10) - bfd_vma expr_stack[EXPR_STACK_SIZE]; - bfd_vma *esp; - - expr_start = *pp; - - esp = expr_stack; - - while (1) - { - const bfd_byte *start; - bfd_vma val; - bfd_boolean present; - ieee_record_enum_type c; - - start = *pp; - - if (! ieee_read_optional_number (info, pp, &val, &present)) - return FALSE; - - if (present) - { - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, _("expression stack overflow")); - return FALSE; - } - *esp++ = val; - continue; - } - - c = (ieee_record_enum_type) **pp; - - if (c >= ieee_module_beginning_enum) - break; - - ++*pp; - - if (c == ieee_comma) - break; - - switch (c) - { - default: - ieee_error (info, start, _("unsupported IEEE expression operator")); - break; - - case ieee_variable_R_enum: - { - bfd_vma indx; - asection *s; - - if (! ieee_read_number (info, pp, &indx)) - return FALSE; - for (s = info->abfd->sections; s != NULL; s = s->next) - if ((bfd_vma) s->target_index == indx) - break; - if (s == NULL) - { - ieee_error (info, start, _("unknown section")); - return FALSE; - } - - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, _("expression stack overflow")); - return FALSE; - } - - *esp++ = bfd_get_section_vma (info->abfd, s); - } - break; - - case ieee_function_plus_enum: - case ieee_function_minus_enum: - { - bfd_vma v1, v2; - - if (esp - expr_stack < 2) - { - ieee_error (info, start, _("expression stack underflow")); - return FALSE; - } - - v1 = *--esp; - v2 = *--esp; - *esp++ = v1 + v2; - } - break; - } - } - - if (esp - 1 != expr_stack) - { - ieee_error (info, expr_start, _("expression stack mismatch")); - return FALSE; - } - - *pv = *--esp; - - return TRUE; -} - -/* Return an IEEE builtin type. */ - -static debug_type -ieee_builtin_type (struct ieee_info *info, const bfd_byte *p, - unsigned int indx) -{ - void *dhandle; - debug_type type; - const char *name; - - if (indx < BUILTIN_TYPE_COUNT - && info->types.builtins[indx] != DEBUG_TYPE_NULL) - return info->types.builtins[indx]; - - dhandle = info->dhandle; - - if (indx >= 32 && indx < 64) - { - type = debug_make_pointer_type (dhandle, - ieee_builtin_type (info, p, indx - 32)); - assert (indx < BUILTIN_TYPE_COUNT); - info->types.builtins[indx] = type; - return type; - } - - switch ((enum builtin_types) indx) - { - default: - ieee_error (info, p, _("unknown builtin type")); - return NULL; - - case builtin_unknown: - type = debug_make_void_type (dhandle); - name = NULL; - break; - - case builtin_void: - type = debug_make_void_type (dhandle); - name = "void"; - break; - - case builtin_signed_char: - type = debug_make_int_type (dhandle, 1, FALSE); - name = "signed char"; - break; - - case builtin_unsigned_char: - type = debug_make_int_type (dhandle, 1, TRUE); - name = "unsigned char"; - break; - - case builtin_signed_short_int: - type = debug_make_int_type (dhandle, 2, FALSE); - name = "signed short int"; - break; - - case builtin_unsigned_short_int: - type = debug_make_int_type (dhandle, 2, TRUE); - name = "unsigned short int"; - break; - - case builtin_signed_long: - type = debug_make_int_type (dhandle, 4, FALSE); - name = "signed long"; - break; - - case builtin_unsigned_long: - type = debug_make_int_type (dhandle, 4, TRUE); - name = "unsigned long"; - break; - - case builtin_signed_long_long: - type = debug_make_int_type (dhandle, 8, FALSE); - name = "signed long long"; - break; - - case builtin_unsigned_long_long: - type = debug_make_int_type (dhandle, 8, TRUE); - name = "unsigned long long"; - break; - - case builtin_float: - type = debug_make_float_type (dhandle, 4); - name = "float"; - break; - - case builtin_double: - type = debug_make_float_type (dhandle, 8); - name = "double"; - break; - - case builtin_long_double: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_float_type (dhandle, 12); - name = "long double"; - break; - - case builtin_long_long_double: - type = debug_make_float_type (dhandle, 16); - name = "long long double"; - break; - - case builtin_quoted_string: - type = debug_make_array_type (dhandle, - ieee_builtin_type (info, p, - ((unsigned int) - builtin_char)), - ieee_builtin_type (info, p, - ((unsigned int) - builtin_int)), - 0, -1, TRUE); - name = "QUOTED STRING"; - break; - - case builtin_instruction_address: - /* FIXME: This should be a code address. */ - type = debug_make_int_type (dhandle, 4, TRUE); - name = "instruction address"; - break; - - case builtin_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, FALSE); - name = "int"; - break; - - case builtin_unsigned: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, TRUE); - name = "unsigned"; - break; - - case builtin_unsigned_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, TRUE); - name = "unsigned int"; - break; - - case builtin_char: - type = debug_make_int_type (dhandle, 1, FALSE); - name = "char"; - break; - - case builtin_long: - type = debug_make_int_type (dhandle, 4, FALSE); - name = "long"; - break; - - case builtin_short: - type = debug_make_int_type (dhandle, 2, FALSE); - name = "short"; - break; - - case builtin_unsigned_short: - type = debug_make_int_type (dhandle, 2, TRUE); - name = "unsigned short"; - break; - - case builtin_short_int: - type = debug_make_int_type (dhandle, 2, FALSE); - name = "short int"; - break; - - case builtin_signed_short: - type = debug_make_int_type (dhandle, 2, FALSE); - name = "signed short"; - break; - - case builtin_bcd_float: - ieee_error (info, p, _("BCD float type not supported")); - return DEBUG_TYPE_NULL; - } - - if (name != NULL) - type = debug_name_type (dhandle, name, type); - - assert (indx < BUILTIN_TYPE_COUNT); - - info->types.builtins[indx] = type; - - return type; -} - -/* Allocate more space in the type table. If ref is TRUE, this is a - reference to the type; if it is not already defined, we should set - up an indirect type. */ - -static bfd_boolean -ieee_alloc_type (struct ieee_info *info, unsigned int indx, bfd_boolean ref) -{ - unsigned int nalloc; - register struct ieee_type *t; - struct ieee_type *tend; - - if (indx >= info->types.alloc) - { - nalloc = info->types.alloc; - if (nalloc == 0) - nalloc = 4; - while (indx >= nalloc) - nalloc *= 2; - - info->types.types = ((struct ieee_type *) - xrealloc (info->types.types, - nalloc * sizeof *info->types.types)); - - memset (info->types.types + info->types.alloc, 0, - (nalloc - info->types.alloc) * sizeof *info->types.types); - - tend = info->types.types + nalloc; - for (t = info->types.types + info->types.alloc; t < tend; t++) - t->type = DEBUG_TYPE_NULL; - - info->types.alloc = nalloc; - } - - if (ref) - { - t = info->types.types + indx; - if (t->type == NULL) - { - t->pslot = (debug_type *) xmalloc (sizeof *t->pslot); - *t->pslot = DEBUG_TYPE_NULL; - t->type = debug_make_indirect_type (info->dhandle, t->pslot, - (const char *) NULL); - if (t->type == NULL) - return FALSE; - } - } - - return TRUE; -} - -/* Read a type index and return the corresponding type. */ - -static bfd_boolean -ieee_read_type_index (struct ieee_info *info, const bfd_byte **pp, - debug_type *ptype) -{ - const bfd_byte *start; - bfd_vma indx; - - start = *pp; - - if (! ieee_read_number (info, pp, &indx)) - return FALSE; - - if (indx < 256) - { - *ptype = ieee_builtin_type (info, start, indx); - if (*ptype == NULL) - return FALSE; - return TRUE; - } - - indx -= 256; - if (! ieee_alloc_type (info, indx, TRUE)) - return FALSE; - - *ptype = info->types.types[indx].type; - - return TRUE; -} - -/* Parse IEEE debugging information for a file. This is passed the - bytes which compose the Debug Information Part of an IEEE file. */ - -bfd_boolean -parse_ieee (void *dhandle, bfd *abfd, const bfd_byte *bytes, bfd_size_type len) -{ - struct ieee_info info; - unsigned int i; - const bfd_byte *p, *pend; - - info.dhandle = dhandle; - info.abfd = abfd; - info.bytes = bytes; - info.pend = bytes + len; - info.blockstack.bsp = info.blockstack.stack; - info.saw_filename = FALSE; - info.vars.alloc = 0; - info.vars.vars = NULL; - info.global_vars = NULL; - info.types.alloc = 0; - info.types.types = NULL; - info.global_types = NULL; - info.tags = NULL; - for (i = 0; i < BUILTIN_TYPE_COUNT; i++) - info.types.builtins[i] = DEBUG_TYPE_NULL; - - p = bytes; - pend = info.pend; - while (p < pend) - { - const bfd_byte *record_start; - ieee_record_enum_type c; - - record_start = p; - - c = (ieee_record_enum_type) *p++; - - if (c == ieee_at_record_enum) - c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++); - - if (c <= ieee_number_repeat_end_enum) - { - ieee_error (&info, record_start, _("unexpected number")); - return FALSE; - } - - switch (c) - { - default: - ieee_error (&info, record_start, _("unexpected record type")); - return FALSE; - - case ieee_bb_record_enum: - if (! parse_ieee_bb (&info, &p)) - return FALSE; - break; - - case ieee_be_record_enum: - if (! parse_ieee_be (&info, &p)) - return FALSE; - break; - - case ieee_nn_record: - if (! parse_ieee_nn (&info, &p)) - return FALSE; - break; - - case ieee_ty_record_enum: - if (! parse_ieee_ty (&info, &p)) - return FALSE; - break; - - case ieee_atn_record_enum: - if (! parse_ieee_atn (&info, &p)) - return FALSE; - break; - } - } - - if (info.blockstack.bsp != info.blockstack.stack) - { - ieee_error (&info, (const bfd_byte *) NULL, - _("blocks left on stack at end")); - return FALSE; - } - - return TRUE; -} - -/* Handle an IEEE BB record. */ - -static bfd_boolean -parse_ieee_bb (struct ieee_info *info, const bfd_byte **pp) -{ - const bfd_byte *block_start; - bfd_byte b; - bfd_vma size; - const char *name; - unsigned long namlen; - char *namcopy = NULL; - unsigned int fnindx; - bfd_boolean skip; - - block_start = *pp; - - b = **pp; - ++*pp; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_id (info, pp, &name, &namlen)) - return FALSE; - - fnindx = (unsigned int) -1; - skip = FALSE; - - switch (b) - { - case 1: - /* BB1: Type definitions local to a module. */ - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_set_filename (info->dhandle, namcopy)) - return FALSE; - info->saw_filename = TRUE; - - /* Discard any variables or types we may have seen before. */ - if (info->vars.vars != NULL) - free (info->vars.vars); - info->vars.vars = NULL; - info->vars.alloc = 0; - if (info->types.types != NULL) - free (info->types.types); - info->types.types = NULL; - info->types.alloc = 0; - - /* Initialize the types to the global types. */ - if (info->global_types != NULL) - { - info->types.alloc = info->global_types->alloc; - info->types.types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->types.types, info->global_types->types, - info->types.alloc * sizeof (*info->types.types)); - } - - break; - - case 2: - /* BB2: Global type definitions. The name is supposed to be - empty, but we don't check. */ - if (! debug_set_filename (info->dhandle, "*global*")) - return FALSE; - info->saw_filename = TRUE; - break; - - case 3: - /* BB3: High level module block begin. We don't have to do - anything here. The name is supposed to be the same as for - the BB1, but we don't check. */ - break; - - case 4: - /* BB4: Global function. */ - { - bfd_vma stackspace, typindx, offset; - debug_type return_type; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return FALSE; - - /* We have no way to record the stack space. FIXME. */ - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, typindx); - if (return_type == DEBUG_TYPE_NULL) - return FALSE; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, TRUE)) - return FALSE; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_record_function (info->dhandle, namcopy, return_type, - TRUE, offset)) - return FALSE; - } - break; - - case 5: - /* BB5: File name for source line numbers. */ - { - unsigned int i; - - /* We ignore the date and time. FIXME. */ - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - bfd_boolean present; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return FALSE; - if (! present) - break; - } - - if (! info->saw_filename) - { - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_set_filename (info->dhandle, namcopy)) - return FALSE; - info->saw_filename = TRUE; - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_start_source (info->dhandle, namcopy)) - return FALSE; - } - break; - - case 6: - /* BB6: Local function or block. */ - { - bfd_vma stackspace, typindx, offset; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return FALSE; - - /* We have no way to record the stack space. FIXME. */ - - if (namlen == 0) - { - if (! debug_start_block (info->dhandle, offset)) - return FALSE; - /* Change b to indicate that this is a block - rather than a function. */ - b = 0x86; - } - else - { - /* The MRI C++ compiler will output a fake function named - __XRYCPP to hold C++ debugging information. We skip - that function. This is not crucial, but it makes - converting from IEEE to other debug formats work - better. */ - if (strncmp (name, "__XRYCPP", namlen) == 0) - skip = TRUE; - else - { - debug_type return_type; - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, - typindx); - if (return_type == NULL) - return FALSE; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, TRUE)) - return FALSE; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_record_function (info->dhandle, namcopy, - return_type, FALSE, offset)) - return FALSE; - } - } - } - break; - - case 10: - /* BB10: Assembler module scope. In the normal case, we - completely ignore all this information. FIXME. */ - { - const char *inam, *vstr; - unsigned long inamlen, vstrlen; - bfd_vma tool_type; - bfd_boolean present; - unsigned int i; - - if (! info->saw_filename) - { - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return FALSE; - if (! debug_set_filename (info->dhandle, namcopy)) - return FALSE; - info->saw_filename = TRUE; - } - - if (! ieee_read_id (info, pp, &inam, &inamlen) - || ! ieee_read_number (info, pp, &tool_type) - || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) - return FALSE; - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return FALSE; - if (! present) - break; - } - } - break; - - case 11: - /* BB11: Module section. We completely ignore all this - information. FIXME. */ - { - bfd_vma sectype, secindx, offset, map; - bfd_boolean present; - - if (! ieee_read_number (info, pp, §ype) - || ! ieee_read_number (info, pp, &secindx) - || ! ieee_read_expression (info, pp, &offset) - || ! ieee_read_optional_number (info, pp, &map, &present)) - return FALSE; - } - break; - - default: - ieee_error (info, block_start, _("unknown BB type")); - return FALSE; - } - - - /* Push this block on the block stack. */ - - if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE) - { - ieee_error (info, (const bfd_byte *) NULL, _("stack overflow")); - return FALSE; - } - - info->blockstack.bsp->kind = b; - if (b == 5) - info->blockstack.bsp->filename = namcopy; - info->blockstack.bsp->fnindx = fnindx; - info->blockstack.bsp->skip = skip; - ++info->blockstack.bsp; - - return TRUE; -} - -/* Handle an IEEE BE record. */ - -static bfd_boolean -parse_ieee_be (struct ieee_info *info, const bfd_byte **pp) -{ - bfd_vma offset; - - if (info->blockstack.bsp <= info->blockstack.stack) - { - ieee_error (info, *pp, _("stack underflow")); - return FALSE; - } - --info->blockstack.bsp; - - switch (info->blockstack.bsp->kind) - { - case 2: - /* When we end the global typedefs block, we copy out the - contents of info->vars. This is because the variable indices - may be reused in the local blocks. However, we need to - preserve them so that we can locate a function returning a - reference variable whose type is named in the global typedef - block. */ - info->global_vars = ((struct ieee_vars *) - xmalloc (sizeof *info->global_vars)); - info->global_vars->alloc = info->vars.alloc; - info->global_vars->vars = ((struct ieee_var *) - xmalloc (info->vars.alloc - * sizeof (*info->vars.vars))); - memcpy (info->global_vars->vars, info->vars.vars, - info->vars.alloc * sizeof (*info->vars.vars)); - - /* We also copy out the non builtin parts of info->types, since - the types are discarded when we start a new block. */ - info->global_types = ((struct ieee_types *) - xmalloc (sizeof *info->global_types)); - info->global_types->alloc = info->types.alloc; - info->global_types->types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->global_types->types, info->types.types, - info->types.alloc * sizeof (*info->types.types)); - memset (info->global_types->builtins, 0, - sizeof (info->global_types->builtins)); - - break; - - case 4: - case 6: - if (! ieee_read_expression (info, pp, &offset)) - return FALSE; - if (! info->blockstack.bsp->skip) - { - if (! debug_end_function (info->dhandle, offset + 1)) - return FALSE; - } - break; - - case 0x86: - /* This is BE6 when BB6 started a block rather than a local - function. */ - if (! ieee_read_expression (info, pp, &offset)) - return FALSE; - if (! debug_end_block (info->dhandle, offset + 1)) - return FALSE; - break; - - case 5: - /* When we end a BB5, we look up the stack for the last BB5, if - there is one, so that we can call debug_start_source. */ - if (info->blockstack.bsp > info->blockstack.stack) - { - struct ieee_block *bl; - - bl = info->blockstack.bsp; - do - { - --bl; - if (bl->kind == 5) - { - if (! debug_start_source (info->dhandle, bl->filename)) - return FALSE; - break; - } - } - while (bl != info->blockstack.stack); - } - break; - - case 11: - if (! ieee_read_expression (info, pp, &offset)) - return FALSE; - /* We just ignore the module size. FIXME. */ - break; - - default: - /* Other block types do not have any trailing information. */ - break; - } - - return TRUE; -} - -/* Parse an NN record. */ - -static bfd_boolean -parse_ieee_nn (struct ieee_info *info, const bfd_byte **pp) -{ - const bfd_byte *nn_start; - bfd_vma varindx; - const char *name; - unsigned long namlen; - - nn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_id (info, pp, &name, &namlen)) - return FALSE; - - if (varindx < 32) - { - ieee_error (info, nn_start, _("illegal variable index")); - return FALSE; - } - varindx -= 32; - - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - alloc * sizeof *info->vars.vars)); - memset (info->vars.vars + info->vars.alloc, 0, - (alloc - info->vars.alloc) * sizeof *info->vars.vars); - info->vars.alloc = alloc; - } - - info->vars.vars[varindx].name = name; - info->vars.vars[varindx].namlen = namlen; - - return TRUE; -} - -/* Parse a TY record. */ - -static bfd_boolean -parse_ieee_ty (struct ieee_info *info, const bfd_byte **pp) -{ - const bfd_byte *ty_start, *ty_var_start, *ty_code_start; - bfd_vma typeindx, varindx, tc; - void *dhandle; - bfd_boolean tag, typdef; - debug_type *arg_slots; - unsigned long type_bitsize; - debug_type type; - - ty_start = *pp; - - if (! ieee_read_number (info, pp, &typeindx)) - return FALSE; - - if (typeindx < 256) - { - ieee_error (info, ty_start, _("illegal type index")); - return FALSE; - } - - typeindx -= 256; - if (! ieee_alloc_type (info, typeindx, FALSE)) - return FALSE; - - if (**pp != 0xce) - { - ieee_error (info, *pp, _("unknown TY code")); - return FALSE; - } - ++*pp; - - ty_var_start = *pp; - - if (! ieee_read_number (info, pp, &varindx)) - return FALSE; - - if (varindx < 32) - { - ieee_error (info, ty_var_start, _("illegal variable index")); - return FALSE; - } - varindx -= 32; - - if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) - { - ieee_error (info, ty_var_start, _("undefined variable in TY")); - return FALSE; - } - - ty_code_start = *pp; - - if (! ieee_read_number (info, pp, &tc)) - return FALSE; - - dhandle = info->dhandle; - - tag = FALSE; - typdef = FALSE; - arg_slots = NULL; - type_bitsize = 0; - switch (tc) - { - default: - ieee_error (info, ty_code_start, _("unknown TY code")); - return FALSE; - - case '!': - /* Unknown type, with size. We treat it as int. FIXME. */ - { - bfd_vma size; - - if (! ieee_read_number (info, pp, &size)) - return FALSE; - type = debug_make_int_type (dhandle, size, FALSE); - } - break; - - case 'A': /* Array. */ - case 'a': /* FORTRAN array in column/row order. FIXME: Not - distinguished from normal array. */ - { - debug_type ele_type; - bfd_vma lower, upper; - - if (! ieee_read_type_index (info, pp, &ele_type) - || ! ieee_read_number (info, pp, &lower) - || ! ieee_read_number (info, pp, &upper)) - return FALSE; - type = debug_make_array_type (dhandle, ele_type, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - (bfd_signed_vma) lower, - (bfd_signed_vma) upper, - FALSE); - } - break; - - case 'E': - /* Simple enumeration. */ - { - bfd_vma size; - unsigned int alloc; - const char **names; - unsigned int c; - bfd_signed_vma *vals; - unsigned int i; - - if (! ieee_read_number (info, pp, &size)) - return FALSE; - /* FIXME: we ignore the enumeration size. */ - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - memset (names, 0, alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - bfd_boolean present; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - if (! present) - break; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return FALSE; - ++c; - } - - names[c] = NULL; - - vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals); - for (i = 0; i < c; i++) - vals[i] = i; - - type = debug_make_enum_type (dhandle, names, vals); - tag = TRUE; - } - break; - - case 'G': - /* Struct with bit fields. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return FALSE; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - bfd_boolean present; - debug_type ftype; - bfd_vma bitpos, bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - if (! present) - break; - if (! ieee_read_type_index (info, pp, &ftype) - || ! ieee_read_number (info, pp, &bitpos) - || ! ieee_read_number (info, pp, &bitsize)) - return FALSE; - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, bitpos, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return FALSE; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, TRUE, size, fields); - tag = TRUE; - } - break; - - case 'N': - /* Enumeration. */ - { - unsigned int alloc; - const char **names; - bfd_signed_vma *vals; - unsigned int c; - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - bfd_boolean present; - bfd_vma val; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - if (! present) - break; - if (! ieee_read_number (info, pp, &val)) - return FALSE; - - /* If the length of the name is zero, then the value is - actually the size of the enum. We ignore this - information. FIXME. */ - if (namlen == 0) - continue; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - vals = ((bfd_signed_vma *) - xrealloc (vals, alloc * sizeof *vals)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return FALSE; - vals[c] = (bfd_signed_vma) val; - ++c; - } - - names[c] = NULL; - - type = debug_make_enum_type (dhandle, names, vals); - tag = TRUE; - } - break; - - case 'O': /* Small pointer. We don't distinguish small and large - pointers. FIXME. */ - case 'P': /* Large pointer. */ - { - debug_type t; - - if (! ieee_read_type_index (info, pp, &t)) - return FALSE; - type = debug_make_pointer_type (dhandle, t); - } - break; - - case 'R': - /* Range. */ - { - bfd_vma low, high, signedp, size; - - if (! ieee_read_number (info, pp, &low) - || ! ieee_read_number (info, pp, &high) - || ! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &size)) - return FALSE; - - type = debug_make_range_type (dhandle, - debug_make_int_type (dhandle, size, - ! signedp), - (bfd_signed_vma) low, - (bfd_signed_vma) high); - } - break; - - case 'S': /* Struct. */ - case 'U': /* Union. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return FALSE; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - bfd_boolean present; - bfd_vma tindx; - bfd_vma offset; - debug_type ftype; - bfd_vma bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - if (! present) - break; - if (! ieee_read_number (info, pp, &tindx) - || ! ieee_read_number (info, pp, &offset)) - return FALSE; - - if (tindx < 256) - { - ftype = ieee_builtin_type (info, ty_code_start, tindx); - bitsize = 0; - offset *= 8; - } - else - { - struct ieee_type *t; - - tindx -= 256; - if (! ieee_alloc_type (info, tindx, TRUE)) - return FALSE; - t = info->types.types + tindx; - ftype = t->type; - bitsize = t->bitsize; - if (bitsize == 0) - offset *= 8; - } - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, offset, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return FALSE; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, tc == 'S', size, fields); - tag = TRUE; - } - break; - - case 'T': - /* Typedef. */ - if (! ieee_read_type_index (info, pp, &type)) - return FALSE; - typdef = TRUE; - break; - - case 'X': - /* Procedure. FIXME: This is an extern declaration, which we - have no way of representing. */ - { - bfd_vma attr; - debug_type rtype; - bfd_vma nargs; - bfd_boolean present; - struct ieee_var *pv; - - /* FIXME: We ignore the attribute and the argument names. */ - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return FALSE; - do - { - const char *name; - unsigned long namlen; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - } - while (present); - - pv = info->vars.vars + varindx; - pv->kind = IEEE_EXTERNAL; - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL, - FALSE); - } - break; - - case 'V': - case 'v': - /* Void. This is not documented, but the MRI compiler emits it. */ - type = debug_make_void_type (dhandle); - break; - - case 'Z': - /* Array with 0 lower bound. */ - { - debug_type etype; - bfd_vma high; - - if (! ieee_read_type_index (info, pp, &etype) - || ! ieee_read_number (info, pp, &high)) - return FALSE; - - type = debug_make_array_type (dhandle, etype, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - 0, (bfd_signed_vma) high, FALSE); - } - break; - - case 'c': /* Complex. */ - case 'd': /* Double complex. */ - { - const char *name; - unsigned long namlen; - - /* FIXME: I don't know what the name means. */ - - if (! ieee_read_id (info, pp, &name, &namlen)) - return FALSE; - - type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8); - } - break; - - case 'f': - /* Pascal file name. FIXME. */ - ieee_error (info, ty_code_start, _("Pascal file name not supported")); - return FALSE; - - case 'g': - /* Bitfield type. */ - { - bfd_vma signedp, bitsize, dummy; - const bfd_byte *hold; - bfd_boolean present; - - if (! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &bitsize)) - return FALSE; - - /* I think the documentation says that there is a type index, - but some actual files do not have one. */ - hold = *pp; - if (! ieee_read_optional_number (info, pp, &dummy, &present)) - return FALSE; - if (! present) - { - /* FIXME: This is just a guess. */ - type = debug_make_int_type (dhandle, 4, - signedp ? FALSE : TRUE); - } - else - { - *pp = hold; - if (! ieee_read_type_index (info, pp, &type)) - return FALSE; - } - type_bitsize = bitsize; - } - break; - - case 'n': - /* Qualifier. */ - { - bfd_vma kind; - debug_type t; - - if (! ieee_read_number (info, pp, &kind) - || ! ieee_read_type_index (info, pp, &t)) - return FALSE; - - switch (kind) - { - default: - ieee_error (info, ty_start, _("unsupported qualifier")); - return FALSE; - - case 1: - type = debug_make_const_type (dhandle, t); - break; - - case 2: - type = debug_make_volatile_type (dhandle, t); - break; - } - } - break; - - case 's': - /* Set. */ - { - bfd_vma size; - debug_type etype; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_type_index (info, pp, &etype)) - return FALSE; - - /* FIXME: We ignore the size. */ - - type = debug_make_set_type (dhandle, etype, FALSE); - } - break; - - case 'x': - /* Procedure with compiler dependencies. */ - { - struct ieee_var *pv; - bfd_vma attr, frame_type, push_mask, nargs, level, father; - debug_type rtype; - debug_type *arg_types; - bfd_boolean varargs; - bfd_boolean present; - - /* FIXME: We ignore some of this information. */ - - pv = info->vars.vars + varindx; - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_number (info, pp, &frame_type) - || ! ieee_read_number (info, pp, &push_mask) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return FALSE; - if (nargs == (bfd_vma) -1) - { - arg_types = NULL; - varargs = FALSE; - } - else - { - unsigned int i; - - arg_types = ((debug_type *) - xmalloc ((nargs + 1) * sizeof *arg_types)); - for (i = 0; i < nargs; i++) - if (! ieee_read_type_index (info, pp, arg_types + i)) - return FALSE; - - /* If the last type is pointer to void, this is really a - varargs function. */ - varargs = FALSE; - if (nargs > 0) - { - debug_type last; - - last = arg_types[nargs - 1]; - if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER - && (debug_get_type_kind (dhandle, - debug_get_target_type (dhandle, - last)) - == DEBUG_KIND_VOID)) - { - --nargs; - varargs = TRUE; - } - } - - /* If there are any pointer arguments, turn them into - indirect types in case we later need to convert them to - reference types. */ - for (i = 0; i < nargs; i++) - { - if (debug_get_type_kind (dhandle, arg_types[i]) - == DEBUG_KIND_POINTER) - { - if (arg_slots == NULL) - { - arg_slots = ((debug_type *) - xmalloc (nargs * sizeof *arg_slots)); - memset (arg_slots, 0, nargs * sizeof *arg_slots); - } - arg_slots[i] = arg_types[i]; - arg_types[i] = - debug_make_indirect_type (dhandle, - arg_slots + i, - (const char *) NULL); - } - } - - arg_types[nargs] = DEBUG_TYPE_NULL; - } - if (! ieee_read_number (info, pp, &level) - || ! ieee_read_optional_number (info, pp, &father, &present)) - return FALSE; - - /* We can't distinguish between a global function and a static - function. */ - pv->kind = IEEE_FUNCTION; - - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, arg_types, varargs); - } - break; - } - - /* Record the type in the table. */ - - if (type == DEBUG_TYPE_NULL) - return FALSE; - - info->vars.vars[varindx].type = type; - - if ((tag || typdef) - && info->vars.vars[varindx].namlen > 0) - { - const char *name; - - name = savestring (info->vars.vars[varindx].name, - info->vars.vars[varindx].namlen); - if (typdef) - type = debug_name_type (dhandle, name, type); - else if (tc == 'E' || tc == 'N') - type = debug_tag_type (dhandle, name, type); - else - { - struct ieee_tag *it; - - /* We must allocate all struct tags as indirect types, so - that if we later see a definition of the tag as a C++ - record we can update the indirect slot and automatically - change all the existing references. */ - it = (struct ieee_tag *) xmalloc (sizeof *it); - memset (it, 0, sizeof *it); - it->next = info->tags; - info->tags = it; - it->name = name; - it->slot = type; - - type = debug_make_indirect_type (dhandle, &it->slot, name); - type = debug_tag_type (dhandle, name, type); - - it->type = type; - } - if (type == NULL) - return FALSE; - } - - info->types.types[typeindx].type = type; - info->types.types[typeindx].arg_slots = arg_slots; - info->types.types[typeindx].bitsize = type_bitsize; - - /* We may have already allocated type as an indirect type pointing - to slot. It does no harm to replace the indirect type with the - real type. Filling in slot as well handles the indirect types - which are already hanging around. */ - if (info->types.types[typeindx].pslot != NULL) - *info->types.types[typeindx].pslot = type; - - return TRUE; -} - -/* Parse an ATN record. */ - -static bfd_boolean -parse_ieee_atn (struct ieee_info *info, const bfd_byte **pp) -{ - const bfd_byte *atn_start, *atn_code_start; - bfd_vma varindx; - struct ieee_var *pvar; - debug_type type; - bfd_vma atn_code; - void *dhandle; - bfd_vma v, v2, v3, v4, v5; - const char *name; - unsigned long namlen; - char *namcopy; - bfd_boolean present; - int blocktype; - - atn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_type_index (info, pp, &type)) - return FALSE; - - atn_code_start = *pp; - - if (! ieee_read_number (info, pp, &atn_code)) - return FALSE; - - if (varindx == 0) - { - pvar = NULL; - name = ""; - namlen = 0; - } - else if (varindx < 32) - { - /* The MRI compiler reportedly sometimes emits variable lifetime - information for a register. We just ignore it. */ - if (atn_code == 9) - return ieee_read_number (info, pp, &v); - - ieee_error (info, atn_start, _("illegal variable index")); - return FALSE; - } - else - { - varindx -= 32; - if (varindx >= info->vars.alloc - || info->vars.vars[varindx].name == NULL) - { - /* The MRI compiler or linker sometimes omits the NN record - for a pmisc record. */ - if (atn_code == 62) - { - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - (alloc - * sizeof *info->vars.vars))); - memset (info->vars.vars + info->vars.alloc, 0, - ((alloc - info->vars.alloc) - * sizeof *info->vars.vars)); - info->vars.alloc = alloc; - } - - pvar = info->vars.vars + varindx; - pvar->name = ""; - pvar->namlen = 0; - } - else - { - ieee_error (info, atn_start, _("undefined variable in ATN")); - return FALSE; - } - } - - pvar = info->vars.vars + varindx; - - pvar->type = type; - - name = pvar->name; - namlen = pvar->namlen; - } - - dhandle = info->dhandle; - - /* If we are going to call debug_record_variable with a pointer - type, change the type to an indirect type so that we can later - change it to a reference type if we encounter a C++ pmisc 'R' - record. */ - if (pvar != NULL - && type != DEBUG_TYPE_NULL - && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) - { - switch (atn_code) - { - case 1: - case 2: - case 3: - case 5: - case 8: - case 10: - pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); - *pvar->pslot = type; - type = debug_make_indirect_type (dhandle, pvar->pslot, - (const char *) NULL); - pvar->type = type; - break; - } - } - - switch (atn_code) - { - default: - ieee_error (info, atn_code_start, _("unknown ATN type")); - return FALSE; - - case 1: - /* Automatic variable. */ - if (! ieee_read_number (info, pp, &v)) - return FALSE; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); - - case 2: - /* Register variable. */ - if (! ieee_read_number (info, pp, &v)) - return FALSE; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, - ieee_regno_to_genreg (info->abfd, v)); - - case 3: - /* Static variable. */ - if (! ieee_require_asn (info, pp, &v)) - return FALSE; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (info->blockstack.bsp <= info->blockstack.stack) - blocktype = 0; - else - blocktype = info->blockstack.bsp[-1].kind; - if (pvar != NULL) - { - if (blocktype == 4 || blocktype == 6) - pvar->kind = IEEE_LOCAL; - else - pvar->kind = IEEE_STATIC; - } - return debug_record_variable (dhandle, namcopy, type, - (blocktype == 4 || blocktype == 6 - ? DEBUG_LOCAL_STATIC - : DEBUG_STATIC), - v); - - case 4: - /* External function. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return TRUE; - - case 5: - /* External variable. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return TRUE; - - case 7: - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return FALSE; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return FALSE; - } - - /* We just ignore the two optional fields in v3 and v4, since - they are not defined. */ - - if (! ieee_require_asn (info, pp, &v3)) - return FALSE; - - /* We have no way to record the column number. FIXME. */ - - return debug_record_line (dhandle, v, v3); - - case 8: - /* Global variable. */ - if (! ieee_require_asn (info, pp, &v)) - return FALSE; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_GLOBAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); - - case 9: - /* Variable lifetime information. */ - if (! ieee_read_number (info, pp, &v)) - return FALSE; - - /* We have no way to record this information. FIXME. */ - return TRUE; - - case 10: - /* Locked register. The spec says that there are two required - fields, but at least on occasion the MRI compiler only emits - one. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return FALSE; - - /* I think this means a variable that is both in a register and - a frame slot. We ignore the frame slot. FIXME. */ - - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); - - case 11: - /* Reserved for FORTRAN common. */ - ieee_error (info, atn_code_start, _("unsupported ATN11")); - - /* Return TRUE to keep going. */ - return TRUE; - - case 12: - /* Based variable. */ - v3 = 0; - v4 = 0x80; - v5 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return FALSE; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return FALSE; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v5, &present)) - return FALSE; - } - } - - /* We have no way to record this information. FIXME. */ - - ieee_error (info, atn_code_start, _("unsupported ATN12")); - - /* Return TRUE to keep going. */ - return TRUE; - - case 16: - /* Constant. The description of this that I have is ambiguous, - so I'm not going to try to implement it. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return FALSE; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v2, &present)) - return FALSE; - if (present) - { - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - } - } - - if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) - { - if (! ieee_require_asn (info, pp, &v3)) - return FALSE; - } - - return TRUE; - - case 19: - /* Static variable from assembler. */ - v2 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present) - || ! ieee_require_asn (info, pp, &v3)) - return FALSE; - namcopy = savestring (name, namlen); - /* We don't really handle this correctly. FIXME. */ - return debug_record_variable (dhandle, namcopy, - debug_make_void_type (dhandle), - v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, - v3); - - case 62: - /* Procedure miscellaneous information. */ - case 63: - /* Variable miscellaneous information. */ - case 64: - /* Module miscellaneous information. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return FALSE; - - if (atn_code == 62 && v == 80) - { - if (present) - { - ieee_error (info, atn_code_start, - _("unexpected string in C++ misc")); - return FALSE; - } - return ieee_read_cxx_misc (info, pp, v2); - } - - /* We just ignore all of this stuff. FIXME. */ - - for (; v2 > 0; --v2) - { - switch ((ieee_record_enum_type) **pp) - { - default: - ieee_error (info, *pp, _("bad misc record")); - return FALSE; - - case ieee_at_record_enum: - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return FALSE; - break; - - case ieee_e2_first_byte_enum: - if (! ieee_require_asn (info, pp, &v3)) - return FALSE; - break; - } - } - - return TRUE; - } - - /*NOTREACHED*/ -} - -/* Handle C++ debugging miscellaneous records. This is called for - procedure miscellaneous records of type 80. */ - -static bfd_boolean -ieee_read_cxx_misc (struct ieee_info *info, const bfd_byte **pp, - unsigned long count) -{ - const bfd_byte *start; - bfd_vma category; - - start = *pp; - - /* Get the category of C++ misc record. */ - if (! ieee_require_asn (info, pp, &category)) - return FALSE; - --count; - - switch (category) - { - default: - ieee_error (info, start, _("unrecognized C++ misc record")); - return FALSE; - - case 'T': - if (! ieee_read_cxx_class (info, pp, count)) - return FALSE; - break; - - case 'M': - { - bfd_vma flags; - const char *name; - unsigned long namlen; - - /* The IEEE spec indicates that the 'M' record only has a - flags field. The MRI compiler also emits the name of the - function. */ - - if (! ieee_require_asn (info, pp, &flags)) - return FALSE; - if (*pp < info->pend - && (ieee_record_enum_type) **pp == ieee_at_record_enum) - { - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return FALSE; - } - - /* This is emitted for method functions, but I don't think we - care very much. It might help if it told us useful - information like the class with which this function is - associated, but it doesn't, so it isn't helpful. */ - } - break; - - case 'B': - if (! ieee_read_cxx_defaults (info, pp, count)) - return FALSE; - break; - - case 'z': - { - const char *name, *mangled, *cxx_class; - unsigned long namlen, mangledlen, classlen; - bfd_vma control; - - /* Pointer to member. */ - - if (! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) - || ! ieee_require_atn65 (info, pp, &cxx_class, &classlen) - || ! ieee_require_asn (info, pp, &control)) - return FALSE; - - /* FIXME: We should now track down name and change its type. */ - } - break; - - case 'R': - if (! ieee_read_reference (info, pp)) - return FALSE; - break; - } - - return TRUE; -} - -/* Read a C++ class definition. This is a pmisc type 80 record of - category 'T'. */ - -static bfd_boolean -ieee_read_cxx_class (struct ieee_info *info, const bfd_byte **pp, - unsigned long count) -{ - const bfd_byte *start; - bfd_vma cxx_class; - const char *tag; - unsigned long taglen; - struct ieee_tag *it; - void *dhandle; - debug_field *fields; - unsigned int field_count, field_alloc; - debug_baseclass *baseclasses; - unsigned int baseclasses_count, baseclasses_alloc; - const debug_field *structfields; - struct ieee_method - { - const char *name; - unsigned long namlen; - debug_method_variant *variants; - unsigned count; - unsigned int alloc; - } *methods; - unsigned int methods_count, methods_alloc; - debug_type vptrbase; - bfd_boolean ownvptr; - debug_method *dmethods; - - start = *pp; - - if (! ieee_require_asn (info, pp, &cxx_class)) - return FALSE; - --count; - - if (! ieee_require_atn65 (info, pp, &tag, &taglen)) - return FALSE; - --count; - - /* Find the C struct with this name. */ - for (it = info->tags; it != NULL; it = it->next) - if (it->name[0] == tag[0] - && strncmp (it->name, tag, taglen) == 0 - && strlen (it->name) == taglen) - break; - if (it == NULL) - { - ieee_error (info, start, _("undefined C++ object")); - return FALSE; - } - - dhandle = info->dhandle; - - fields = NULL; - field_count = 0; - field_alloc = 0; - baseclasses = NULL; - baseclasses_count = 0; - baseclasses_alloc = 0; - methods = NULL; - methods_count = 0; - methods_alloc = 0; - vptrbase = DEBUG_TYPE_NULL; - ownvptr = FALSE; - - structfields = debug_get_fields (dhandle, it->type); - - while (count > 0) - { - bfd_vma id; - const bfd_byte *spec_start; - - spec_start = *pp; - - if (! ieee_require_asn (info, pp, &id)) - return FALSE; - --count; - - switch (id) - { - default: - ieee_error (info, spec_start, _("unrecognized C++ object spec")); - return FALSE; - - case 'b': - { - bfd_vma flags, cinline; - const char *base, *fieldname; - unsigned long baselen, fieldlen; - char *basecopy; - debug_type basetype; - bfd_vma bitpos; - bfd_boolean virtualp; - enum debug_visibility visibility; - debug_baseclass baseclass; - - /* This represents a base or friend class. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &base, &baselen) - || ! ieee_require_asn (info, pp, &cinline) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) - return FALSE; - count -= 4; - - /* We have no way of recording friend information, so we - just ignore it. */ - if ((flags & BASEFLAGS_FRIEND) != 0) - break; - - /* I assume that either all of the members of the - baseclass are included in the object, starting at the - beginning of the object, or that none of them are - included. */ - - if ((fieldlen == 0) == (cinline == 0)) - { - ieee_error (info, start, _("unsupported C++ object type")); - return FALSE; - } - - basecopy = savestring (base, baselen); - basetype = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (basetype == DEBUG_TYPE_NULL) - { - ieee_error (info, start, _("C++ base class not defined")); - return FALSE; - } - - if (fieldlen == 0) - bitpos = 0; - else - { - const debug_field *pf; - - if (structfields == NULL) - { - ieee_error (info, start, _("C++ object has no fields")); - return FALSE; - } - - for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return FALSE; - if (fname[0] == fieldname[0] - && strncmp (fname, fieldname, fieldlen) == 0 - && strlen (fname) == fieldlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - _("C++ base class not found in container")); - return FALSE; - } - - bitpos = debug_get_field_bitpos (dhandle, *pf); - } - - if ((flags & BASEFLAGS_VIRTUAL) != 0) - virtualp = TRUE; - else - virtualp = FALSE; - if ((flags & BASEFLAGS_PRIVATE) != 0) - visibility = DEBUG_VISIBILITY_PRIVATE; - else - visibility = DEBUG_VISIBILITY_PUBLIC; - - baseclass = debug_make_baseclass (dhandle, basetype, bitpos, - virtualp, visibility); - if (baseclass == DEBUG_BASECLASS_NULL) - return FALSE; - - if (baseclasses_count + 1 >= baseclasses_alloc) - { - baseclasses_alloc += 10; - baseclasses = ((debug_baseclass *) - xrealloc (baseclasses, - (baseclasses_alloc - * sizeof *baseclasses))); - } - - baseclasses[baseclasses_count] = baseclass; - ++baseclasses_count; - baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL; - } - break; - - case 'd': - { - bfd_vma flags; - const char *fieldname, *mangledname; - unsigned long fieldlen, mangledlen; - char *fieldcopy; - bfd_boolean staticp; - debug_type ftype; - const debug_field *pf = NULL; - enum debug_visibility visibility; - debug_field field; - - /* This represents a data member. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen) - || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen)) - return FALSE; - count -= 3; - - fieldcopy = savestring (fieldname, fieldlen); - - staticp = (flags & CXXFLAGS_STATIC) != 0 ? TRUE : FALSE; - - if (staticp) - { - struct ieee_var *pv, *pvend; - - /* See if we can find a definition for this variable. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangledname, mangledlen) == 0) - break; - if (pv < pvend) - ftype = pv->type; - else - { - /* This can happen if the variable is never used. */ - ftype = ieee_builtin_type (info, start, - (unsigned int) builtin_void); - } - } - else - { - unsigned int findx; - - if (structfields == NULL) - { - ieee_error (info, start, _("C++ object has no fields")); - return FALSE; - } - - for (pf = structfields, findx = 0; - *pf != DEBUG_FIELD_NULL; - pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return FALSE; - if (fname[0] == mangledname[0] - && strncmp (fname, mangledname, mangledlen) == 0 - && strlen (fname) == mangledlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - _("C++ data member not found in container")); - return FALSE; - } - - ftype = debug_get_field_type (dhandle, *pf); - - if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER) - { - /* We might need to convert this field into a - reference type later on, so make it an indirect - type. */ - if (it->fslots == NULL) - { - unsigned int fcnt; - const debug_field *pfcnt; - - fcnt = 0; - for (pfcnt = structfields; - *pfcnt != DEBUG_FIELD_NULL; - pfcnt++) - ++fcnt; - it->fslots = ((debug_type *) - xmalloc (fcnt * sizeof *it->fslots)); - memset (it->fslots, 0, - fcnt * sizeof *it->fslots); - } - - if (ftype == DEBUG_TYPE_NULL) - return FALSE; - it->fslots[findx] = ftype; - ftype = debug_make_indirect_type (dhandle, - it->fslots + findx, - (const char *) NULL); - } - } - if (ftype == DEBUG_TYPE_NULL) - return FALSE; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, _("unknown C++ visibility")); - return FALSE; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - if (staticp) - { - char *mangledcopy; - - mangledcopy = savestring (mangledname, mangledlen); - - field = debug_make_static_member (dhandle, fieldcopy, - ftype, mangledcopy, - visibility); - } - else - { - bfd_vma bitpos, bitsize; - - bitpos = debug_get_field_bitpos (dhandle, *pf); - bitsize = debug_get_field_bitsize (dhandle, *pf); - if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1) - { - ieee_error (info, start, _("bad C++ field bit pos or size")); - return FALSE; - } - field = debug_make_field (dhandle, fieldcopy, ftype, bitpos, - bitsize, visibility); - } - - if (field == DEBUG_FIELD_NULL) - return FALSE; - - if (field_count + 1 >= field_alloc) - { - field_alloc += 10; - fields = ((debug_field *) - xrealloc (fields, field_alloc * sizeof *fields)); - } - - fields[field_count] = field; - ++field_count; - fields[field_count] = DEBUG_FIELD_NULL; - } - break; - - case 'm': - case 'v': - { - bfd_vma flags, voffset, control; - const char *name, *mangled; - unsigned long namlen, mangledlen; - struct ieee_var *pv, *pvend; - debug_type type; - enum debug_visibility visibility; - bfd_boolean constp, volatilep; - char *mangledcopy; - debug_method_variant mv; - struct ieee_method *meth; - unsigned int im; - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return FALSE; - count -= 3; - if (id != 'v') - voffset = 0; - else - { - if (! ieee_require_asn (info, pp, &voffset)) - return FALSE; - --count; - } - if (! ieee_require_asn (info, pp, &control)) - return FALSE; - --count; - - /* We just ignore the control information. */ - - /* We have no way to represent friend information, so we - just ignore it. */ - if ((flags & CXXFLAGS_FRIEND) != 0) - break; - - /* We should already have seen a type for the function. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangled, mangledlen) == 0) - break; - - if (pv >= pvend) - { - /* We won't have type information for this function if - it is not included in this file. We don't try to - handle this case. FIXME. */ - type = (debug_make_function_type - (dhandle, - ieee_builtin_type (info, start, - (unsigned int) builtin_void), - (debug_type *) NULL, - FALSE)); - } - else - { - debug_type return_type; - const debug_type *arg_types; - bfd_boolean varargs; - - if (debug_get_type_kind (dhandle, pv->type) - != DEBUG_KIND_FUNCTION) - { - ieee_error (info, start, - _("bad type for C++ method function")); - return FALSE; - } - - return_type = debug_get_return_type (dhandle, pv->type); - arg_types = debug_get_parameter_types (dhandle, pv->type, - &varargs); - if (return_type == DEBUG_TYPE_NULL || arg_types == NULL) - { - ieee_error (info, start, - _("no type information for C++ method function")); - return FALSE; - } - - type = debug_make_method_type (dhandle, return_type, it->type, - (debug_type *) arg_types, - varargs); - } - if (type == DEBUG_TYPE_NULL) - return FALSE; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, _("unknown C++ visibility")); - return FALSE; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - constp = (flags & CXXFLAGS_CONST) != 0 ? TRUE : FALSE; - volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? TRUE : FALSE; - - mangledcopy = savestring (mangled, mangledlen); - - if ((flags & CXXFLAGS_STATIC) != 0) - { - if (id == 'v') - { - ieee_error (info, start, _("C++ static virtual method")); - return FALSE; - } - mv = debug_make_static_method_variant (dhandle, mangledcopy, - type, visibility, - constp, volatilep); - } - else - { - debug_type vcontext; - - if (id != 'v') - vcontext = DEBUG_TYPE_NULL; - else - { - /* FIXME: How can we calculate this correctly? */ - vcontext = it->type; - } - mv = debug_make_method_variant (dhandle, mangledcopy, type, - visibility, constp, - volatilep, voffset, - vcontext); - } - if (mv == DEBUG_METHOD_VARIANT_NULL) - return FALSE; - - for (meth = methods, im = 0; im < methods_count; meth++, im++) - if (meth->namlen == namlen - && strncmp (meth->name, name, namlen) == 0) - break; - if (im >= methods_count) - { - if (methods_count >= methods_alloc) - { - methods_alloc += 10; - methods = ((struct ieee_method *) - xrealloc (methods, - methods_alloc * sizeof *methods)); - } - methods[methods_count].name = name; - methods[methods_count].namlen = namlen; - methods[methods_count].variants = NULL; - methods[methods_count].count = 0; - methods[methods_count].alloc = 0; - meth = methods + methods_count; - ++methods_count; - } - - if (meth->count + 1 >= meth->alloc) - { - meth->alloc += 10; - meth->variants = ((debug_method_variant *) - xrealloc (meth->variants, - (meth->alloc - * sizeof *meth->variants))); - } - - meth->variants[meth->count] = mv; - ++meth->count; - meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL; - } - break; - - case 'o': - { - bfd_vma spec; - - /* We have no way to store this information, so we just - ignore it. */ - if (! ieee_require_asn (info, pp, &spec)) - return FALSE; - --count; - if ((spec & 4) != 0) - { - const char *filename; - unsigned long filenamlen; - bfd_vma lineno; - - if (! ieee_require_atn65 (info, pp, &filename, &filenamlen) - || ! ieee_require_asn (info, pp, &lineno)) - return FALSE; - count -= 2; - } - else if ((spec & 8) != 0) - { - const char *mangled; - unsigned long mangledlen; - - if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return FALSE; - --count; - } - else - { - ieee_error (info, start, - _("unrecognized C++ object overhead spec")); - return FALSE; - } - } - break; - - case 'z': - { - const char *vname, *base; - unsigned long vnamelen, baselen; - bfd_vma vsize, control; - - /* A virtual table pointer. */ - - if (! ieee_require_atn65 (info, pp, &vname, &vnamelen) - || ! ieee_require_asn (info, pp, &vsize) - || ! ieee_require_atn65 (info, pp, &base, &baselen) - || ! ieee_require_asn (info, pp, &control)) - return FALSE; - count -= 4; - - /* We just ignore the control number. We don't care what - the virtual table name is. We have no way to store the - virtual table size, and I don't think we care anyhow. */ - - /* FIXME: We can't handle multiple virtual table pointers. */ - - if (baselen == 0) - ownvptr = TRUE; - else - { - char *basecopy; - - basecopy = savestring (base, baselen); - vptrbase = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (vptrbase == DEBUG_TYPE_NULL) - { - ieee_error (info, start, _("undefined C++ vtable")); - return FALSE; - } - } - } - break; - } - } - - /* Now that we have seen all the method variants, we can call - debug_make_method for each one. */ - - if (methods_count == 0) - dmethods = NULL; - else - { - unsigned int i; - - dmethods = ((debug_method *) - xmalloc ((methods_count + 1) * sizeof *dmethods)); - for (i = 0; i < methods_count; i++) - { - char *namcopy; - - namcopy = savestring (methods[i].name, methods[i].namlen); - dmethods[i] = debug_make_method (dhandle, namcopy, - methods[i].variants); - if (dmethods[i] == DEBUG_METHOD_NULL) - return FALSE; - } - dmethods[i] = DEBUG_METHOD_NULL; - free (methods); - } - - /* The struct type was created as an indirect type pointing at - it->slot. We update it->slot to automatically update all - references to this struct. */ - it->slot = debug_make_object_type (dhandle, - cxx_class != 'u', - debug_get_type_size (dhandle, - it->slot), - fields, baseclasses, dmethods, - vptrbase, ownvptr); - if (it->slot == DEBUG_TYPE_NULL) - return FALSE; - - return TRUE; -} - -/* Read C++ default argument value and reference type information. */ - -static bfd_boolean -ieee_read_cxx_defaults (struct ieee_info *info, const bfd_byte **pp, - unsigned long count) -{ - const bfd_byte *start; - const char *fnname; - unsigned long fnlen; - bfd_vma defcount; - - start = *pp; - - /* Giving the function name before the argument count is an addendum - to the spec. The function name is demangled, though, so this - record must always refer to the current function. */ - - if (info->blockstack.bsp <= info->blockstack.stack - || info->blockstack.bsp[-1].fnindx == (unsigned int) -1) - { - ieee_error (info, start, _("C++ default values not in a function")); - return FALSE; - } - - if (! ieee_require_atn65 (info, pp, &fnname, &fnlen) - || ! ieee_require_asn (info, pp, &defcount)) - return FALSE; - count -= 2; - - while (defcount-- > 0) - { - bfd_vma type, val; - const char *strval; - unsigned long strvallen; - - if (! ieee_require_asn (info, pp, &type)) - return FALSE; - --count; - - switch (type) - { - case 0: - case 4: - break; - - case 1: - case 2: - if (! ieee_require_asn (info, pp, &val)) - return FALSE; - --count; - break; - - case 3: - case 7: - if (! ieee_require_atn65 (info, pp, &strval, &strvallen)) - return FALSE; - --count; - break; - - default: - ieee_error (info, start, _("unrecognized C++ default type")); - return FALSE; - } - - /* We have no way to record the default argument values, so we - just ignore them. FIXME. */ - } - - /* Any remaining arguments are indices of parameters that are really - reference type. */ - if (count > 0) - { - void *dhandle; - debug_type *arg_slots; - - dhandle = info->dhandle; - arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots; - while (count-- > 0) - { - bfd_vma indx; - debug_type target; - - if (! ieee_require_asn (info, pp, &indx)) - return FALSE; - /* The index is 1 based. */ - --indx; - if (arg_slots == NULL - || arg_slots[indx] == DEBUG_TYPE_NULL - || (debug_get_type_kind (dhandle, arg_slots[indx]) - != DEBUG_KIND_POINTER)) - { - ieee_error (info, start, _("reference parameter is not a pointer")); - return FALSE; - } - - target = debug_get_target_type (dhandle, arg_slots[indx]); - arg_slots[indx] = debug_make_reference_type (dhandle, target); - if (arg_slots[indx] == DEBUG_TYPE_NULL) - return FALSE; - } - } - - return TRUE; -} - -/* Read a C++ reference definition. */ - -static bfd_boolean -ieee_read_reference (struct ieee_info *info, const bfd_byte **pp) -{ - const bfd_byte *start; - bfd_vma flags; - const char *cxx_class, *name; - unsigned long classlen, namlen; - debug_type *pslot; - debug_type target; - - start = *pp; - - if (! ieee_require_asn (info, pp, &flags)) - return FALSE; - - /* Giving the class name before the member name is in an addendum to - the spec. */ - if (flags == 3) - { - if (! ieee_require_atn65 (info, pp, &cxx_class, &classlen)) - return FALSE; - } - - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return FALSE; - - pslot = NULL; - if (flags != 3) - { - int pass; - - /* We search from the last variable indices to the first in - hopes of finding local variables correctly. We search the - local variables on the first pass, and the global variables - on the second. FIXME: This probably won't work in all cases. - On the other hand, I don't know what will. */ - for (pass = 0; pass < 2; pass++) - { - struct ieee_vars *vars; - int i; - struct ieee_var *pv = NULL; - - if (pass == 0) - vars = &info->vars; - else - { - vars = info->global_vars; - if (vars == NULL) - break; - } - - for (i = (int) vars->alloc - 1; i >= 0; i--) - { - bfd_boolean found; - - pv = vars->vars + i; - - if (pv->pslot == NULL - || pv->namlen != namlen - || strncmp (pv->name, name, namlen) != 0) - continue; - - found = FALSE; - switch (flags) - { - default: - ieee_error (info, start, - _("unrecognized C++ reference type")); - return FALSE; - - case 0: - /* Global variable or function. */ - if (pv->kind == IEEE_GLOBAL - || pv->kind == IEEE_EXTERNAL - || pv->kind == IEEE_FUNCTION) - found = TRUE; - break; - - case 1: - /* Global static variable or function. */ - if (pv->kind == IEEE_STATIC - || pv->kind == IEEE_FUNCTION) - found = TRUE; - break; - - case 2: - /* Local variable. */ - if (pv->kind == IEEE_LOCAL) - found = TRUE; - break; - } - - if (found) - break; - } - - if (i >= 0) - { - pslot = pv->pslot; - break; - } - } - } - else - { - struct ieee_tag *it; - - for (it = info->tags; it != NULL; it = it->next) - { - if (it->name[0] == cxx_class[0] - && strncmp (it->name, cxx_class, classlen) == 0 - && strlen (it->name) == classlen) - { - if (it->fslots != NULL) - { - const debug_field *pf; - unsigned int findx; - - pf = debug_get_fields (info->dhandle, it->type); - if (pf == NULL) - { - ieee_error (info, start, - "C++ reference in class with no fields"); - return FALSE; - } - - for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (info->dhandle, *pf); - if (fname == NULL) - return FALSE; - if (strncmp (fname, name, namlen) == 0 - && strlen (fname) == namlen) - { - pslot = it->fslots + findx; - break; - } - } - } - - break; - } - } - } - - if (pslot == NULL) - { - ieee_error (info, start, _("C++ reference not found")); - return FALSE; - } - - /* We allocated the type of the object as an indirect type pointing - to *pslot, which we can now update to be a reference type. */ - if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER) - { - ieee_error (info, start, _("C++ reference is not pointer")); - return FALSE; - } - - target = debug_get_target_type (info->dhandle, *pslot); - *pslot = debug_make_reference_type (info->dhandle, target); - if (*pslot == DEBUG_TYPE_NULL) - return FALSE; - - return TRUE; -} - -/* Require an ASN record. */ - -static bfd_boolean -ieee_require_asn (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv) -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma varindx; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_e2_first_byte_enum) - { - ieee_error (info, start, _("missing required ASN")); - return FALSE; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_asn_record_enum) - { - ieee_error (info, start, _("missing required ASN")); - return FALSE; - } - ++*pp; - - /* Just ignore the variable index. */ - if (! ieee_read_number (info, pp, &varindx)) - return FALSE; - - return ieee_read_expression (info, pp, pv); -} - -/* Require an ATN65 record. */ - -static bfd_boolean -ieee_require_atn65 (struct ieee_info *info, const bfd_byte **pp, - const char **pname, unsigned long *pnamlen) -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma name_indx, type_indx, atn_code; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_at_record_enum) - { - ieee_error (info, start, _("missing required ATN65")); - return FALSE; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_atn_record_enum) - { - ieee_error (info, start, _("missing required ATN65")); - return FALSE; - } - ++*pp; - - if (! ieee_read_number (info, pp, &name_indx) - || ! ieee_read_number (info, pp, &type_indx) - || ! ieee_read_number (info, pp, &atn_code)) - return FALSE; - - /* Just ignore name_indx. */ - - if (type_indx != 0 || atn_code != 65) - { - ieee_error (info, start, _("bad ATN65 record")); - return FALSE; - } - - return ieee_read_id (info, pp, pname, pnamlen); -} - -/* Convert a register number in IEEE debugging information into a - generic register number. */ - -static int -ieee_regno_to_genreg (bfd *abfd, int r) -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reasons stabs adds 2 to the floating point register - numbers. */ - if (r >= 16) - r += 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - --r; - break; - - default: - break; - } - - return r; -} - -/* Convert a generic register number to an IEEE specific one. */ - -static int -ieee_genreg_to_regno (bfd *abfd, int r) -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reason stabs add 2 to the floating point register - numbers. */ - if (r >= 18) - r -= 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - ++r; - break; - - default: - break; - } - - return r; -} - -/* These routines build IEEE debugging information out of the generic - debugging information. */ - -/* We build the IEEE debugging information byte by byte. Rather than - waste time copying data around, we use a linked list of buffers to - hold the data. */ - -#define IEEE_BUFSIZE (490) - -struct ieee_buf -{ - /* Next buffer. */ - struct ieee_buf *next; - /* Number of data bytes in this buffer. */ - unsigned int c; - /* Bytes. */ - bfd_byte buf[IEEE_BUFSIZE]; -}; - -/* A list of buffers. */ - -struct ieee_buflist -{ - /* Head of list. */ - struct ieee_buf *head; - /* Tail--last buffer on list. */ - struct ieee_buf *tail; -}; - -/* In order to generate the BB11 blocks required by the HP emulator, - we keep track of ranges of addresses which correspond to a given - compilation unit. */ - -struct ieee_range -{ - /* Next range. */ - struct ieee_range *next; - /* Low address. */ - bfd_vma low; - /* High address. */ - bfd_vma high; -}; - -/* This structure holds information for a class on the type stack. */ - -struct ieee_type_class -{ - /* The name index in the debugging information. */ - unsigned int indx; - /* The pmisc records for the class. */ - struct ieee_buflist pmiscbuf; - /* The number of pmisc records. */ - unsigned int pmisccount; - /* The name of the class holding the virtual table, if not this - class. */ - const char *vclass; - /* Whether this class holds its own virtual table. */ - bfd_boolean ownvptr; - /* The largest virtual table offset seen so far. */ - bfd_vma voffset; - /* The current method. */ - const char *method; - /* Additional pmisc records used to record fields of reference type. */ - struct ieee_buflist refs; -}; - -/* This is how we store types for the writing routines. Most types - are simply represented by a type index. */ - -struct ieee_write_type -{ - /* Type index. */ - unsigned int indx; - /* The size of the type, if known. */ - unsigned int size; - /* The name of the type, if any. */ - const char *name; - /* If this is a function or method type, we build the type here, and - only add it to the output buffers if we need it. */ - struct ieee_buflist fndef; - /* If this is a struct, this is where the struct definition is - built. */ - struct ieee_buflist strdef; - /* If this is a class, this is where the class information is built. */ - struct ieee_type_class *classdef; - /* Whether the type is unsigned. */ - unsigned int unsignedp : 1; - /* Whether this is a reference type. */ - unsigned int referencep : 1; - /* Whether this is in the local type block. */ - unsigned int localp : 1; - /* Whether this is a duplicate struct definition which we are - ignoring. */ - unsigned int ignorep : 1; -}; - -/* This is the type stack used by the debug writing routines. FIXME: - We could generate more efficient output if we remembered when we - have output a particular type before. */ - -struct ieee_type_stack -{ - /* Next entry on stack. */ - struct ieee_type_stack *next; - /* Type information. */ - struct ieee_write_type type; -}; - -/* This is a list of associations between a name and some types. - These are used for typedefs and tags. */ - -struct ieee_name_type -{ - /* Next type for this name. */ - struct ieee_name_type *next; - /* ID number. For a typedef, this is the index of the type to which - this name is typedefed. */ - unsigned int id; - /* Type. */ - struct ieee_write_type type; - /* If this is a tag which has not yet been defined, this is the - kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */ - enum debug_type_kind kind; -}; - -/* We use a hash table to associate names and types. */ - -struct ieee_name_type_hash_table -{ - struct bfd_hash_table root; -}; - -struct ieee_name_type_hash_entry -{ - struct bfd_hash_entry root; - /* Information for this name. */ - struct ieee_name_type *types; -}; - -/* This is a list of enums. */ - -struct ieee_defined_enum -{ - /* Next enum. */ - struct ieee_defined_enum *next; - /* Type index. */ - unsigned int indx; - /* Whether this enum has been defined. */ - bfd_boolean defined; - /* Tag. */ - const char *tag; - /* Names. */ - const char **names; - /* Values. */ - bfd_signed_vma *vals; -}; - -/* We keep a list of modified versions of types, so that we don't - output them more than once. */ - -struct ieee_modified_type -{ - /* Pointer to this type. */ - unsigned int pointer; - /* Function with unknown arguments returning this type. */ - unsigned int function; - /* Const version of this type. */ - unsigned int const_qualified; - /* Volatile version of this type. */ - unsigned int volatile_qualified; - /* List of arrays of this type of various bounds. */ - struct ieee_modified_array_type *arrays; -}; - -/* A list of arrays bounds. */ - -struct ieee_modified_array_type -{ - /* Next array bounds. */ - struct ieee_modified_array_type *next; - /* Type index with these bounds. */ - unsigned int indx; - /* Low bound. */ - bfd_signed_vma low; - /* High bound. */ - bfd_signed_vma high; -}; - -/* This is a list of pending function parameter information. We don't - output them until we see the first block. */ - -struct ieee_pending_parm -{ - /* Next pending parameter. */ - struct ieee_pending_parm *next; - /* Name. */ - const char *name; - /* Type index. */ - unsigned int type; - /* Whether the type is a reference. */ - bfd_boolean referencep; - /* Kind. */ - enum debug_parm_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* This is the handle passed down by debug_write. */ - -struct ieee_handle -{ - /* BFD we are writing to. */ - bfd *abfd; - /* Whether we got an error in a subroutine called via traverse or - map_over_sections. */ - bfd_boolean error; - /* Current data buffer list. */ - struct ieee_buflist *current; - /* Current data buffer. */ - struct ieee_buf *curbuf; - /* Filename of current compilation unit. */ - const char *filename; - /* Module name of current compilation unit. */ - const char *modname; - /* List of buffer for global types. */ - struct ieee_buflist global_types; - /* List of finished data buffers. */ - struct ieee_buflist data; - /* List of buffers for typedefs in the current compilation unit. */ - struct ieee_buflist types; - /* List of buffers for variables and functions in the current - compilation unit. */ - struct ieee_buflist vars; - /* List of buffers for C++ class definitions in the current - compilation unit. */ - struct ieee_buflist cxx; - /* List of buffers for line numbers in the current compilation unit. */ - struct ieee_buflist linenos; - /* Ranges for the current compilation unit. */ - struct ieee_range *ranges; - /* Ranges for all debugging information. */ - struct ieee_range *global_ranges; - /* Nested pending ranges. */ - struct ieee_range *pending_ranges; - /* Type stack. */ - struct ieee_type_stack *type_stack; - /* Next unallocated type index. */ - unsigned int type_indx; - /* Next unallocated name index. */ - unsigned int name_indx; - /* Typedefs. */ - struct ieee_name_type_hash_table typedefs; - /* Tags. */ - struct ieee_name_type_hash_table tags; - /* Enums. */ - struct ieee_defined_enum *enums; - /* Modified versions of types. */ - struct ieee_modified_type *modified; - /* Number of entries allocated in modified. */ - unsigned int modified_alloc; - /* 4 byte complex type. */ - unsigned int complex_float_index; - /* 8 byte complex type. */ - unsigned int complex_double_index; - /* The depth of block nesting. This is 0 outside a function, and 1 - just after start_function is called. */ - unsigned int block_depth; - /* The name of the current function. */ - const char *fnname; - /* List of buffers for the type of the function we are currently - writing out. */ - struct ieee_buflist fntype; - /* List of buffers for the parameters of the function we are - currently writing out. */ - struct ieee_buflist fnargs; - /* Number of arguments written to fnargs. */ - unsigned int fnargcount; - /* Pending function parameters. */ - struct ieee_pending_parm *pending_parms; - /* Current line number filename. */ - const char *lineno_filename; - /* Line number name index. */ - unsigned int lineno_name_indx; - /* Filename of pending line number. */ - const char *pending_lineno_filename; - /* Pending line number. */ - unsigned long pending_lineno; - /* Address of pending line number. */ - bfd_vma pending_lineno_addr; - /* Highest address seen at end of procedure. */ - bfd_vma highaddr; -}; - -static bfd_boolean ieee_init_buffer - (struct ieee_handle *, struct ieee_buflist *); -static bfd_boolean ieee_change_buffer - (struct ieee_handle *, struct ieee_buflist *); -static bfd_boolean ieee_append_buffer - (struct ieee_handle *, struct ieee_buflist *, struct ieee_buflist *); -static bfd_boolean ieee_real_write_byte (struct ieee_handle *, int); -static bfd_boolean ieee_write_2bytes (struct ieee_handle *, int); -static bfd_boolean ieee_write_number (struct ieee_handle *, bfd_vma); -static bfd_boolean ieee_write_id (struct ieee_handle *, const char *); -static bfd_boolean ieee_write_asn - (struct ieee_handle *, unsigned int, bfd_vma); -static bfd_boolean ieee_write_atn65 - (struct ieee_handle *, unsigned int, const char *); -static bfd_boolean ieee_push_type - (struct ieee_handle *, unsigned int, unsigned int, bfd_boolean, - bfd_boolean); -static unsigned int ieee_pop_type (struct ieee_handle *); -static void ieee_pop_unused_type (struct ieee_handle *); -static unsigned int ieee_pop_type_used (struct ieee_handle *, bfd_boolean); -static bfd_boolean ieee_add_range - (struct ieee_handle *, bfd_boolean, bfd_vma, bfd_vma); -static bfd_boolean ieee_start_range (struct ieee_handle *, bfd_vma); -static bfd_boolean ieee_end_range (struct ieee_handle *, bfd_vma); -static bfd_boolean ieee_define_type - (struct ieee_handle *, unsigned int, bfd_boolean, bfd_boolean); -static bfd_boolean ieee_define_named_type - (struct ieee_handle *, const char *, unsigned int, unsigned int, - bfd_boolean, bfd_boolean, struct ieee_buflist *); -static struct ieee_modified_type *ieee_get_modified_info - (struct ieee_handle *, unsigned int); -static struct bfd_hash_entry *ieee_name_type_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -static bfd_boolean ieee_write_undefined_tag - (struct ieee_name_type_hash_entry *, void *); -static bfd_boolean ieee_finish_compilation_unit (struct ieee_handle *); -static void ieee_add_bb11_blocks (bfd *, asection *, void *); -static bfd_boolean ieee_add_bb11 - (struct ieee_handle *, asection *, bfd_vma, bfd_vma); -static bfd_boolean ieee_output_pending_parms (struct ieee_handle *); -static unsigned int ieee_vis_to_flags (enum debug_visibility); -static bfd_boolean ieee_class_method_var - (struct ieee_handle *, const char *, enum debug_visibility, bfd_boolean, - bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean); - -static bfd_boolean ieee_start_compilation_unit (void *, const char *); -static bfd_boolean ieee_start_source (void *, const char *); -static bfd_boolean ieee_empty_type (void *); -static bfd_boolean ieee_void_type (void *); -static bfd_boolean ieee_int_type (void *, unsigned int, bfd_boolean); -static bfd_boolean ieee_float_type (void *, unsigned int); -static bfd_boolean ieee_complex_type (void *, unsigned int); -static bfd_boolean ieee_bool_type (void *, unsigned int); -static bfd_boolean ieee_enum_type - (void *, const char *, const char **, bfd_signed_vma *); -static bfd_boolean ieee_pointer_type (void *); -static bfd_boolean ieee_function_type (void *, int, bfd_boolean); -static bfd_boolean ieee_reference_type (void *); -static bfd_boolean ieee_range_type (void *, bfd_signed_vma, bfd_signed_vma); -static bfd_boolean ieee_array_type - (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); -static bfd_boolean ieee_set_type (void *, bfd_boolean); -static bfd_boolean ieee_offset_type (void *); -static bfd_boolean ieee_method_type (void *, bfd_boolean, int, bfd_boolean); -static bfd_boolean ieee_const_type (void *); -static bfd_boolean ieee_volatile_type (void *); -static bfd_boolean ieee_start_struct_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int); -static bfd_boolean ieee_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean ieee_end_struct_type (void *); -static bfd_boolean ieee_start_class_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, - bfd_boolean); -static bfd_boolean ieee_class_static_member - (void *, const char *, const char *, enum debug_visibility); -static bfd_boolean ieee_class_baseclass - (void *, bfd_vma, bfd_boolean, enum debug_visibility); -static bfd_boolean ieee_class_start_method (void *, const char *); -static bfd_boolean ieee_class_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, - bfd_vma, bfd_boolean); -static bfd_boolean ieee_class_static_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); -static bfd_boolean ieee_class_end_method (void *); -static bfd_boolean ieee_end_class_type (void *); -static bfd_boolean ieee_typedef_type (void *, const char *); -static bfd_boolean ieee_tag_type - (void *, const char *, unsigned int, enum debug_type_kind); -static bfd_boolean ieee_typdef (void *, const char *); -static bfd_boolean ieee_tag (void *, const char *); -static bfd_boolean ieee_int_constant (void *, const char *, bfd_vma); -static bfd_boolean ieee_float_constant (void *, const char *, double); -static bfd_boolean ieee_typed_constant (void *, const char *, bfd_vma); -static bfd_boolean ieee_variable - (void *, const char *, enum debug_var_kind, bfd_vma); -static bfd_boolean ieee_start_function (void *, const char *, bfd_boolean); -static bfd_boolean ieee_function_parameter - (void *, const char *, enum debug_parm_kind, bfd_vma); -static bfd_boolean ieee_start_block (void *, bfd_vma); -static bfd_boolean ieee_end_block (void *, bfd_vma); -static bfd_boolean ieee_end_function (void *); -static bfd_boolean ieee_lineno (void *, const char *, unsigned long, bfd_vma); - -static const struct debug_write_fns ieee_fns = -{ - ieee_start_compilation_unit, - ieee_start_source, - ieee_empty_type, - ieee_void_type, - ieee_int_type, - ieee_float_type, - ieee_complex_type, - ieee_bool_type, - ieee_enum_type, - ieee_pointer_type, - ieee_function_type, - ieee_reference_type, - ieee_range_type, - ieee_array_type, - ieee_set_type, - ieee_offset_type, - ieee_method_type, - ieee_const_type, - ieee_volatile_type, - ieee_start_struct_type, - ieee_struct_field, - ieee_end_struct_type, - ieee_start_class_type, - ieee_class_static_member, - ieee_class_baseclass, - ieee_class_start_method, - ieee_class_method_variant, - ieee_class_static_method_variant, - ieee_class_end_method, - ieee_end_class_type, - ieee_typedef_type, - ieee_tag_type, - ieee_typdef, - ieee_tag, - ieee_int_constant, - ieee_float_constant, - ieee_typed_constant, - ieee_variable, - ieee_start_function, - ieee_function_parameter, - ieee_start_block, - ieee_end_block, - ieee_end_function, - ieee_lineno -}; - -/* Initialize a buffer to be empty. */ - -static bfd_boolean -ieee_init_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED, - struct ieee_buflist *buflist) -{ - buflist->head = NULL; - buflist->tail = NULL; - return TRUE; -} - -/* See whether a buffer list has any data. */ - -#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL) - -/* Change the current buffer to a specified buffer chain. */ - -static bfd_boolean -ieee_change_buffer (struct ieee_handle *info, struct ieee_buflist *buflist) -{ - if (buflist->head == NULL) - { - struct ieee_buf *buf; - - buf = (struct ieee_buf *) xmalloc (sizeof *buf); - buf->next = NULL; - buf->c = 0; - buflist->head = buf; - buflist->tail = buf; - } - - info->current = buflist; - info->curbuf = buflist->tail; - - return TRUE; -} - -/* Append a buffer chain. */ - -static bfd_boolean -ieee_append_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED, - struct ieee_buflist *mainbuf, - struct ieee_buflist *newbuf) -{ - if (newbuf->head != NULL) - { - if (mainbuf->head == NULL) - mainbuf->head = newbuf->head; - else - mainbuf->tail->next = newbuf->head; - mainbuf->tail = newbuf->tail; - } - return TRUE; -} - -/* Write a byte into the buffer. We use a macro for speed and a - function for the complex cases. */ - -#define ieee_write_byte(info, b) \ - ((info)->curbuf->c < IEEE_BUFSIZE \ - ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), TRUE) \ - : ieee_real_write_byte ((info), (b))) - -static bfd_boolean -ieee_real_write_byte (struct ieee_handle *info, int b) -{ - if (info->curbuf->c >= IEEE_BUFSIZE) - { - struct ieee_buf *n; - - n = (struct ieee_buf *) xmalloc (sizeof *n); - n->next = NULL; - n->c = 0; - if (info->current->head == NULL) - info->current->head = n; - else - info->current->tail->next = n; - info->current->tail = n; - info->curbuf = n; - } - - info->curbuf->buf[info->curbuf->c] = b; - ++info->curbuf->c; - - return TRUE; -} - -/* Write out two bytes. */ - -static bfd_boolean -ieee_write_2bytes (struct ieee_handle *info, int i) -{ - return (ieee_write_byte (info, i >> 8) - && ieee_write_byte (info, i & 0xff)); -} - -/* Write out an integer. */ - -static bfd_boolean -ieee_write_number (struct ieee_handle *info, bfd_vma v) -{ - bfd_vma t; - bfd_byte ab[20]; - bfd_byte *p; - unsigned int c; - - if (v <= (bfd_vma) ieee_number_end_enum) - return ieee_write_byte (info, (int) v); - - t = v; - p = ab + sizeof ab; - while (t != 0) - { - *--p = t & 0xff; - t >>= 8; - } - c = (ab + 20) - p; - - if (c > (unsigned int) (ieee_number_repeat_end_enum - - ieee_number_repeat_start_enum)) - { - fprintf (stderr, _("IEEE numeric overflow: 0x")); - fprintf_vma (stderr, v); - fprintf (stderr, "\n"); - return FALSE; - } - - if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c)) - return FALSE; - for (; c > 0; --c, ++p) - { - if (! ieee_write_byte (info, *p)) - return FALSE; - } - - return TRUE; -} - -/* Write out a string. */ - -static bfd_boolean -ieee_write_id (struct ieee_handle *info, const char *s) -{ - unsigned int len; - - len = strlen (s); - if (len <= 0x7f) - { - if (! ieee_write_byte (info, len)) - return FALSE; - } - else if (len <= 0xff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum) - || ! ieee_write_byte (info, len)) - return FALSE; - } - else if (len <= 0xffff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum) - || ! ieee_write_2bytes (info, len)) - return FALSE; - } - else - { - fprintf (stderr, _("IEEE string length overflow: %u\n"), len); - return FALSE; - } - - for (; *s != '\0'; s++) - if (! ieee_write_byte (info, *s)) - return FALSE; - - return TRUE; -} - -/* Write out an ASN record. */ - -static bfd_boolean -ieee_write_asn (struct ieee_handle *info, unsigned int indx, bfd_vma val) -{ - return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, val)); -} - -/* Write out an ATN65 record. */ - -static bfd_boolean -ieee_write_atn65 (struct ieee_handle *info, unsigned int indx, const char *s) -{ - return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, 0) - && ieee_write_number (info, 65) - && ieee_write_id (info, s)); -} - -/* Push a type index onto the type stack. */ - -static bfd_boolean -ieee_push_type (struct ieee_handle *info, unsigned int indx, - unsigned int size, bfd_boolean unsignedp, bfd_boolean localp) -{ - struct ieee_type_stack *ts; - - ts = (struct ieee_type_stack *) xmalloc (sizeof *ts); - memset (ts, 0, sizeof *ts); - - ts->type.indx = indx; - ts->type.size = size; - ts->type.unsignedp = unsignedp; - ts->type.localp = localp; - - ts->next = info->type_stack; - info->type_stack = ts; - - return TRUE; -} - -/* Pop a type index off the type stack. */ - -static unsigned int -ieee_pop_type (struct ieee_handle *info) -{ - return ieee_pop_type_used (info, TRUE); -} - -/* Pop an unused type index off the type stack. */ - -static void -ieee_pop_unused_type (struct ieee_handle *info) -{ - (void) ieee_pop_type_used (info, FALSE); -} - -/* Pop a used or unused type index off the type stack. */ - -static unsigned int -ieee_pop_type_used (struct ieee_handle *info, bfd_boolean used) -{ - struct ieee_type_stack *ts; - unsigned int ret; - - ts = info->type_stack; - assert (ts != NULL); - - /* If this is a function type, and we need it, we need to append the - actual definition to the typedef block now. */ - if (used && ! ieee_buffer_emptyp (&ts->type.fndef)) - { - struct ieee_buflist *buflist; - - if (ts->type.localp) - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - } - buflist = &info->types; - } - else - { - /* Make sure we started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return FALSE; - } - buflist = &info->global_types; - } - - if (! ieee_append_buffer (info, buflist, &ts->type.fndef)) - return FALSE; - } - - ret = ts->type.indx; - info->type_stack = ts->next; - free (ts); - return ret; -} - -/* Add a range of bytes included in the current compilation unit. */ - -static bfd_boolean -ieee_add_range (struct ieee_handle *info, bfd_boolean global, bfd_vma low, - bfd_vma high) -{ - struct ieee_range **plist, *r, **pr; - - if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high) - return TRUE; - - if (global) - plist = &info->global_ranges; - else - plist = &info->ranges; - - for (r = *plist; r != NULL; r = r->next) - { - if (high >= r->low && low <= r->high) - { - /* The new range overlaps r. */ - if (low < r->low) - r->low = low; - if (high > r->high) - r->high = high; - pr = &r->next; - while (*pr != NULL && (*pr)->low <= r->high) - { - struct ieee_range *n; - - if ((*pr)->high > r->high) - r->high = (*pr)->high; - n = (*pr)->next; - free (*pr); - *pr = n; - } - return TRUE; - } - } - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->low = low; - r->high = high; - - /* Store the ranges sorted by address. */ - for (pr = plist; *pr != NULL; pr = &(*pr)->next) - if ((*pr)->low > high) - break; - r->next = *pr; - *pr = r; - - return TRUE; -} - -/* Start a new range for which we only have the low address. */ - -static bfd_boolean -ieee_start_range (struct ieee_handle *info, bfd_vma low) -{ - struct ieee_range *r; - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - r->low = low; - r->next = info->pending_ranges; - info->pending_ranges = r; - return TRUE; -} - -/* Finish a range started by ieee_start_range. */ - -static bfd_boolean -ieee_end_range (struct ieee_handle *info, bfd_vma high) -{ - struct ieee_range *r; - bfd_vma low; - - assert (info->pending_ranges != NULL); - r = info->pending_ranges; - low = r->low; - info->pending_ranges = r->next; - free (r); - return ieee_add_range (info, FALSE, low, high); -} - -/* Start defining a type. */ - -static bfd_boolean -ieee_define_type (struct ieee_handle *info, unsigned int size, - bfd_boolean unsignedp, bfd_boolean localp) -{ - return ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, size, unsignedp, - localp, (struct ieee_buflist *) NULL); -} - -/* Start defining a named type. */ - -static bfd_boolean -ieee_define_named_type (struct ieee_handle *info, const char *name, - unsigned int indx, unsigned int size, - bfd_boolean unsignedp, bfd_boolean localp, - struct ieee_buflist *buflist) -{ - unsigned int type_indx; - unsigned int name_indx; - - if (indx != (unsigned int) -1) - type_indx = indx; - else - { - type_indx = info->type_indx; - ++info->type_indx; - } - - name_indx = info->name_indx; - ++info->name_indx; - - if (name == NULL) - name = ""; - - /* If we were given a buffer, use it; otherwise, use either the - local or the global type information, and make sure that the type - block is started. */ - if (buflist != NULL) - { - if (! ieee_change_buffer (info, buflist)) - return FALSE; - } - else if (localp) - { - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types)) - return FALSE; - } - else - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - } - } - else - { - if (! ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types)) - return FALSE; - } - else - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return FALSE; - } - } - - /* Push the new type on the type stack, write out an NN record, and - write out the start of a TY record. The caller will then finish - the TY record. */ - if (! ieee_push_type (info, type_indx, size, unsignedp, localp)) - return FALSE; - - return (ieee_write_byte (info, (int) ieee_nn_record) - && ieee_write_number (info, name_indx) - && ieee_write_id (info, name) - && ieee_write_byte (info, (int) ieee_ty_record_enum) - && ieee_write_number (info, type_indx) - && ieee_write_byte (info, 0xce) - && ieee_write_number (info, name_indx)); -} - -/* Get an entry to the list of modified versions of a type. */ - -static struct ieee_modified_type * -ieee_get_modified_info (struct ieee_handle *info, unsigned int indx) -{ - if (indx >= info->modified_alloc) - { - unsigned int nalloc; - - nalloc = info->modified_alloc; - if (nalloc == 0) - nalloc = 16; - while (indx >= nalloc) - nalloc *= 2; - info->modified = ((struct ieee_modified_type *) - xrealloc (info->modified, - nalloc * sizeof *info->modified)); - memset (info->modified + info->modified_alloc, 0, - (nalloc - info->modified_alloc) * sizeof *info->modified); - info->modified_alloc = nalloc; - } - - return info->modified + indx; -} - -/* Routines for the hash table mapping names to types. */ - -/* Initialize an entry in the hash table. */ - -static struct bfd_hash_entry * -ieee_name_type_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, const char *string) -{ - struct ieee_name_type_hash_entry *ret = - (struct ieee_name_type_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_allocate (table, sizeof *ret)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret) - { - /* Set local fields. */ - ret->types = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in the hash table. */ - -#define ieee_name_type_hash_lookup(table, string, create, copy) \ - ((struct ieee_name_type_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Traverse the hash table. */ - -#define ieee_name_type_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \ - (info))) - -/* The general routine to write out IEEE debugging information. */ - -bfd_boolean -write_ieee_debugging_info (bfd *abfd, void *dhandle) -{ - struct ieee_handle info; - asection *s; - const char *err; - struct ieee_buf *b; - - memset (&info, 0, sizeof info); - info.abfd = abfd; - info.type_indx = 256; - info.name_indx = 32; - - if (!bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc, - sizeof (struct ieee_name_type_hash_entry)) - || !bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc, - sizeof (struct ieee_name_type_hash_entry))) - return FALSE; - - if (! ieee_init_buffer (&info, &info.global_types) - || ! ieee_init_buffer (&info, &info.data) - || ! ieee_init_buffer (&info, &info.types) - || ! ieee_init_buffer (&info, &info.vars) - || ! ieee_init_buffer (&info, &info.cxx) - || ! ieee_init_buffer (&info, &info.linenos) - || ! ieee_init_buffer (&info, &info.fntype) - || ! ieee_init_buffer (&info, &info.fnargs)) - return FALSE; - - if (! debug_write (dhandle, &ieee_fns, (void *) &info)) - return FALSE; - - if (info.filename != NULL) - { - if (! ieee_finish_compilation_unit (&info)) - return FALSE; - } - - /* Put any undefined tags in the global typedef information. */ - info.error = FALSE; - ieee_name_type_hash_traverse (&info.tags, - ieee_write_undefined_tag, - (void *) &info); - if (info.error) - return FALSE; - - /* Prepend the global typedef information to the other data. */ - if (! ieee_buffer_emptyp (&info.global_types)) - { - /* The HP debugger seems to have a bug in which it ignores the - last entry in the global types, so we add a dummy entry. */ - if (! ieee_change_buffer (&info, &info.global_types) - || ! ieee_write_byte (&info, (int) ieee_nn_record) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_id (&info, "") - || ! ieee_write_byte (&info, (int) ieee_ty_record_enum) - || ! ieee_write_number (&info, info.type_indx) - || ! ieee_write_byte (&info, 0xce) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_number (&info, 'P') - || ! ieee_write_number (&info, (int) builtin_void + 32) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return FALSE; - - if (! ieee_append_buffer (&info, &info.global_types, &info.data)) - return FALSE; - info.data = info.global_types; - } - - /* Make sure that we have declare BB11 blocks for each range in the - file. They are added to info->vars. */ - info.error = FALSE; - if (! ieee_init_buffer (&info, &info.vars)) - return FALSE; - bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (void *) &info); - if (info.error) - return FALSE; - if (! ieee_buffer_emptyp (&info.vars)) - { - if (! ieee_change_buffer (&info, &info.vars) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return FALSE; - - if (! ieee_append_buffer (&info, &info.data, &info.vars)) - return FALSE; - } - - /* Now all the data is in info.data. Write it out to the BFD. We - normally would need to worry about whether all the other sections - are set up yet, but the IEEE backend will handle this particular - case correctly regardless. */ - if (ieee_buffer_emptyp (&info.data)) - { - /* There is no debugging information. */ - return TRUE; - } - err = NULL; - s = bfd_make_section_with_flags (abfd, ".debug", - SEC_DEBUGGING | SEC_HAS_CONTENTS); - if (s == NULL) - err = "bfd_make_section"; - if (err == NULL) - { - bfd_size_type size; - - size = 0; - for (b = info.data.head; b != NULL; b = b->next) - size += b->c; - if (! bfd_set_section_size (abfd, s, size)) - err = "bfd_set_section_size"; - } - if (err == NULL) - { - file_ptr offset; - - offset = 0; - for (b = info.data.head; b != NULL; b = b->next) - { - if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c)) - { - err = "bfd_set_section_contents"; - break; - } - offset += b->c; - } - } - - if (err != NULL) - { - fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err, - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - bfd_hash_table_free (&info.typedefs.root); - bfd_hash_table_free (&info.tags.root); - - return TRUE; -} - -/* Write out information for an undefined tag. This is called via - ieee_name_type_hash_traverse. */ - -static bfd_boolean -ieee_write_undefined_tag (struct ieee_name_type_hash_entry *h, void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type *nt; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - unsigned int name_indx; - char code; - - if (nt->kind == DEBUG_KIND_ILLEGAL) - continue; - - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - { - info->error = TRUE; - return FALSE; - } - } - else - { - if (! ieee_change_buffer (info, &info->global_types)) - { - info->error = TRUE; - return FALSE; - } - } - - name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, nt->type.name) - || ! ieee_write_byte (info, (int) ieee_ty_record_enum) - || ! ieee_write_number (info, nt->type.indx) - || ! ieee_write_byte (info, 0xce) - || ! ieee_write_number (info, name_indx)) - { - info->error = TRUE; - return FALSE; - } - - switch (nt->kind) - { - default: - abort (); - info->error = TRUE; - return FALSE; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_CLASS: - code = 'S'; - break; - case DEBUG_KIND_UNION: - case DEBUG_KIND_UNION_CLASS: - code = 'U'; - break; - case DEBUG_KIND_ENUM: - code = 'E'; - break; - } - if (! ieee_write_number (info, code) - || ! ieee_write_number (info, 0)) - { - info->error = TRUE; - return FALSE; - } - } - - return TRUE; -} - -/* Start writing out information for a compilation unit. */ - -static bfd_boolean -ieee_start_compilation_unit (void *p, const char *filename) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *modname; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - const char *backslash; -#endif - char *c, *s; - - if (info->filename != NULL) - { - if (! ieee_finish_compilation_unit (info)) - return FALSE; - } - - info->filename = filename; - modname = strrchr (filename, '/'); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* We could have a mixed forward/back slash case. */ - backslash = strrchr (filename, '\\'); - if (modname == NULL || (backslash != NULL && backslash > modname)) - modname = backslash; -#endif - - if (modname != NULL) - ++modname; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - else if (filename[0] && filename[1] == ':') - modname = filename + 2; -#endif - else - modname = filename; - - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - info->modname = c; - - if (! ieee_init_buffer (info, &info->types) - || ! ieee_init_buffer (info, &info->vars) - || ! ieee_init_buffer (info, &info->cxx) - || ! ieee_init_buffer (info, &info->linenos)) - return FALSE; - info->ranges = NULL; - - /* Always include a BB1 and a BB3 block. That is what the output of - the MRI linker seems to look like. */ - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 3) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - - return TRUE; -} - -/* Finish up a compilation unit. */ - -static bfd_boolean -ieee_finish_compilation_unit (struct ieee_handle *info) -{ - struct ieee_range *r; - - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - } - - if (! ieee_buffer_emptyp (&info->cxx)) - { - /* Append any C++ information to the global function and - variable information. */ - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return FALSE; - - /* We put the pmisc records in a dummy procedure, just as the - MRI compiler does. */ - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "__XRYCPP") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, info->highaddr - 1) - || ! ieee_append_buffer (info, &info->vars, &info->cxx) - || ! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, info->highaddr - 1)) - return FALSE; - } - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - } - - if (info->pending_lineno_filename != NULL) - { - /* Force out the pending line number. */ - if (! ieee_lineno ((void *) info, (const char *) NULL, 0, (bfd_vma) -1)) - return FALSE; - } - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - if (filename_cmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. We just closed the - included line number block, and now we must close the - main line number block. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - } - } - - if (! ieee_append_buffer (info, &info->data, &info->types) - || ! ieee_append_buffer (info, &info->data, &info->vars) - || ! ieee_append_buffer (info, &info->data, &info->linenos)) - return FALSE; - - /* Build BB10/BB11 blocks based on the ranges we recorded. */ - if (! ieee_change_buffer (info, &info->data)) - return FALSE; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - return FALSE; - - for (r = info->ranges; r != NULL; r = r->next) - { - bfd_vma low, high; - asection *s; - int kind; - - low = r->low; - high = r->high; - - /* Find the section corresponding to this range. */ - for (s = info->abfd->sections; s != NULL; s = s->next) - { - if (bfd_get_section_vma (info->abfd, s) <= low - && high <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s))) - break; - } - - if (s == NULL) - { - /* Just ignore this range. */ - continue; - } - - /* Coalesce ranges if it seems reasonable. */ - while (r->next != NULL - && high + 0x1000 >= r->next->low - && (r->next->high - <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s)))) - { - r = r->next; - high = r->high; - } - - if ((s->flags & SEC_CODE) != 0) - kind = 1; - else if ((s->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return FALSE; - - /* Add this range to the list of global ranges. */ - if (! ieee_add_range (info, TRUE, low, high)) - return FALSE; - } - - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - - return TRUE; -} - -/* Add BB11 blocks describing each range that we have not already - described. */ - -static void -ieee_add_bb11_blocks (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *data) -{ - struct ieee_handle *info = (struct ieee_handle *) data; - bfd_vma low, high; - struct ieee_range *r; - - low = bfd_get_section_vma (abfd, sec); - high = low + bfd_section_size (abfd, sec); - - /* Find the first range at or after this section. The ranges are - sorted by address. */ - for (r = info->global_ranges; r != NULL; r = r->next) - if (r->high > low) - break; - - while (low < high) - { - if (r == NULL || r->low >= high) - { - if (! ieee_add_bb11 (info, sec, low, high)) - info->error = TRUE; - return; - } - - if (low < r->low - && r->low - low > 0x100) - { - if (! ieee_add_bb11 (info, sec, low, r->low)) - { - info->error = TRUE; - return; - } - } - low = r->high; - - r = r->next; - } -} - -/* Add a single BB11 block for a range. We add it to info->vars. */ - -static bfd_boolean -ieee_add_bb11 (struct ieee_handle *info, asection *sec, bfd_vma low, - bfd_vma high) -{ - int kind; - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars)) - return FALSE; - } - else - { - const char *filename, *modname; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - const char *backslash; -#endif - char *c, *s; - - /* Start the enclosing BB10 block. */ - filename = bfd_get_filename (info->abfd); - modname = strrchr (filename, '/'); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - backslash = strrchr (filename, '\\'); - if (modname == NULL || (backslash != NULL && backslash > modname)) - modname = backslash; -#endif - - if (modname != NULL) - ++modname; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - else if (filename[0] && filename[1] == ':') - modname = filename + 2; -#endif - else - modname = filename; - - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, c) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - { - free (c); - return FALSE; - } - - free (c); - } - - if ((sec->flags & SEC_CODE) != 0) - kind = 1; - else if ((sec->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return FALSE; - - return TRUE; -} - -/* Start recording information from a particular source file. This is - used to record which file defined which types, variables, etc. It - is not used for line numbers, since the lineno entry point passes - down the file name anyhow. IEEE debugging information doesn't seem - to store this information anywhere. */ - -static bfd_boolean -ieee_start_source (void *p ATTRIBUTE_UNUSED, - const char *filename ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Make an empty type. */ - -static bfd_boolean -ieee_empty_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_unknown, 0, FALSE, FALSE); -} - -/* Make a void type. */ - -static bfd_boolean -ieee_void_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_void, 0, FALSE, FALSE); -} - -/* Make an integer type. */ - -static bfd_boolean -ieee_int_type (void *p, unsigned int size, bfd_boolean unsignedp) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 1: - indx = (int) builtin_signed_char; - break; - case 2: - indx = (int) builtin_signed_short_int; - break; - case 4: - indx = (int) builtin_signed_long; - break; - case 8: - indx = (int) builtin_signed_long_long; - break; - default: - fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size); - return FALSE; - } - - if (unsignedp) - ++indx; - - return ieee_push_type (info, indx, size, unsignedp, FALSE); -} - -/* Make a floating point type. */ - -static bfd_boolean -ieee_float_type (void *p, unsigned int size) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 4: - indx = (int) builtin_float; - break; - case 8: - indx = (int) builtin_double; - break; - case 12: - /* FIXME: This size really depends upon the processor. */ - indx = (int) builtin_long_double; - break; - case 16: - indx = (int) builtin_long_long_double; - break; - default: - fprintf (stderr, _("IEEE unsupported float type size %u\n"), size); - return FALSE; - } - - return ieee_push_type (info, indx, size, FALSE, FALSE); -} - -/* Make a complex type. */ - -static bfd_boolean -ieee_complex_type (void *p, unsigned int size) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - char code; - - switch (size) - { - case 4: - if (info->complex_float_index != 0) - return ieee_push_type (info, info->complex_float_index, size * 2, - FALSE, FALSE); - code = 'c'; - break; - case 12: - case 16: - /* These cases can be output by gcc -gstabs. Outputting the - wrong type is better than crashing. */ - case 8: - if (info->complex_double_index != 0) - return ieee_push_type (info, info->complex_double_index, size * 2, - FALSE, FALSE); - code = 'd'; - break; - default: - fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size); - return FALSE; - } - - /* FIXME: I don't know what the string is for. */ - if (! ieee_define_type (info, size * 2, FALSE, FALSE) - || ! ieee_write_number (info, code) - || ! ieee_write_id (info, "")) - return FALSE; - - if (size == 4) - info->complex_float_index = info->type_stack->type.indx; - else - info->complex_double_index = info->type_stack->type.indx; - - return TRUE; -} - -/* Make a boolean type. IEEE doesn't support these, so we just make - an integer type instead. */ - -static bfd_boolean -ieee_bool_type (void *p, unsigned int size) -{ - return ieee_int_type (p, size, TRUE); -} - -/* Make an enumeration. */ - -static bfd_boolean -ieee_enum_type (void *p, const char *tag, const char **names, - bfd_signed_vma *vals) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_defined_enum *e; - bfd_boolean localp, simple; - unsigned int indx; - int i = 0; - - localp = FALSE; - indx = (unsigned int) -1; - for (e = info->enums; e != NULL; e = e->next) - { - if (tag == NULL) - { - if (e->tag != NULL) - continue; - } - else - { - if (e->tag == NULL - || tag[0] != e->tag[0] - || strcmp (tag, e->tag) != 0) - continue; - } - - if (! e->defined) - { - /* This enum tag has been seen but not defined. */ - indx = e->indx; - break; - } - - if (names != NULL && e->names != NULL) - { - for (i = 0; names[i] != NULL && e->names[i] != NULL; i++) - { - if (names[i][0] != e->names[i][0] - || vals[i] != e->vals[i] - || strcmp (names[i], e->names[i]) != 0) - break; - } - } - - if ((names == NULL && e->names == NULL) - || (names != NULL - && e->names != NULL - && names[i] == NULL - && e->names[i] == NULL)) - { - /* We've seen this enum before. */ - return ieee_push_type (info, e->indx, 0, TRUE, FALSE); - } - - if (tag != NULL) - { - /* We've already seen an enum of the same name, so we must make - sure to output this one locally. */ - localp = TRUE; - break; - } - } - - /* If this is a simple enumeration, in which the values start at 0 - and always increment by 1, we can use type E. Otherwise we must - use type N. */ - - simple = TRUE; - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (vals[i] != i) - { - simple = FALSE; - break; - } - } - } - - if (! ieee_define_named_type (info, tag, indx, 0, TRUE, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, simple ? 'E' : 'N')) - return FALSE; - if (simple) - { - /* FIXME: This is supposed to be the enumeration size, but we - don't store that. */ - if (! ieee_write_number (info, 4)) - return FALSE; - } - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (! ieee_write_id (info, names[i])) - return FALSE; - if (! simple) - { - if (! ieee_write_number (info, vals[i])) - return FALSE; - } - } - } - - if (! localp) - { - if (indx == (unsigned int) -1) - { - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - e->indx = info->type_stack->type.indx; - e->tag = tag; - - e->next = info->enums; - info->enums = e; - } - - e->names = names; - e->vals = vals; - e->defined = TRUE; - } - - return TRUE; -} - -/* Make a pointer type. */ - -static bfd_boolean -ieee_pointer_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - /* A pointer to a simple builtin type can be obtained by adding 32. - FIXME: Will this be a short pointer, and will that matter? */ - if (indx < 32) - return ieee_push_type (info, indx + 32, 0, TRUE, FALSE); - - if (! localp) - { - m = ieee_get_modified_info ((struct ieee_handle *) p, indx); - if (m == NULL) - return FALSE; - - /* FIXME: The size should depend upon the architecture. */ - if (m->pointer > 0) - return ieee_push_type (info, m->pointer, 4, TRUE, FALSE); - } - - if (! ieee_define_type (info, 4, TRUE, localp) - || ! ieee_write_number (info, 'P') - || ! ieee_write_number (info, indx)) - return FALSE; - - if (! localp) - m->pointer = info->type_stack->type.indx; - - return TRUE; -} - -/* Make a function type. This will be called for a method, but we - don't want to actually add it to the type table in that case. We - handle this by defining the type in a private buffer, and only - adding that buffer to the typedef block if we are going to use it. */ - -static bfd_boolean -ieee_function_type (void *p, int argcount, bfd_boolean varargs) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean localp; - unsigned int *args = NULL; - int i; - unsigned int retindx; - struct ieee_buflist fndef; - struct ieee_modified_type *m; - - localp = FALSE; - - if (argcount > 0) - { - args = (unsigned int *) xmalloc (argcount * sizeof *args); - for (i = argcount - 1; i >= 0; i--) - { - if (info->type_stack->type.localp) - localp = TRUE; - args[i] = ieee_pop_type (info); - } - } - else if (argcount < 0) - varargs = FALSE; - - if (info->type_stack->type.localp) - localp = TRUE; - retindx = ieee_pop_type (info); - - m = NULL; - if (argcount < 0 && ! localp) - { - m = ieee_get_modified_info ((struct ieee_handle *) p, retindx); - if (m == NULL) - return FALSE; - - if (m->function > 0) - return ieee_push_type (info, m->function, 0, TRUE, FALSE); - } - - /* An attribute of 0x41 means that the frame and push mask are - unknown. */ - if (! ieee_init_buffer (info, &fndef) - || ! ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, 0, TRUE, localp, - &fndef) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x41) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx) - || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0))) - { - free (args); - return FALSE; - } - if (argcount > 0) - { - for (i = 0; i < argcount; i++) - if (! ieee_write_number (info, args[i])) - return FALSE; - free (args); - } - if (varargs) - { - /* A varargs function is represented by writing out the last - argument as type void *, although this makes little sense. */ - if (! ieee_write_number (info, (bfd_vma) builtin_void + 32)) - return FALSE; - } - - if (! ieee_write_number (info, 0)) - return FALSE; - - /* We wrote the information into fndef, in case we don't need it. - It will be appended to info->types by ieee_pop_type. */ - info->type_stack->type.fndef = fndef; - - if (m != NULL) - m->function = info->type_stack->type.indx; - - return TRUE; -} - -/* Make a reference type. */ - -static bfd_boolean -ieee_reference_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* IEEE appears to record a normal pointer type, and then use a - pmisc record to indicate that it is really a reference. */ - - if (! ieee_pointer_type (p)) - return FALSE; - info->type_stack->type.referencep = TRUE; - return TRUE; -} - -/* Make a range type. */ - -static bfd_boolean -ieee_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - bfd_boolean unsignedp, localp; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - ieee_pop_unused_type (info); - return (ieee_define_type (info, size, unsignedp, localp) - && ieee_write_number (info, 'R') - && ieee_write_number (info, (bfd_vma) low) - && ieee_write_number (info, (bfd_vma) high) - && ieee_write_number (info, unsignedp ? 0 : 1) - && ieee_write_number (info, size)); -} - -/* Make an array type. */ - -static bfd_boolean -ieee_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, - bfd_boolean stringp ATTRIBUTE_UNUSED) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int eleindx; - bfd_boolean localp; - unsigned int size; - struct ieee_modified_type *m = NULL; - struct ieee_modified_array_type *a; - - /* IEEE does not store the range, so we just ignore it. */ - ieee_pop_unused_type (info); - localp = info->type_stack->type.localp; - size = info->type_stack->type.size; - eleindx = ieee_pop_type (info); - - /* If we don't know the range, treat the size as exactly one - element. */ - if (low < high) - size *= (high - low) + 1; - - if (! localp) - { - m = ieee_get_modified_info (info, eleindx); - if (m == NULL) - return FALSE; - - for (a = m->arrays; a != NULL; a = a->next) - { - if (a->low == low && a->high == high) - return ieee_push_type (info, a->indx, size, FALSE, FALSE); - } - } - - if (! ieee_define_type (info, size, FALSE, localp) - || ! ieee_write_number (info, low == 0 ? 'Z' : 'C') - || ! ieee_write_number (info, eleindx)) - return FALSE; - if (low != 0) - { - if (! ieee_write_number (info, low)) - return FALSE; - } - - if (! ieee_write_number (info, high + 1)) - return FALSE; - - if (! localp) - { - a = (struct ieee_modified_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->indx = info->type_stack->type.indx; - a->low = low; - a->high = high; - - a->next = m->arrays; - m->arrays = a; - } - - return TRUE; -} - -/* Make a set type. */ - -static bfd_boolean -ieee_set_type (void *p, bfd_boolean bitstringp ATTRIBUTE_UNUSED) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean localp; - unsigned int eleindx; - - localp = info->type_stack->type.localp; - eleindx = ieee_pop_type (info); - - /* FIXME: We don't know the size, so we just use 4. */ - - return (ieee_define_type (info, 0, TRUE, localp) - && ieee_write_number (info, 's') - && ieee_write_number (info, 4) - && ieee_write_number (info, eleindx)); -} - -/* Make an offset type. */ - -static bfd_boolean -ieee_offset_type (void *p) -{ - /* FIXME: The MRI C++ compiler does not appear to generate any - useful type information about an offset type. It just records a - pointer to member as an integer. The MRI/HP IEEE spec does - describe a pmisc record which can be used for a pointer to - member. Unfortunately, it does not describe the target type, - which seems pretty important. I'm going to punt this for now. */ - - return ieee_int_type (p, 4, TRUE); -} - -/* Make a method type. */ - -static bfd_boolean -ieee_method_type (void *p, bfd_boolean domain, int argcount, - bfd_boolean varargs) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a - method, but the definition is incomplete. We just output an 'x' - type. */ - - if (domain) - ieee_pop_unused_type (info); - - return ieee_function_type (p, argcount, varargs); -} - -/* Make a const qualified type. */ - -static bfd_boolean -ieee_const_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - bfd_boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return FALSE; - - if (m->const_qualified > 0) - return ieee_push_type (info, m->const_qualified, size, unsignedp, - FALSE); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 1) - || ! ieee_write_number (info, indx)) - return FALSE; - - if (! localp) - m->const_qualified = info->type_stack->type.indx; - - return TRUE; -} - -/* Make a volatile qualified type. */ - -static bfd_boolean -ieee_volatile_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - bfd_boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return FALSE; - - if (m->volatile_qualified > 0) - return ieee_push_type (info, m->volatile_qualified, size, unsignedp, - FALSE); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 2) - || ! ieee_write_number (info, indx)) - return FALSE; - - if (! localp) - m->volatile_qualified = info->type_stack->type.indx; - - return TRUE; -} - -/* Convert an enum debug_visibility into a CXXFLAGS value. */ - -static unsigned int -ieee_vis_to_flags (enum debug_visibility visibility) -{ - switch (visibility) - { - default: - abort (); - case DEBUG_VISIBILITY_PUBLIC: - return CXXFLAGS_VISIBILITY_PUBLIC; - case DEBUG_VISIBILITY_PRIVATE: - return CXXFLAGS_VISIBILITY_PRIVATE; - case DEBUG_VISIBILITY_PROTECTED: - return CXXFLAGS_VISIBILITY_PROTECTED; - } - /*NOTREACHED*/ -} - -/* Start defining a struct type. We build it in the strdef field on - the stack, to avoid confusing type definitions required by the - fields with the struct type itself. */ - -static bfd_boolean -ieee_start_struct_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean localp, ignorep; - bfd_boolean copy; - char ab[20]; - const char *look; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt, *ntlook; - struct ieee_buflist strdef; - - localp = FALSE; - ignorep = FALSE; - - /* We need to create a tag for internal use even if we don't want - one for external use. This will let us refer to an anonymous - struct. */ - if (tag != NULL) - { - look = tag; - copy = FALSE; - } - else - { - sprintf (ab, "__anon%u", id); - look = ab; - copy = TRUE; - } - - /* If we already have references to the tag, we must use the - existing type index. */ - h = ieee_name_type_hash_lookup (&info->tags, look, TRUE, copy); - if (h == NULL) - return FALSE; - - nt = NULL; - for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next) - { - if (ntlook->id == id) - nt = ntlook; - else if (! ntlook->type.localp) - { - /* We are creating a duplicate definition of a globally - defined tag. Force it to be local to avoid - confusion. */ - localp = TRUE; - } - } - - if (nt != NULL) - { - assert (localp == nt->type.localp); - if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp) - { - /* We've already seen a global definition of the type. - Ignore this new definition. */ - ignorep = TRUE; - } - } - else - { - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = id; - nt->type.name = h->root.string; - nt->next = h->types; - h->types = nt; - nt->type.indx = info->type_indx; - ++info->type_indx; - } - - nt->kind = DEBUG_KIND_ILLEGAL; - - if (! ieee_init_buffer (info, &strdef) - || ! ieee_define_named_type (info, tag, nt->type.indx, size, TRUE, - localp, &strdef) - || ! ieee_write_number (info, structp ? 'S' : 'U') - || ! ieee_write_number (info, size)) - return FALSE; - - if (! ignorep) - { - const char *hold; - - /* We never want nt->type.name to be NULL. We want the rest of - the type to be the object set up on the type stack; it will - have a NULL name if tag is NULL. */ - hold = nt->type.name; - nt->type = info->type_stack->type; - nt->type.name = hold; - } - - info->type_stack->type.name = tag; - info->type_stack->type.strdef = strdef; - info->type_stack->type.ignorep = ignorep; - - return TRUE; -} - -/* Add a field to a struct. */ - -static bfd_boolean -ieee_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize, - enum debug_visibility visibility) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - bfd_boolean unsignedp; - bfd_boolean referencep; - bfd_boolean localp; - unsigned int indx; - bfd_vma offset; - - assert (info->type_stack != NULL - && info->type_stack->next != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - /* If we are ignoring this struct definition, just pop and ignore - the type. */ - if (info->type_stack->next->type.ignorep) - { - ieee_pop_unused_type (info); - return TRUE; - } - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - referencep = info->type_stack->type.referencep; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (localp) - info->type_stack->type.localp = TRUE; - - if (info->type_stack->type.classdef != NULL) - { - unsigned int flags; - unsigned int nindx; - - /* This is a class. We must add a description of this field to - the class records we are building. */ - - flags = ieee_vis_to_flags (visibility); - nindx = info->type_stack->type.classdef->indx; - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, name)) - return FALSE; - info->type_stack->type.classdef->pmisccount += 4; - - if (referencep) - { - /* We need to output a record recording that this field is - really of reference type. We put this on the refs field - of classdef, so that it can be appended to the C++ - records after the class is defined. */ - - nindx = info->name_indx; - ++info->name_indx; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->refs) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 4) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, 3) - || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name) - || ! ieee_write_atn65 (info, nindx, name)) - return FALSE; - } - } - - /* If the bitsize doesn't match the expected size, we need to output - a bitfield type. */ - if (size == 0 || bitsize == 0 || bitsize == size * 8) - offset = bitpos / 8; - else - { - if (! ieee_define_type (info, 0, unsignedp, - info->type_stack->type.localp) - || ! ieee_write_number (info, 'g') - || ! ieee_write_number (info, unsignedp ? 0 : 1) - || ! ieee_write_number (info, bitsize) - || ! ieee_write_number (info, indx)) - return FALSE; - indx = ieee_pop_type (info); - offset = bitpos; - } - - /* Switch to the struct we are building in order to output this - field definition. */ - return (ieee_change_buffer (info, &info->type_stack->type.strdef) - && ieee_write_id (info, name) - && ieee_write_number (info, indx) - && ieee_write_number (info, offset)); -} - -/* Finish up a struct type. */ - -static bfd_boolean -ieee_end_struct_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_buflist *pb; - - assert (info->type_stack != NULL - && ! ieee_buffer_emptyp (&info->type_stack->type.strdef)); - - /* If we were ignoring this struct definition because it was a - duplicate definition, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return TRUE; - - /* If this is not a duplicate definition of this tag, then localp - will be FALSE, and we can put it in the global type block. - FIXME: We should avoid outputting duplicate definitions which are - the same. */ - if (! info->type_stack->type.localp) - { - /* Make sure we have started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return FALSE; - } - pb = &info->global_types; - } - else - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - } - pb = &info->types; - } - - /* Append the struct definition to the types. */ - if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef) - || ! ieee_init_buffer (info, &info->type_stack->type.strdef)) - return FALSE; - - /* Leave the struct on the type stack. */ - - return TRUE; -} - -/* Start a class type. */ - -static bfd_boolean -ieee_start_class_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size, - bfd_boolean vptr, bfd_boolean ownvptr) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *vclass; - struct ieee_buflist pmiscbuf; - unsigned int indx; - struct ieee_type_class *classdef; - - /* A C++ class is output as a C++ struct along with a set of pmisc - records describing the class. */ - - /* We need to have a name so that we can associate the struct and - the class. */ - if (tag == NULL) - { - char *t; - - t = (char *) xmalloc (20); - sprintf (t, "__anon%u", id); - tag = t; - } - - /* We can't write out the virtual table information until we have - finished the class, because we don't know the virtual table size. - We get the size from the largest voffset we see. */ - vclass = NULL; - if (vptr && ! ownvptr) - { - vclass = info->type_stack->type.name; - assert (vclass != NULL); - /* We don't call ieee_pop_unused_type, since the class should - get defined. */ - (void) ieee_pop_type (info); - } - - if (! ieee_start_struct_type (p, tag, id, structp, size)) - return FALSE; - - indx = info->name_indx; - ++info->name_indx; - - /* We write out pmisc records into the classdef field. We will - write out the pmisc start after we know the number of records we - need. */ - if (! ieee_init_buffer (info, &pmiscbuf) - || ! ieee_change_buffer (info, &pmiscbuf) - || ! ieee_write_asn (info, indx, 'T') - || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') - || ! ieee_write_atn65 (info, indx, tag)) - return FALSE; - - classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); - memset (classdef, 0, sizeof *classdef); - - classdef->indx = indx; - classdef->pmiscbuf = pmiscbuf; - classdef->pmisccount = 3; - classdef->vclass = vclass; - classdef->ownvptr = ownvptr; - - info->type_stack->type.classdef = classdef; - - return TRUE; -} - -/* Add a static member to a class. */ - -static bfd_boolean -ieee_class_static_member (void *p, const char *name, const char *physname, - enum debug_visibility visibility) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int flags; - unsigned int nindx; - - /* We don't care about the type. Hopefully there will be a call to - ieee_variable declaring the physical name and the type, since - that is where an IEEE consumer must get the type. */ - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - flags = ieee_vis_to_flags (visibility); - flags |= CXXFLAGS_STATIC; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, physname)) - return FALSE; - info->type_stack->type.classdef->pmisccount += 4; - - return TRUE; -} - -/* Add a base class to a class. */ - -static bfd_boolean -ieee_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean is_virtual, - enum debug_visibility visibility) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *bname; - bfd_boolean localp; - unsigned int bindx; - char *fname; - unsigned int flags; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.name != NULL - && info->type_stack->next != NULL - && info->type_stack->next->type.classdef != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - bname = info->type_stack->type.name; - localp = info->type_stack->type.localp; - bindx = ieee_pop_type (info); - - /* We are currently defining both a struct and a class. We must - write out a field definition in the struct which holds the base - class. The stabs debugging reader will create a field named - _vb$CLASS for a virtual base class, so we just use that. FIXME: - we should not depend upon a detail of stabs debugging. */ - if (is_virtual) - { - fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); - sprintf (fname, "_vb$%s", bname); - flags = BASEFLAGS_VIRTUAL; - } - else - { - if (localp) - info->type_stack->type.localp = TRUE; - - fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); - sprintf (fname, "_b$%s", bname); - - if (! ieee_change_buffer (info, &info->type_stack->type.strdef) - || ! ieee_write_id (info, fname) - || ! ieee_write_number (info, bindx) - || ! ieee_write_number (info, bitpos / 8)) - { - free (fname); - return FALSE; - } - flags = 0; - } - - if (visibility == DEBUG_VISIBILITY_PRIVATE) - flags |= BASEFLAGS_PRIVATE; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'b') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, bname) - || ! ieee_write_asn (info, nindx, 0) - || ! ieee_write_atn65 (info, nindx, fname)) - { - free (fname); - return FALSE; - } - info->type_stack->type.classdef->pmisccount += 5; - - free (fname); - - return TRUE; -} - -/* Start building a method for a class. */ - -static bfd_boolean -ieee_class_start_method (void *p, const char *name) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method == NULL); - - info->type_stack->type.classdef->method = name; - - return TRUE; -} - -/* Define a new method variant, either static or not. */ - -static bfd_boolean -ieee_class_method_var (struct ieee_handle *info, const char *physname, - enum debug_visibility visibility, - bfd_boolean staticp, bfd_boolean constp, - bfd_boolean volatilep, bfd_vma voffset, - bfd_boolean context) -{ - unsigned int flags; - unsigned int nindx; - bfd_boolean is_virtual; - - /* We don't need the type of the method. An IEEE consumer which - wants the type must track down the function by the physical name - and get the type from that. */ - ieee_pop_unused_type (info); - - /* We don't use the context. FIXME: We probably ought to use it to - adjust the voffset somehow, but I don't really know how. */ - if (context) - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - flags = ieee_vis_to_flags (visibility); - - /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, - CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ - - if (staticp) - flags |= CXXFLAGS_STATIC; - if (constp) - flags |= CXXFLAGS_CONST; - if (volatilep) - flags |= CXXFLAGS_VOLATILE; - - nindx = info->type_stack->type.classdef->indx; - - is_virtual = context || voffset > 0; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, is_virtual ? 'v' : 'm') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->method) - || ! ieee_write_atn65 (info, nindx, physname)) - return FALSE; - - if (is_virtual) - { - if (voffset > info->type_stack->type.classdef->voffset) - info->type_stack->type.classdef->voffset = voffset; - if (! ieee_write_asn (info, nindx, voffset)) - return FALSE; - ++info->type_stack->type.classdef->pmisccount; - } - - if (! ieee_write_asn (info, nindx, 0)) - return FALSE; - - info->type_stack->type.classdef->pmisccount += 5; - - return TRUE; -} - -/* Define a new method variant. */ - -static bfd_boolean -ieee_class_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep, - bfd_vma voffset, bfd_boolean context) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, FALSE, constp, - volatilep, voffset, context); -} - -/* Define a new static method variant. */ - -static bfd_boolean -ieee_class_static_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, TRUE, constp, - volatilep, 0, FALSE); -} - -/* Finish up a method. */ - -static bfd_boolean -ieee_class_end_method (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - info->type_stack->type.classdef->method = NULL; - - return TRUE; -} - -/* Finish up a class. */ - -static bfd_boolean -ieee_end_class_type (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - /* If we were ignoring this class definition because it was a - duplicate definition, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return TRUE; - - nindx = info->type_stack->type.classdef->indx; - - /* If we have a virtual table, we can write out the information now. */ - if (info->type_stack->type.classdef->vclass != NULL - || info->type_stack->type.classdef->ownvptr) - { - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'z') - || ! ieee_write_atn65 (info, nindx, "") - || ! ieee_write_asn (info, nindx, - info->type_stack->type.classdef->voffset)) - return FALSE; - if (info->type_stack->type.classdef->ownvptr) - { - if (! ieee_write_atn65 (info, nindx, "")) - return FALSE; - } - else - { - if (! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->vclass)) - return FALSE; - } - if (! ieee_write_asn (info, nindx, 0)) - return FALSE; - info->type_stack->type.classdef->pmisccount += 5; - } - - /* Now that we know the number of pmisc records, we can write out - the atn62 which starts the pmisc records, and append them to the - C++ buffers. */ - - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, - info->type_stack->type.classdef->pmisccount)) - return FALSE; - - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->pmiscbuf)) - return FALSE; - if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs)) - { - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->refs)) - return FALSE; - } - - return ieee_end_struct_type (p); -} - -/* Push a previously seen typedef onto the type stack. */ - -static bfd_boolean -ieee_typedef_type (void *p, const char *name) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - h = ieee_name_type_hash_lookup (&info->typedefs, name, FALSE, FALSE); - - /* h should never be NULL, since that would imply that the generic - debugging code has asked for a typedef which it has not yet - defined. */ - assert (h != NULL); - - /* We always use the most recently defined type for this name, which - will be the first one on the list. */ - - nt = h->types; - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return FALSE; - - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - - return TRUE; -} - -/* Push a tagged type onto the type stack. */ - -static bfd_boolean -ieee_tag_type (void *p, const char *name, unsigned int id, - enum debug_type_kind kind) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean localp; - bfd_boolean copy; - char ab[20]; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - if (kind == DEBUG_KIND_ENUM) - { - struct ieee_defined_enum *e; - - if (name == NULL) - abort (); - for (e = info->enums; e != NULL; e = e->next) - if (e->tag != NULL && strcmp (e->tag, name) == 0) - return ieee_push_type (info, e->indx, 0, TRUE, FALSE); - - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->indx = info->type_indx; - ++info->type_indx; - e->tag = name; - e->defined = FALSE; - - e->next = info->enums; - info->enums = e; - - return ieee_push_type (info, e->indx, 0, TRUE, FALSE); - } - - localp = FALSE; - - copy = FALSE; - if (name == NULL) - { - sprintf (ab, "__anon%u", id); - name = ab; - copy = TRUE; - } - - h = ieee_name_type_hash_lookup (&info->tags, name, TRUE, copy); - if (h == NULL) - return FALSE; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == id) - { - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return FALSE; - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - return TRUE; - } - - if (! nt->type.localp) - { - /* This is a duplicate of a global type, so it must be - local. */ - localp = TRUE; - } - } - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - - nt->id = id; - nt->type.name = h->root.string; - nt->type.indx = info->type_indx; - nt->type.localp = localp; - ++info->type_indx; - nt->kind = kind; - - nt->next = h->types; - h->types = nt; - - if (! ieee_push_type (info, nt->type.indx, 0, FALSE, localp)) - return FALSE; - - info->type_stack->type.name = h->root.string; - - return TRUE; -} - -/* Output a typedef. */ - -static bfd_boolean -ieee_typdef (void *p, const char *name) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_write_type type; - unsigned int indx; - bfd_boolean found; - bfd_boolean localp; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - type = info->type_stack->type; - indx = type.indx; - - /* If this is a simple builtin type using a builtin name, we don't - want to output the typedef itself. We also want to change the - type index to correspond to the name being used. We recognize - names used in stabs debugging output even if they don't exactly - correspond to the names used for the IEEE builtin types. */ - found = FALSE; - if (indx <= (unsigned int) builtin_bcd_float) - { - switch ((enum builtin_types) indx) - { - default: - break; - - case builtin_void: - if (strcmp (name, "void") == 0) - found = TRUE; - break; - - case builtin_signed_char: - case builtin_char: - if (strcmp (name, "signed char") == 0) - { - indx = (unsigned int) builtin_signed_char; - found = TRUE; - } - else if (strcmp (name, "char") == 0) - { - indx = (unsigned int) builtin_char; - found = TRUE; - } - break; - - case builtin_unsigned_char: - if (strcmp (name, "unsigned char") == 0) - found = TRUE; - break; - - case builtin_signed_short_int: - case builtin_short: - case builtin_short_int: - case builtin_signed_short: - if (strcmp (name, "signed short int") == 0) - { - indx = (unsigned int) builtin_signed_short_int; - found = TRUE; - } - else if (strcmp (name, "short") == 0) - { - indx = (unsigned int) builtin_short; - found = TRUE; - } - else if (strcmp (name, "short int") == 0) - { - indx = (unsigned int) builtin_short_int; - found = TRUE; - } - else if (strcmp (name, "signed short") == 0) - { - indx = (unsigned int) builtin_signed_short; - found = TRUE; - } - break; - - case builtin_unsigned_short_int: - case builtin_unsigned_short: - if (strcmp (name, "unsigned short int") == 0 - || strcmp (name, "short unsigned int") == 0) - { - indx = builtin_unsigned_short_int; - found = TRUE; - } - else if (strcmp (name, "unsigned short") == 0) - { - indx = builtin_unsigned_short; - found = TRUE; - } - break; - - case builtin_signed_long: - case builtin_int: /* FIXME: Size depends upon architecture. */ - case builtin_long: - if (strcmp (name, "signed long") == 0) - { - indx = builtin_signed_long; - found = TRUE; - } - else if (strcmp (name, "int") == 0) - { - indx = builtin_int; - found = TRUE; - } - else if (strcmp (name, "long") == 0 - || strcmp (name, "long int") == 0) - { - indx = builtin_long; - found = TRUE; - } - break; - - case builtin_unsigned_long: - case builtin_unsigned: /* FIXME: Size depends upon architecture. */ - case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */ - if (strcmp (name, "unsigned long") == 0 - || strcmp (name, "long unsigned int") == 0) - { - indx = builtin_unsigned_long; - found = TRUE; - } - else if (strcmp (name, "unsigned") == 0) - { - indx = builtin_unsigned; - found = TRUE; - } - else if (strcmp (name, "unsigned int") == 0) - { - indx = builtin_unsigned_int; - found = TRUE; - } - break; - - case builtin_signed_long_long: - if (strcmp (name, "signed long long") == 0 - || strcmp (name, "long long int") == 0) - found = TRUE; - break; - - case builtin_unsigned_long_long: - if (strcmp (name, "unsigned long long") == 0 - || strcmp (name, "long long unsigned int") == 0) - found = TRUE; - break; - - case builtin_float: - if (strcmp (name, "float") == 0) - found = TRUE; - break; - - case builtin_double: - if (strcmp (name, "double") == 0) - found = TRUE; - break; - - case builtin_long_double: - if (strcmp (name, "long double") == 0) - found = TRUE; - break; - - case builtin_long_long_double: - if (strcmp (name, "long long double") == 0) - found = TRUE; - break; - } - - if (found) - type.indx = indx; - } - - h = ieee_name_type_hash_lookup (&info->typedefs, name, TRUE, FALSE); - if (h == NULL) - return FALSE; - - /* See if we have already defined this type with this name. */ - localp = type.localp; - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == indx) - { - /* If this is a global definition, then we don't need to - do anything here. */ - if (! nt->type.localp) - { - ieee_pop_unused_type (info); - return TRUE; - } - } - else - { - /* This is a duplicate definition, so make this one local. */ - localp = TRUE; - } - } - - /* We need to add a new typedef for this type. */ - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = indx; - nt->type = type; - nt->type.name = name; - nt->type.localp = localp; - nt->kind = DEBUG_KIND_ILLEGAL; - - nt->next = h->types; - h->types = nt; - - if (found) - { - /* This is one of the builtin typedefs, so we don't need to - actually define it. */ - ieee_pop_unused_type (info); - return TRUE; - } - - indx = ieee_pop_type (info); - - if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size, - type.unsignedp, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, 'T') - || ! ieee_write_number (info, indx)) - return FALSE; - - /* Remove the type we just added to the type stack. This should not - be ieee_pop_unused_type, since the type is used, we just don't - need it now. */ - (void) ieee_pop_type (info); - - return TRUE; -} - -/* Output a tag for a type. We don't have to do anything here. */ - -static bfd_boolean -ieee_tag (void *p, const char *name ATTRIBUTE_UNUSED) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* This should not be ieee_pop_unused_type, since we want the type - to be defined. */ - (void) ieee_pop_type (info); - return TRUE; -} - -/* Output an integer constant. */ - -static bfd_boolean -ieee_int_constant (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, - bfd_vma val ATTRIBUTE_UNUSED) -{ - /* FIXME. */ - return TRUE; -} - -/* Output a floating point constant. */ - -static bfd_boolean -ieee_float_constant (void *p ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - double val ATTRIBUTE_UNUSED) -{ - /* FIXME. */ - return TRUE; -} - -/* Output a typed constant. */ - -static bfd_boolean -ieee_typed_constant (void *p, const char *name ATTRIBUTE_UNUSED, - bfd_vma val ATTRIBUTE_UNUSED) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME. */ - ieee_pop_unused_type (info); - return TRUE; -} - -/* Output a variable. */ - -static bfd_boolean -ieee_variable (void *p, const char *name, enum debug_var_kind kind, - bfd_vma val) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int name_indx; - unsigned int size; - bfd_boolean referencep; - unsigned int type_indx; - bfd_boolean asn; - int refflag; - - size = info->type_stack->type.size; - referencep = info->type_stack->type.referencep; - type_indx = ieee_pop_type (info); - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return FALSE; - - name_indx = info->name_indx; - ++info->name_indx; - - /* Write out an NN and an ATN record for this variable. */ - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, name) - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_number (info, type_indx)) - return FALSE; - switch (kind) - { - default: - abort (); - return FALSE; - case DEBUG_GLOBAL: - if (! ieee_write_number (info, 8) - || ! ieee_add_range (info, FALSE, val, val + size)) - return FALSE; - refflag = 0; - asn = TRUE; - break; - case DEBUG_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, FALSE, val, val + size)) - return FALSE; - refflag = 1; - asn = TRUE; - break; - case DEBUG_LOCAL_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, FALSE, val, val + size)) - return FALSE; - refflag = 2; - asn = TRUE; - break; - case DEBUG_LOCAL: - if (! ieee_write_number (info, 1) - || ! ieee_write_number (info, val)) - return FALSE; - refflag = 2; - asn = FALSE; - break; - case DEBUG_REGISTER: - if (! ieee_write_number (info, 2) - || ! ieee_write_number (info, - ieee_genreg_to_regno (info->abfd, val))) - return FALSE; - refflag = 2; - asn = FALSE; - break; - } - - if (asn) - { - if (! ieee_write_asn (info, name_indx, val)) - return FALSE; - } - - /* If this is really a reference type, then we just output it with - pointer type, and must now output a C++ record indicating that it - is really reference type. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - - /* If this is a global variable, we want to output the misc - record in the C++ misc record block. Otherwise, we want to - output it just after the variable definition, which is where - the current buffer is. */ - if (refflag != 2) - { - if (! ieee_change_buffer (info, &info->cxx)) - return FALSE; - } - - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, refflag) - || ! ieee_write_atn65 (info, nindx, name)) - return FALSE; - } - - return TRUE; -} - -/* Start outputting information for a function. */ - -static bfd_boolean -ieee_start_function (void *p, const char *name, bfd_boolean global) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - bfd_boolean referencep; - unsigned int retindx, typeindx; - - referencep = info->type_stack->type.referencep; - retindx = ieee_pop_type (info); - - /* Besides recording a BB4 or BB6 block, we record the type of the - function in the BB1 typedef block. We can't write out the full - type until we have seen all the parameters, so we accumulate it - in info->fntype and info->fnargs. */ - if (! ieee_buffer_emptyp (&info->fntype)) - { - /* FIXME: This might happen someday if we support nested - functions. */ - abort (); - } - - info->fnname = name; - - /* An attribute of 0x40 means that the push mask is unknown. */ - if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, FALSE, TRUE, - &info->fntype) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x40) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx)) - return FALSE; - - typeindx = ieee_pop_type (info); - - if (! ieee_init_buffer (info, &info->fnargs)) - return FALSE; - info->fnargcount = 0; - - /* If the function return value is actually a reference type, we - must add a record indicating that. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, global ? 0 : 1) - || ! ieee_write_atn65 (info, nindx, name)) - return FALSE; - } - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return FALSE; - - /* The address is written out as the first block. */ - - ++info->block_depth; - - return (ieee_write_byte (info, (int) ieee_bb_record_enum) - && ieee_write_byte (info, global ? 4 : 6) - && ieee_write_number (info, 0) - && ieee_write_id (info, name) - && ieee_write_number (info, 0) - && ieee_write_number (info, typeindx)); -} - -/* Add a function parameter. This will normally be called before the - first block, so we postpone them until we see the block. */ - -static bfd_boolean -ieee_function_parameter (void *p, const char *name, enum debug_parm_kind kind, - bfd_vma val) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_pending_parm *m, **pm; - - assert (info->block_depth == 1); - - m = (struct ieee_pending_parm *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->next = NULL; - m->name = name; - m->referencep = info->type_stack->type.referencep; - m->type = ieee_pop_type (info); - m->kind = kind; - m->val = val; - - for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next) - ; - *pm = m; - - /* Add the type to the fnargs list. */ - if (! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, m->type)) - return FALSE; - ++info->fnargcount; - - return TRUE; -} - -/* Output pending function parameters. */ - -static bfd_boolean -ieee_output_pending_parms (struct ieee_handle *info) -{ - struct ieee_pending_parm *m; - unsigned int refcount; - - refcount = 0; - for (m = info->pending_parms; m != NULL; m = m->next) - { - enum debug_var_kind vkind; - - switch (m->kind) - { - default: - abort (); - return FALSE; - case DEBUG_PARM_STACK: - case DEBUG_PARM_REFERENCE: - vkind = DEBUG_LOCAL; - break; - case DEBUG_PARM_REG: - case DEBUG_PARM_REF_REG: - vkind = DEBUG_REGISTER; - break; - } - - if (! ieee_push_type (info, m->type, 0, FALSE, FALSE)) - return FALSE; - info->type_stack->type.referencep = m->referencep; - if (m->referencep) - ++refcount; - if (! ieee_variable ((void *) info, m->name, vkind, m->val)) - return FALSE; - } - - /* If there are any reference parameters, we need to output a - miscellaneous record indicating them. */ - if (refcount > 0) - { - unsigned int nindx, varindx; - - /* FIXME: The MRI compiler outputs the demangled function name - here, but we are outputting the mangled name. */ - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, refcount + 3) - || ! ieee_write_asn (info, nindx, 'B') - || ! ieee_write_atn65 (info, nindx, info->fnname) - || ! ieee_write_asn (info, nindx, 0)) - return FALSE; - for (m = info->pending_parms, varindx = 1; - m != NULL; - m = m->next, varindx++) - { - if (m->referencep) - { - if (! ieee_write_asn (info, nindx, varindx)) - return FALSE; - } - } - } - - m = info->pending_parms; - while (m != NULL) - { - struct ieee_pending_parm *next; - - next = m->next; - free (m); - m = next; - } - - info->pending_parms = NULL; - - return TRUE; -} - -/* Start a block. If this is the first block, we output the address - to finish the BB4 or BB6, and then output the function parameters. */ - -static bfd_boolean -ieee_start_block (void *p, bfd_vma addr) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - if (! ieee_change_buffer (info, &info->vars)) - return FALSE; - - if (info->block_depth == 1) - { - if (! ieee_write_number (info, addr) - || ! ieee_output_pending_parms (info)) - return FALSE; - } - else - { - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, addr)) - return FALSE; - } - - if (! ieee_start_range (info, addr)) - return FALSE; - - ++info->block_depth; - - return TRUE; -} - -/* End a block. */ - -static bfd_boolean -ieee_end_block (void *p, bfd_vma addr) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* The address we are given is the end of the block, but IEEE seems - to want to the address of the last byte in the block, so we - subtract one. */ - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, addr - 1)) - return FALSE; - - if (! ieee_end_range (info, addr)) - return FALSE; - - --info->block_depth; - - if (addr > info->highaddr) - info->highaddr = addr; - - return TRUE; -} - -/* End a function. */ - -static bfd_boolean -ieee_end_function (void *p) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->block_depth == 1); - - --info->block_depth; - - /* Now we can finish up fntype, and add it to the typdef section. - At this point, fntype is the 'x' type up to the argument count, - and fnargs is the argument types. We must add the argument - count, and we must add the level. FIXME: We don't record varargs - functions correctly. In fact, stabs debugging does not give us - enough information to do so. */ - if (! ieee_change_buffer (info, &info->fntype) - || ! ieee_write_number (info, info->fnargcount) - || ! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, 0)) - return FALSE; - - /* Make sure the typdef block has been started. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return FALSE; - } - - if (! ieee_append_buffer (info, &info->types, &info->fntype) - || ! ieee_append_buffer (info, &info->types, &info->fnargs)) - return FALSE; - - info->fnname = NULL; - if (! ieee_init_buffer (info, &info->fntype) - || ! ieee_init_buffer (info, &info->fnargs)) - return FALSE; - info->fnargcount = 0; - - return TRUE; -} - -/* Record line number information. */ - -static bfd_boolean -ieee_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr) -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->filename != NULL); - - /* The HP simulator seems to get confused when more than one line is - listed for the same address, at least if they are in different - files. We handle this by always listing the last line for a - given address, since that seems to be the one that gdb uses. */ - if (info->pending_lineno_filename != NULL - && addr != info->pending_lineno_addr) - { - /* Make sure we have a line number block. */ - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos)) - return FALSE; - } - else - { - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return FALSE; - info->lineno_filename = info->filename; - } - - if (filename_cmp (info->pending_lineno_filename, - info->lineno_filename) != 0) - { - if (filename_cmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. Close the block for the - included file. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return FALSE; - if (filename_cmp (info->filename, - info->pending_lineno_filename) == 0) - { - /* We need a new NN record, and we aren't about to - output one. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return FALSE; - } - } - if (filename_cmp (info->filename, - info->pending_lineno_filename) != 0) - { - /* We are not changing to the main file. Open a block for - the new included file. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->pending_lineno_filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return FALSE; - } - info->lineno_filename = info->pending_lineno_filename; - } - - if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 7) - || ! ieee_write_number (info, info->pending_lineno) - || ! ieee_write_number (info, 0) - || ! ieee_write_asn (info, info->lineno_name_indx, - info->pending_lineno_addr)) - return FALSE; - } - - info->pending_lineno_filename = filename; - info->pending_lineno = lineno; - info->pending_lineno_addr = addr; - - return TRUE; -} diff --git a/contrib/binutils-2.22/binutils/is-ranlib.c b/contrib/binutils-2.22/binutils/is-ranlib.c deleted file mode 100644 index 947d8d2846..0000000000 --- a/contrib/binutils-2.22/binutils/is-ranlib.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2007 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Linked with ar.o to flag that this program is 'ranlib' (not 'ar'). */ - -int is_ranlib = 1; diff --git a/contrib/binutils-2.22/binutils/is-strip.c b/contrib/binutils-2.22/binutils/is-strip.c deleted file mode 100644 index 1fddbe2e13..0000000000 --- a/contrib/binutils-2.22/binutils/is-strip.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2007 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Linked with objcopy.o to flag that this program is 'strip' (not - 'objcopy'). */ - -int is_strip = 1; diff --git a/contrib/binutils-2.22/binutils/nm.c b/contrib/binutils-2.22/binutils/nm.c deleted file mode 100644 index 04067b1581..0000000000 --- a/contrib/binutils-2.22/binutils/nm.c +++ /dev/null @@ -1,1695 +0,0 @@ -/* nm.c -- Describe symbol table of a rel file. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "progress.h" -#include "getopt.h" -#include "aout/stab_gnu.h" -#include "aout/ranlib.h" -#include "demangle.h" -#include "libiberty.h" -#include "elf-bfd.h" -#include "elf/common.h" -#include "bucomm.h" -#include "plugin.h" - -/* When sorting by size, we use this structure to hold the size and a - pointer to the minisymbol. */ - -struct size_sym -{ - const void *minisym; - bfd_vma size; -}; - -/* When fetching relocs, we use this structure to pass information to - get_relocs. */ - -struct get_relocs_info -{ - asection **secs; - arelent ***relocs; - long *relcount; - asymbol **syms; -}; - -struct extended_symbol_info -{ - symbol_info *sinfo; - bfd_vma ssize; - elf_symbol_type *elfinfo; - /* FIXME: We should add more fields for Type, Line, Section. */ -}; -#define SYM_NAME(sym) (sym->sinfo->name) -#define SYM_VALUE(sym) (sym->sinfo->value) -#define SYM_TYPE(sym) (sym->sinfo->type) -#define SYM_STAB_NAME(sym) (sym->sinfo->stab_name) -#define SYM_STAB_DESC(sym) (sym->sinfo->stab_desc) -#define SYM_STAB_OTHER(sym) (sym->sinfo->stab_other) -#define SYM_SIZE(sym) \ - (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize) - -/* The output formatting functions. */ -static void print_object_filename_bsd (char *); -static void print_object_filename_sysv (char *); -static void print_object_filename_posix (char *); -static void print_archive_filename_bsd (char *); -static void print_archive_filename_sysv (char *); -static void print_archive_filename_posix (char *); -static void print_archive_member_bsd (char *, const char *); -static void print_archive_member_sysv (char *, const char *); -static void print_archive_member_posix (char *, const char *); -static void print_symbol_filename_bsd (bfd *, bfd *); -static void print_symbol_filename_sysv (bfd *, bfd *); -static void print_symbol_filename_posix (bfd *, bfd *); -static void print_value (bfd *, bfd_vma); -static void print_symbol_info_bsd (struct extended_symbol_info *, bfd *); -static void print_symbol_info_sysv (struct extended_symbol_info *, bfd *); -static void print_symbol_info_posix (struct extended_symbol_info *, bfd *); - -/* Support for different output formats. */ -struct output_fns - { - /* Print the name of an object file given on the command line. */ - void (*print_object_filename) (char *); - - /* Print the name of an archive file given on the command line. */ - void (*print_archive_filename) (char *); - - /* Print the name of an archive member file. */ - void (*print_archive_member) (char *, const char *); - - /* Print the name of the file (and archive, if there is one) - containing a symbol. */ - void (*print_symbol_filename) (bfd *, bfd *); - - /* Print a line of information about a symbol. */ - void (*print_symbol_info) (struct extended_symbol_info *, bfd *); - }; - -static struct output_fns formats[] = -{ - {print_object_filename_bsd, - print_archive_filename_bsd, - print_archive_member_bsd, - print_symbol_filename_bsd, - print_symbol_info_bsd}, - {print_object_filename_sysv, - print_archive_filename_sysv, - print_archive_member_sysv, - print_symbol_filename_sysv, - print_symbol_info_sysv}, - {print_object_filename_posix, - print_archive_filename_posix, - print_archive_member_posix, - print_symbol_filename_posix, - print_symbol_info_posix} -}; - -/* Indices in `formats'. */ -#define FORMAT_BSD 0 -#define FORMAT_SYSV 1 -#define FORMAT_POSIX 2 -#define FORMAT_DEFAULT FORMAT_BSD - -/* The output format to use. */ -static struct output_fns *format = &formats[FORMAT_DEFAULT]; - -/* Command options. */ - -static int do_demangle = 0; /* Pretty print C++ symbol names. */ -static int external_only = 0; /* Print external symbols only. */ -static int defined_only = 0; /* Print defined symbols only. */ -static int no_sort = 0; /* Don't sort; print syms in order found. */ -static int print_debug_syms = 0;/* Print debugger-only symbols too. */ -static int print_armap = 0; /* Describe __.SYMDEF data in archive files. */ -static int print_size = 0; /* Print size of defined symbols. */ -static int reverse_sort = 0; /* Sort in downward(alpha or numeric) order. */ -static int sort_numerically = 0;/* Sort in numeric rather than alpha order. */ -static int sort_by_size = 0; /* Sort by size of symbol. */ -static int undefined_only = 0; /* Print undefined symbols only. */ -static int dynamic = 0; /* Print dynamic symbols. */ -static int show_version = 0; /* Show the version number. */ -static int show_stats = 0; /* Show statistics. */ -static int show_synthetic = 0; /* Display synthesized symbols too. */ -static int line_numbers = 0; /* Print line numbers for symbols. */ -static int allow_special_symbols = 0; /* Allow special symbols. */ - -/* When to print the names of files. Not mutually exclusive in SYSV format. */ -static int filename_per_file = 0; /* Once per file, on its own line. */ -static int filename_per_symbol = 0; /* Once per symbol, at start of line. */ - -/* Print formats for printing a symbol value. */ -static char value_format_32bit[] = "%08lx"; -#if BFD_HOST_64BIT_LONG -static char value_format_64bit[] = "%016lx"; -#elif BFD_HOST_64BIT_LONG_LONG -#ifndef __MSVCRT__ -static char value_format_64bit[] = "%016llx"; -#else -static char value_format_64bit[] = "%016I64x"; -#endif -#endif -static int print_width = 0; -static int print_radix = 16; -/* Print formats for printing stab info. */ -static char other_format[] = "%02x"; -static char desc_format[] = "%04x"; - -static char *target = NULL; -static char *plugin_target = NULL; - -/* Used to cache the line numbers for a BFD. */ -static bfd *lineno_cache_bfd; -static bfd *lineno_cache_rel_bfd; - -#define OPTION_TARGET 200 -#define OPTION_PLUGIN 201 - -static struct option long_options[] = -{ - {"debug-syms", no_argument, &print_debug_syms, 1}, - {"demangle", optional_argument, 0, 'C'}, - {"dynamic", no_argument, &dynamic, 1}, - {"extern-only", no_argument, &external_only, 1}, - {"format", required_argument, 0, 'f'}, - {"help", no_argument, 0, 'h'}, - {"line-numbers", no_argument, 0, 'l'}, - {"no-cplus", no_argument, &do_demangle, 0}, /* Linux compatibility. */ - {"no-demangle", no_argument, &do_demangle, 0}, - {"no-sort", no_argument, &no_sort, 1}, - {"numeric-sort", no_argument, &sort_numerically, 1}, - {"plugin", required_argument, 0, OPTION_PLUGIN}, - {"portability", no_argument, 0, 'P'}, - {"print-armap", no_argument, &print_armap, 1}, - {"print-file-name", no_argument, 0, 'o'}, - {"print-size", no_argument, 0, 'S'}, - {"radix", required_argument, 0, 't'}, - {"reverse-sort", no_argument, &reverse_sort, 1}, - {"size-sort", no_argument, &sort_by_size, 1}, - {"special-syms", no_argument, &allow_special_symbols, 1}, - {"stats", no_argument, &show_stats, 1}, - {"synthetic", no_argument, &show_synthetic, 1}, - {"target", required_argument, 0, OPTION_TARGET}, - {"defined-only", no_argument, &defined_only, 1}, - {"undefined-only", no_argument, &undefined_only, 1}, - {"version", no_argument, &show_version, 1}, - {0, no_argument, 0, 0} -}; - -/* Some error-reporting functions. */ - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name); - fprintf (stream, _(" List symbols in [file(s)] (a.out by default).\n")); - fprintf (stream, _(" The options are:\n\ - -a, --debug-syms Display debugger-only symbols\n\ - -A, --print-file-name Print name of the input file before every symbol\n\ - -B Same as --format=bsd\n\ - -C, --demangle[=STYLE] Decode low-level symbol names into user-level names\n\ - The STYLE, if specified, can be `auto' (the default),\n\ - `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\ - or `gnat'\n\ - --no-demangle Do not demangle low-level symbol names\n\ - -D, --dynamic Display dynamic symbols instead of normal symbols\n\ - --defined-only Display only defined symbols\n\ - -e (ignored)\n\ - -f, --format=FORMAT Use the output format FORMAT. FORMAT can be `bsd',\n\ - `sysv' or `posix'. The default is `bsd'\n\ - -g, --extern-only Display only external symbols\n\ - -l, --line-numbers Use debugging information to find a filename and\n\ - line number for each symbol\n\ - -n, --numeric-sort Sort symbols numerically by address\n\ - -o Same as -A\n\ - -p, --no-sort Do not sort the symbols\n\ - -P, --portability Same as --format=posix\n\ - -r, --reverse-sort Reverse the sense of the sort\n")); -#if BFD_SUPPORTS_PLUGINS - fprintf (stream, _("\ - --plugin NAME Load the specified plugin\n")); -#endif - fprintf (stream, _("\ - -S, --print-size Print size of defined symbols\n\ - -s, --print-armap Include index for symbols from archive members\n\ - --size-sort Sort symbols by size\n\ - --special-syms Include special symbols in the output\n\ - --synthetic Display synthetic symbols as well\n\ - -t, --radix=RADIX Use RADIX for printing symbol values\n\ - --target=BFDNAME Specify the target object format as BFDNAME\n\ - -u, --undefined-only Display only undefined symbols\n\ - -X 32_64 (ignored)\n\ - @FILE Read options from FILE\n\ - -h, --help Display this information\n\ - -V, --version Display this program's version number\n\ -\n")); - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO); - exit (status); -} - -/* Set the radix for the symbol value and size according to RADIX. */ - -static void -set_print_radix (char *radix) -{ - switch (*radix) - { - case 'x': - break; - case 'd': - case 'o': - if (*radix == 'd') - print_radix = 10; - else - print_radix = 8; - value_format_32bit[4] = *radix; -#if BFD_HOST_64BIT_LONG - value_format_64bit[5] = *radix; -#elif BFD_HOST_64BIT_LONG_LONG -#ifndef __MSVCRT__ - value_format_64bit[6] = *radix; -#else - value_format_64bit[7] = *radix; -#endif -#endif - other_format[3] = desc_format[3] = *radix; - break; - default: - fatal (_("%s: invalid radix"), radix); - } -} - -static void -set_output_format (char *f) -{ - int i; - - switch (*f) - { - case 'b': - case 'B': - i = FORMAT_BSD; - break; - case 'p': - case 'P': - i = FORMAT_POSIX; - break; - case 's': - case 'S': - i = FORMAT_SYSV; - break; - default: - fatal (_("%s: invalid output format"), f); - } - format = &formats[i]; -} - -static const char * -get_symbol_type (unsigned int type) -{ - static char buff [32]; - - switch (type) - { - case STT_NOTYPE: return "NOTYPE"; - case STT_OBJECT: return "OBJECT"; - case STT_FUNC: return "FUNC"; - case STT_SECTION: return "SECTION"; - case STT_FILE: return "FILE"; - case STT_COMMON: return "COMMON"; - case STT_TLS: return "TLS"; - default: - if (type >= STT_LOPROC && type <= STT_HIPROC) - sprintf (buff, _(": %d"), type); - else if (type >= STT_LOOS && type <= STT_HIOS) - sprintf (buff, _(": %d"), type); - else - sprintf (buff, _(": %d"), type); - return buff; - } -} - -/* Print symbol name NAME, read from ABFD, with printf format FORM, - demangling it if requested. */ - -static void -print_symname (const char *form, const char *name, bfd *abfd) -{ - if (do_demangle && *name) - { - char *res = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); - - if (res != NULL) - { - printf (form, res); - free (res); - return; - } - } - - printf (form, name); -} - -static void -print_symdef_entry (bfd *abfd) -{ - symindex idx = BFD_NO_MORE_SYMBOLS; - carsym *thesym; - bfd_boolean everprinted = FALSE; - - for (idx = bfd_get_next_mapent (abfd, idx, &thesym); - idx != BFD_NO_MORE_SYMBOLS; - idx = bfd_get_next_mapent (abfd, idx, &thesym)) - { - bfd *elt; - if (!everprinted) - { - printf (_("\nArchive index:\n")); - everprinted = TRUE; - } - elt = bfd_get_elt_at_index (abfd, idx); - if (elt == NULL) - bfd_fatal ("bfd_get_elt_at_index"); - if (thesym->name != (char *) NULL) - { - print_symname ("%s", thesym->name, abfd); - printf (" in %s\n", bfd_get_filename (elt)); - } - } -} - -/* Choose which symbol entries to print; - compact them downward to get rid of the rest. - Return the number of symbols to be printed. */ - -static long -filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, - long symcount, unsigned int size) -{ - bfd_byte *from, *fromend, *to; - asymbol *store; - - store = bfd_make_empty_symbol (abfd); - if (store == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - from = (bfd_byte *) minisyms; - fromend = from + symcount * size; - to = (bfd_byte *) minisyms; - - for (; from < fromend; from += size) - { - int keep = 0; - asymbol *sym; - - PROGRESS (1); - - sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, (const void *) from, store); - if (sym == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - if (undefined_only) - keep = bfd_is_und_section (sym->section); - else if (external_only) - keep = ((sym->flags & BSF_GLOBAL) != 0 - || (sym->flags & BSF_WEAK) != 0 - /* PR binutls/12753: Unique symbols are global too. */ - || (sym->flags & BSF_GNU_UNIQUE) != 0 - || bfd_is_und_section (sym->section) - || bfd_is_com_section (sym->section)); - else - keep = 1; - - if (keep - && ! print_debug_syms - && (sym->flags & BSF_DEBUGGING) != 0) - keep = 0; - - if (keep - && sort_by_size - && (bfd_is_abs_section (sym->section) - || bfd_is_und_section (sym->section))) - keep = 0; - - if (keep - && defined_only) - { - if (bfd_is_und_section (sym->section)) - keep = 0; - } - - if (keep - && bfd_is_target_special_symbol (abfd, sym) - && ! allow_special_symbols) - keep = 0; - - if (keep) - { - if (to != from) - memcpy (to, from, size); - to += size; - } - } - - return (to - (bfd_byte *) minisyms) / size; -} - -/* These globals are used to pass information into the sorting - routines. */ -static bfd *sort_bfd; -static bfd_boolean sort_dynamic; -static asymbol *sort_x; -static asymbol *sort_y; - -/* Symbol-sorting predicates */ -#define valueof(x) ((x)->section->vma + (x)->value) - -/* Numeric sorts. Undefined symbols are always considered "less than" - defined symbols with zero values. Common symbols are not treated - specially -- i.e., their sizes are used as their "values". */ - -static int -non_numeric_forward (const void *P_x, const void *P_y) -{ - asymbol *x, *y; - const char *xn, *yn; - - x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x); - y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y); - if (x == NULL || y == NULL) - bfd_fatal (bfd_get_filename (sort_bfd)); - - xn = bfd_asymbol_name (x); - yn = bfd_asymbol_name (y); - - if (yn == NULL) - return xn != NULL; - if (xn == NULL) - return -1; - -#ifdef HAVE_STRCOLL - /* Solaris 2.5 has a bug in strcoll. - strcoll returns invalid values when confronted with empty strings. */ - if (*yn == '\0') - return *xn != '\0'; - if (*xn == '\0') - return -1; - - return strcoll (xn, yn); -#else - return strcmp (xn, yn); -#endif -} - -static int -non_numeric_reverse (const void *x, const void *y) -{ - return - non_numeric_forward (x, y); -} - -static int -numeric_forward (const void *P_x, const void *P_y) -{ - asymbol *x, *y; - asection *xs, *ys; - - x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x); - y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y); - if (x == NULL || y == NULL) - bfd_fatal (bfd_get_filename (sort_bfd)); - - xs = bfd_get_section (x); - ys = bfd_get_section (y); - - if (bfd_is_und_section (xs)) - { - if (! bfd_is_und_section (ys)) - return -1; - } - else if (bfd_is_und_section (ys)) - return 1; - else if (valueof (x) != valueof (y)) - return valueof (x) < valueof (y) ? -1 : 1; - - return non_numeric_forward (P_x, P_y); -} - -static int -numeric_reverse (const void *x, const void *y) -{ - return - numeric_forward (x, y); -} - -static int (*(sorters[2][2])) (const void *, const void *) = -{ - { non_numeric_forward, non_numeric_reverse }, - { numeric_forward, numeric_reverse } -}; - -/* This sort routine is used by sort_symbols_by_size. It is similar - to numeric_forward, but when symbols have the same value it sorts - by section VMA. This simplifies the sort_symbols_by_size code - which handles symbols at the end of sections. Also, this routine - tries to sort file names before other symbols with the same value. - That will make the file name have a zero size, which will make - sort_symbols_by_size choose the non file name symbol, leading to - more meaningful output. For similar reasons, this code sorts - gnu_compiled_* and gcc2_compiled before other symbols with the same - value. */ - -static int -size_forward1 (const void *P_x, const void *P_y) -{ - asymbol *x, *y; - asection *xs, *ys; - const char *xn, *yn; - size_t xnl, ynl; - int xf, yf; - - x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x); - y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y); - if (x == NULL || y == NULL) - bfd_fatal (bfd_get_filename (sort_bfd)); - - xs = bfd_get_section (x); - ys = bfd_get_section (y); - - if (bfd_is_und_section (xs)) - abort (); - if (bfd_is_und_section (ys)) - abort (); - - if (valueof (x) != valueof (y)) - return valueof (x) < valueof (y) ? -1 : 1; - - if (xs->vma != ys->vma) - return xs->vma < ys->vma ? -1 : 1; - - xn = bfd_asymbol_name (x); - yn = bfd_asymbol_name (y); - xnl = strlen (xn); - ynl = strlen (yn); - - /* The symbols gnu_compiled and gcc2_compiled convey even less - information than the file name, so sort them out first. */ - - xf = (strstr (xn, "gnu_compiled") != NULL - || strstr (xn, "gcc2_compiled") != NULL); - yf = (strstr (yn, "gnu_compiled") != NULL - || strstr (yn, "gcc2_compiled") != NULL); - - if (xf && ! yf) - return -1; - if (! xf && yf) - return 1; - - /* We use a heuristic for the file name. It may not work on non - Unix systems, but it doesn't really matter; the only difference - is precisely which symbol names get printed. */ - -#define file_symbol(s, sn, snl) \ - (((s)->flags & BSF_FILE) != 0 \ - || ((sn)[(snl) - 2] == '.' \ - && ((sn)[(snl) - 1] == 'o' \ - || (sn)[(snl) - 1] == 'a'))) - - xf = file_symbol (x, xn, xnl); - yf = file_symbol (y, yn, ynl); - - if (xf && ! yf) - return -1; - if (! xf && yf) - return 1; - - return non_numeric_forward (P_x, P_y); -} - -/* This sort routine is used by sort_symbols_by_size. It is sorting - an array of size_sym structures into size order. */ - -static int -size_forward2 (const void *P_x, const void *P_y) -{ - const struct size_sym *x = (const struct size_sym *) P_x; - const struct size_sym *y = (const struct size_sym *) P_y; - - if (x->size < y->size) - return reverse_sort ? 1 : -1; - else if (x->size > y->size) - return reverse_sort ? -1 : 1; - else - return sorters[0][reverse_sort] (x->minisym, y->minisym); -} - -/* Sort the symbols by size. ELF provides a size but for other formats - we have to make a guess by assuming that the difference between the - address of a symbol and the address of the next higher symbol is the - size. */ - -static long -sort_symbols_by_size (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, - long symcount, unsigned int size, - struct size_sym **symsizesp) -{ - struct size_sym *symsizes; - bfd_byte *from, *fromend; - asymbol *sym = NULL; - asymbol *store_sym, *store_next; - - qsort (minisyms, symcount, size, size_forward1); - - /* We are going to return a special set of symbols and sizes to - print. */ - symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym)); - *symsizesp = symsizes; - - /* Note that filter_symbols has already removed all absolute and - undefined symbols. Here we remove all symbols whose size winds - up as zero. */ - from = (bfd_byte *) minisyms; - fromend = from + symcount * size; - - store_sym = sort_x; - store_next = sort_y; - - if (from < fromend) - { - sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, (const void *) from, - store_sym); - if (sym == NULL) - bfd_fatal (bfd_get_filename (abfd)); - } - - for (; from < fromend; from += size) - { - asymbol *next; - asection *sec; - bfd_vma sz; - asymbol *temp; - - if (from + size < fromend) - { - next = bfd_minisymbol_to_symbol (abfd, - is_dynamic, - (const void *) (from + size), - store_next); - if (next == NULL) - bfd_fatal (bfd_get_filename (abfd)); - } - else - next = NULL; - - sec = bfd_get_section (sym); - - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size; - else if (bfd_is_com_section (sec)) - sz = sym->value; - else - { - if (from + size < fromend - && sec == bfd_get_section (next)) - sz = valueof (next) - valueof (sym); - else - sz = (bfd_get_section_vma (abfd, sec) - + bfd_section_size (abfd, sec) - - valueof (sym)); - } - - if (sz != 0) - { - symsizes->minisym = (const void *) from; - symsizes->size = sz; - ++symsizes; - } - - sym = next; - - temp = store_sym; - store_sym = store_next; - store_next = temp; - } - - symcount = symsizes - *symsizesp; - - /* We must now sort again by size. */ - qsort ((void *) *symsizesp, symcount, sizeof (struct size_sym), size_forward2); - - return symcount; -} - -/* This function is used to get the relocs for a particular section. - It is called via bfd_map_over_sections. */ - -static void -get_relocs (bfd *abfd, asection *sec, void *dataarg) -{ - struct get_relocs_info *data = (struct get_relocs_info *) dataarg; - - *data->secs = sec; - - if ((sec->flags & SEC_RELOC) == 0) - { - *data->relocs = NULL; - *data->relcount = 0; - } - else - { - long relsize; - - relsize = bfd_get_reloc_upper_bound (abfd, sec); - if (relsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - - *data->relocs = (arelent **) xmalloc (relsize); - *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs, - data->syms); - if (*data->relcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - } - - ++data->secs; - ++data->relocs; - ++data->relcount; -} - -/* Print a single symbol. */ - -static void -print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd) -{ - symbol_info syminfo; - struct extended_symbol_info info; - - PROGRESS (1); - - format->print_symbol_filename (archive_bfd, abfd); - - bfd_get_symbol_info (abfd, sym, &syminfo); - info.sinfo = &syminfo; - info.ssize = ssize; - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - info.elfinfo = (elf_symbol_type *) sym; - else - info.elfinfo = NULL; - format->print_symbol_info (&info, abfd); - - if (line_numbers) - { - static asymbol **syms; - static long symcount; - const char *filename, *functionname; - unsigned int lineno; - - /* We need to get the canonical symbols in order to call - bfd_find_nearest_line. This is inefficient, but, then, you - don't have to use --line-numbers. */ - if (abfd != lineno_cache_bfd && syms != NULL) - { - free (syms); - syms = NULL; - } - if (syms == NULL) - { - long symsize; - - symsize = bfd_get_symtab_upper_bound (abfd); - if (symsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - syms = (asymbol **) xmalloc (symsize); - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - lineno_cache_bfd = abfd; - } - - if (bfd_is_und_section (bfd_get_section (sym))) - { - static asection **secs; - static arelent ***relocs; - static long *relcount; - static unsigned int seccount; - unsigned int i; - const char *symname; - - /* For an undefined symbol, we try to find a reloc for the - symbol, and print the line number of the reloc. */ - if (abfd != lineno_cache_rel_bfd && relocs != NULL) - { - for (i = 0; i < seccount; i++) - if (relocs[i] != NULL) - free (relocs[i]); - free (secs); - free (relocs); - free (relcount); - secs = NULL; - relocs = NULL; - relcount = NULL; - } - - if (relocs == NULL) - { - struct get_relocs_info rinfo; - - seccount = bfd_count_sections (abfd); - - secs = (asection **) xmalloc (seccount * sizeof *secs); - relocs = (arelent ***) xmalloc (seccount * sizeof *relocs); - relcount = (long *) xmalloc (seccount * sizeof *relcount); - - rinfo.secs = secs; - rinfo.relocs = relocs; - rinfo.relcount = relcount; - rinfo.syms = syms; - bfd_map_over_sections (abfd, get_relocs, (void *) &rinfo); - lineno_cache_rel_bfd = abfd; - } - - symname = bfd_asymbol_name (sym); - for (i = 0; i < seccount; i++) - { - long j; - - for (j = 0; j < relcount[i]; j++) - { - arelent *r; - - r = relocs[i][j]; - if (r->sym_ptr_ptr != NULL - && (*r->sym_ptr_ptr)->section == sym->section - && (*r->sym_ptr_ptr)->value == sym->value - && strcmp (symname, - bfd_asymbol_name (*r->sym_ptr_ptr)) == 0 - && bfd_find_nearest_line (abfd, secs[i], syms, - r->address, &filename, - &functionname, &lineno) - && filename != NULL) - { - /* We only print the first one we find. */ - printf ("\t%s:%u", filename, lineno); - i = seccount; - break; - } - } - } - } - else if (bfd_get_section (sym)->owner == abfd) - { - if ((bfd_find_line (abfd, syms, sym, &filename, &lineno) - || bfd_find_nearest_line (abfd, bfd_get_section (sym), - syms, sym->value, &filename, - &functionname, &lineno)) - && filename != NULL - && lineno != 0) - printf ("\t%s:%u", filename, lineno); - } - } - - putchar ('\n'); -} - -/* Print the symbols when sorting by size. */ - -static void -print_size_symbols (bfd *abfd, bfd_boolean is_dynamic, - struct size_sym *symsizes, long symcount, - bfd *archive_bfd) -{ - asymbol *store; - struct size_sym *from, *fromend; - - store = bfd_make_empty_symbol (abfd); - if (store == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - from = symsizes; - fromend = from + symcount; - for (; from < fromend; from++) - { - asymbol *sym; - bfd_vma ssize; - - sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, from->minisym, store); - if (sym == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - /* For elf we have already computed the correct symbol size. */ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - ssize = from->size; - else - ssize = from->size - bfd_section_vma (abfd, bfd_get_section (sym)); - - print_symbol (abfd, sym, ssize, archive_bfd); - } -} - - -/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive - containing ABFD. */ - -static void -print_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, long symcount, - unsigned int size, bfd *archive_bfd) -{ - asymbol *store; - bfd_byte *from, *fromend; - - store = bfd_make_empty_symbol (abfd); - if (store == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - from = (bfd_byte *) minisyms; - fromend = from + symcount * size; - for (; from < fromend; from += size) - { - asymbol *sym; - - sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, from, store); - if (sym == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd); - } -} - -/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */ - -static void -display_rel_file (bfd *abfd, bfd *archive_bfd) -{ - long symcount; - void *minisyms; - unsigned int size; - struct size_sym *symsizes; - - if (! dynamic) - { - if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) - { - non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); - return; - } - } - - symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size); - if (symcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - - if (symcount == 0) - { - non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); - return; - } - - if (show_synthetic && size == sizeof (asymbol *)) - { - asymbol *synthsyms; - long synth_count; - asymbol **static_syms = NULL; - asymbol **dyn_syms = NULL; - long static_count = 0; - long dyn_count = 0; - - if (dynamic) - { - dyn_count = symcount; - dyn_syms = (asymbol **) minisyms; - } - else - { - long storage = bfd_get_dynamic_symtab_upper_bound (abfd); - - static_count = symcount; - static_syms = (asymbol **) minisyms; - - if (storage > 0) - { - dyn_syms = (asymbol **) xmalloc (storage); - dyn_count = bfd_canonicalize_dynamic_symtab (abfd, dyn_syms); - if (dyn_count < 0) - bfd_fatal (bfd_get_filename (abfd)); - } - } - synth_count = bfd_get_synthetic_symtab (abfd, static_count, static_syms, - dyn_count, dyn_syms, &synthsyms); - if (synth_count > 0) - { - asymbol **symp; - void *new_mini; - long i; - - new_mini = xmalloc ((symcount + synth_count + 1) * sizeof (*symp)); - symp = (asymbol **) new_mini; - memcpy (symp, minisyms, symcount * sizeof (*symp)); - symp += symcount; - for (i = 0; i < synth_count; i++) - *symp++ = synthsyms + i; - *symp = 0; - minisyms = new_mini; - symcount += synth_count; - } - } - - /* Discard the symbols we don't want to print. - It's OK to do this in place; we'll free the storage anyway - (after printing). */ - - symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size); - - symsizes = NULL; - if (! no_sort) - { - sort_bfd = abfd; - sort_dynamic = dynamic; - sort_x = bfd_make_empty_symbol (abfd); - sort_y = bfd_make_empty_symbol (abfd); - if (sort_x == NULL || sort_y == NULL) - bfd_fatal (bfd_get_filename (abfd)); - - if (! sort_by_size) - qsort (minisyms, symcount, size, - sorters[sort_numerically][reverse_sort]); - else - symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount, - size, &symsizes); - } - - if (! sort_by_size) - print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd); - else - print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd); - - free (minisyms); - free (symsizes); -} - -static void -set_print_width (bfd *file) -{ - print_width = bfd_get_arch_size (file); - - if (print_width == -1) - { - /* PR binutils/4292 - Guess the target's bitsize based on its name. - We assume here than any 64-bit format will include - "64" somewhere in its name. The only known exception - is the MMO object file format. */ - if (strstr (bfd_get_target (file), "64") != NULL - || strcmp (bfd_get_target (file), "mmo") == 0) - print_width = 64; - else - print_width = 32; - } -} - -static void -display_archive (bfd *file) -{ - bfd *arfile = NULL; - bfd *last_arfile = NULL; - char **matching; - - format->print_archive_filename (bfd_get_filename (file)); - - if (print_armap) - print_symdef_entry (file); - - for (;;) - { - PROGRESS (1); - - arfile = bfd_openr_next_archived_file (file, arfile); - - if (arfile == NULL) - { - if (bfd_get_error () != bfd_error_no_more_archived_files) - bfd_fatal (bfd_get_filename (file)); - break; - } - - if (bfd_check_format_matches (arfile, bfd_object, &matching)) - { - set_print_width (arfile); - format->print_archive_member (bfd_get_filename (file), - bfd_get_filename (arfile)); - display_rel_file (arfile, file); - } - else - { - bfd_nonfatal (bfd_get_filename (arfile)); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - } - - if (last_arfile != NULL) - { - bfd_close (last_arfile); - lineno_cache_bfd = NULL; - lineno_cache_rel_bfd = NULL; - } - last_arfile = arfile; - } - - if (last_arfile != NULL) - { - bfd_close (last_arfile); - lineno_cache_bfd = NULL; - lineno_cache_rel_bfd = NULL; - } -} - -static bfd_boolean -display_file (char *filename) -{ - bfd_boolean retval = TRUE; - bfd *file; - char **matching; - - if (get_file_size (filename) < 1) - return FALSE; - - file = bfd_openr (filename, target ? target : plugin_target); - if (file == NULL) - { - bfd_nonfatal (filename); - return FALSE; - } - - /* If printing line numbers, decompress the debug sections. */ - if (line_numbers) - file->flags |= BFD_DECOMPRESS; - - if (bfd_check_format (file, bfd_archive)) - { - display_archive (file); - } - else if (bfd_check_format_matches (file, bfd_object, &matching)) - { - set_print_width (file); - format->print_object_filename (filename); - display_rel_file (file, NULL); - } - else - { - bfd_nonfatal (filename); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - retval = FALSE; - } - - if (!bfd_close (file)) - bfd_fatal (filename); - - lineno_cache_bfd = NULL; - lineno_cache_rel_bfd = NULL; - - return retval; -} - -/* The following 3 groups of functions are called unconditionally, - once at the start of processing each file of the appropriate type. - They should check `filename_per_file' and `filename_per_symbol', - as appropriate for their output format, to determine whether to - print anything. */ - -/* Print the name of an object file given on the command line. */ - -static void -print_object_filename_bsd (char *filename) -{ - if (filename_per_file && !filename_per_symbol) - printf ("\n%s:\n", filename); -} - -static void -print_object_filename_sysv (char *filename) -{ - if (undefined_only) - printf (_("\n\nUndefined symbols from %s:\n\n"), filename); - else - printf (_("\n\nSymbols from %s:\n\n"), filename); - if (print_width == 32) - printf (_("\ -Name Value Class Type Size Line Section\n\n")); - else - printf (_("\ -Name Value Class Type Size Line Section\n\n")); -} - -static void -print_object_filename_posix (char *filename) -{ - if (filename_per_file && !filename_per_symbol) - printf ("%s:\n", filename); -} - -/* Print the name of an archive file given on the command line. */ - -static void -print_archive_filename_bsd (char *filename) -{ - if (filename_per_file) - printf ("\n%s:\n", filename); -} - -static void -print_archive_filename_sysv (char *filename ATTRIBUTE_UNUSED) -{ -} - -static void -print_archive_filename_posix (char *filename ATTRIBUTE_UNUSED) -{ -} - -/* Print the name of an archive member file. */ - -static void -print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED, - const char *filename) -{ - if (!filename_per_symbol) - printf ("\n%s:\n", filename); -} - -static void -print_archive_member_sysv (char *archive, const char *filename) -{ - if (undefined_only) - printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename); - else - printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename); - if (print_width == 32) - printf (_("\ -Name Value Class Type Size Line Section\n\n")); - else - printf (_("\ -Name Value Class Type Size Line Section\n\n")); -} - -static void -print_archive_member_posix (char *archive, const char *filename) -{ - if (!filename_per_symbol) - printf ("%s[%s]:\n", archive, filename); -} - -/* Print the name of the file (and archive, if there is one) - containing a symbol. */ - -static void -print_symbol_filename_bsd (bfd *archive_bfd, bfd *abfd) -{ - if (filename_per_symbol) - { - if (archive_bfd) - printf ("%s:", bfd_get_filename (archive_bfd)); - printf ("%s:", bfd_get_filename (abfd)); - } -} - -static void -print_symbol_filename_sysv (bfd *archive_bfd, bfd *abfd) -{ - if (filename_per_symbol) - { - if (archive_bfd) - printf ("%s:", bfd_get_filename (archive_bfd)); - printf ("%s:", bfd_get_filename (abfd)); - } -} - -static void -print_symbol_filename_posix (bfd *archive_bfd, bfd *abfd) -{ - if (filename_per_symbol) - { - if (archive_bfd) - printf ("%s[%s]: ", bfd_get_filename (archive_bfd), - bfd_get_filename (abfd)); - else - printf ("%s: ", bfd_get_filename (abfd)); - } -} - -/* Print a symbol value. */ - -static void -print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val) -{ - switch (print_width) - { - case 32: - printf (value_format_32bit, (unsigned long) val); - break; - - case 64: -#if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG - printf (value_format_64bit, val); -#else - /* We have a 64 bit value to print, but the host is only 32 bit. */ - if (print_radix == 16) - bfd_fprintf_vma (abfd, stdout, val); - else - { - char buf[30]; - char *s; - - s = buf + sizeof buf; - *--s = '\0'; - while (val > 0) - { - *--s = (val % print_radix) + '0'; - val /= print_radix; - } - while ((buf + sizeof buf - 1) - s < 16) - *--s = '0'; - printf ("%s", s); - } -#endif - break; - - default: - fatal (_("Print width has not been initialized (%d)"), print_width); - break; - } -} - -/* Print a line of information about a symbol. */ - -static void -print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd) -{ - if (bfd_is_undefined_symclass (SYM_TYPE (info))) - { - if (print_width == 64) - printf (" "); - printf (" "); - } - else - { - /* Normally we print the value of the symbol. If we are printing the - size or sorting by size then we print its size, except for the - (weird) special case where both flags are defined, in which case we - print both values. This conforms to documented behaviour. */ - if (sort_by_size && !print_size) - print_value (abfd, SYM_SIZE (info)); - else - print_value (abfd, SYM_VALUE (info)); - - if (print_size && SYM_SIZE (info)) - { - printf (" "); - print_value (abfd, SYM_SIZE (info)); - } - } - - printf (" %c", SYM_TYPE (info)); - - if (SYM_TYPE (info) == '-') - { - /* A stab. */ - printf (" "); - printf (other_format, SYM_STAB_OTHER (info)); - printf (" "); - printf (desc_format, SYM_STAB_DESC (info)); - printf (" %5s", SYM_STAB_NAME (info)); - } - print_symname (" %s", SYM_NAME (info), abfd); -} - -static void -print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd) -{ - print_symname ("%-20s|", SYM_NAME (info), abfd); - - if (bfd_is_undefined_symclass (SYM_TYPE (info))) - { - if (print_width == 32) - printf (" "); - else - printf (" "); - } - else - print_value (abfd, SYM_VALUE (info)); - - printf ("| %c |", SYM_TYPE (info)); - - if (SYM_TYPE (info) == '-') - { - /* A stab. */ - printf ("%18s| ", SYM_STAB_NAME (info)); /* (C) Type. */ - printf (desc_format, SYM_STAB_DESC (info)); /* Size. */ - printf ("| |"); /* Line, Section. */ - } - else - { - /* Type, Size, Line, Section */ - if (info->elfinfo) - printf ("%18s|", - get_symbol_type (ELF_ST_TYPE (info->elfinfo->internal_elf_sym.st_info))); - else - printf (" |"); - - if (SYM_SIZE (info)) - print_value (abfd, SYM_SIZE (info)); - else - { - if (print_width == 32) - printf (" "); - else - printf (" "); - } - - if (info->elfinfo) - printf("| |%s", info->elfinfo->symbol.section->name); - else - printf("| |"); - } -} - -static void -print_symbol_info_posix (struct extended_symbol_info *info, bfd *abfd) -{ - print_symname ("%s ", SYM_NAME (info), abfd); - printf ("%c ", SYM_TYPE (info)); - - if (bfd_is_undefined_symclass (SYM_TYPE (info))) - printf (" "); - else - { - print_value (abfd, SYM_VALUE (info)); - printf (" "); - if (SYM_SIZE (info)) - print_value (abfd, SYM_SIZE (info)); - } -} - -int -main (int argc, char **argv) -{ - int c; - int retval; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); - setlocale (LC_COLLATE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = *argv; - xmalloc_set_program_name (program_name); -#if BFD_SUPPORTS_PLUGINS - bfd_plugin_set_program_name (program_name); -#endif - - START_PROGRESS (program_name, 0); - - expandargv (&argc, &argv); - - bfd_init (); - set_default_bfd_target (); - - while ((c = getopt_long (argc, argv, "aABCDef:gHhlnopPrSst:uvVvX:", - long_options, (int *) 0)) != EOF) - { - switch (c) - { - case 'a': - print_debug_syms = 1; - break; - case 'A': - case 'o': - filename_per_symbol = 1; - break; - case 'B': /* For MIPS compatibility. */ - set_output_format ("bsd"); - break; - case 'C': - do_demangle = 1; - if (optarg != NULL) - { - enum demangling_styles style; - - style = cplus_demangle_name_to_style (optarg); - if (style == unknown_demangling) - fatal (_("unknown demangling style `%s'"), - optarg); - - cplus_demangle_set_style (style); - } - break; - case 'D': - dynamic = 1; - break; - case 'e': - /* Ignored for HP/UX compatibility. */ - break; - case 'f': - set_output_format (optarg); - break; - case 'g': - external_only = 1; - break; - case 'H': - case 'h': - usage (stdout, 0); - case 'l': - line_numbers = 1; - break; - case 'n': - case 'v': - sort_numerically = 1; - break; - case 'p': - no_sort = 1; - break; - case 'P': - set_output_format ("posix"); - break; - case 'r': - reverse_sort = 1; - break; - case 's': - print_armap = 1; - break; - case 'S': - print_size = 1; - break; - case 't': - set_print_radix (optarg); - break; - case 'u': - undefined_only = 1; - break; - case 'V': - show_version = 1; - break; - case 'X': - /* Ignored for (partial) AIX compatibility. On AIX, the - argument has values 32, 64, or 32_64, and specifies that - only 32-bit, only 64-bit, or both kinds of objects should - be examined. The default is 32. So plain AIX nm on a - library archive with both kinds of objects will ignore - the 64-bit ones. For GNU nm, the default is and always - has been -X 32_64, and other options are not supported. */ - if (strcmp (optarg, "32_64") != 0) - fatal (_("Only -X 32_64 is supported")); - break; - - case OPTION_TARGET: /* --target */ - target = optarg; - break; - - case OPTION_PLUGIN: /* --plugin */ -#if BFD_SUPPORTS_PLUGINS - plugin_target = "plugin"; - bfd_plugin_set_plugin (optarg); -#else - fatal (_("sorry - this program has been built without plugin support\n")); -#endif - break; - - case 0: /* A long option that just sets a flag. */ - break; - - default: - usage (stderr, 1); - } - } - - if (show_version) - print_version ("nm"); - - if (sort_by_size && undefined_only) - { - non_fatal (_("Using the --size-sort and --undefined-only options together")); - non_fatal (_("will produce no output, since undefined symbols have no size.")); - return 0; - } - - /* OK, all options now parsed. If no filename specified, do a.out. */ - if (optind == argc) - return !display_file ("a.out"); - - retval = 0; - - if (argc - optind > 1) - filename_per_file = 1; - - /* We were given several filenames to do. */ - while (optind < argc) - { - PROGRESS (1); - if (!display_file (argv[optind++])) - retval++; - } - - END_PROGRESS (program_name); - -#ifdef HAVE_SBRK - if (show_stats) - { - char *lim = (char *) sbrk (0); - - non_fatal (_("data size %ld"), (long) (lim - (char *) &environ)); - } -#endif - - exit (retval); - return retval; -} diff --git a/contrib/binutils-2.22/binutils/not-ranlib.c b/contrib/binutils-2.22/binutils/not-ranlib.c deleted file mode 100644 index 6431f8413f..0000000000 --- a/contrib/binutils-2.22/binutils/not-ranlib.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2007 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Linked with ar.o to flag that this program is 'ar' (not 'ranlib'). */ - -int is_ranlib = 0; diff --git a/contrib/binutils-2.22/binutils/not-strip.c b/contrib/binutils-2.22/binutils/not-strip.c deleted file mode 100644 index 8ffbba6b25..0000000000 --- a/contrib/binutils-2.22/binutils/not-strip.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2007 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Linked with objcopy.o to flag that this program is 'objcopy' (not - 'strip'). */ - -int is_strip = 0; diff --git a/contrib/binutils-2.22/binutils/objcopy.c b/contrib/binutils-2.22/binutils/objcopy.c deleted file mode 100644 index 31ac0a2bb3..0000000000 --- a/contrib/binutils-2.22/binutils/objcopy.c +++ /dev/null @@ -1,4045 +0,0 @@ -/* objcopy.c -- copy object file from input to output, optionally massaging it. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "progress.h" -#include "getopt.h" -#include "libiberty.h" -#include "bucomm.h" -#include "budbg.h" -#include "filenames.h" -#include "fnmatch.h" -#include "elf-bfd.h" -#include -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* FIXME: See bfd/peXXigen.c for why we include an architecture specific - header in generic PE code. */ -#include "coff/i386.h" -#include "coff/pe.h" - -static bfd_vma pe_file_alignment = (bfd_vma) -1; -static bfd_vma pe_heap_commit = (bfd_vma) -1; -static bfd_vma pe_heap_reserve = (bfd_vma) -1; -static bfd_vma pe_image_base = (bfd_vma) -1; -static bfd_vma pe_section_alignment = (bfd_vma) -1; -static bfd_vma pe_stack_commit = (bfd_vma) -1; -static bfd_vma pe_stack_reserve = (bfd_vma) -1; -static short pe_subsystem = -1; -static short pe_major_subsystem_version = -1; -static short pe_minor_subsystem_version = -1; - -struct is_specified_symbol_predicate_data -{ - const char *name; - bfd_boolean found; -}; - -/* A list to support redefine_sym. */ -struct redefine_node -{ - char *source; - char *target; - struct redefine_node *next; -}; - -typedef struct section_rename -{ - const char * old_name; - const char * new_name; - flagword flags; - struct section_rename * next; -} -section_rename; - -/* List of sections to be renamed. */ -static section_rename *section_rename_list; - -static asymbol **isympp = NULL; /* Input symbols. */ -static asymbol **osympp = NULL; /* Output symbols that survive stripping. */ - -/* If `copy_byte' >= 0, copy 'copy_width' byte(s) of every `interleave' bytes. */ -static int copy_byte = -1; -static int interleave = 0; /* Initialised to 4 in copy_main(). */ -static int copy_width = 1; - -static bfd_boolean verbose; /* Print file and target names. */ -static bfd_boolean preserve_dates; /* Preserve input file timestamp. */ -static int status = 0; /* Exit status. */ - -enum strip_action - { - STRIP_UNDEF, - STRIP_NONE, /* Don't strip. */ - STRIP_DEBUG, /* Strip all debugger symbols. */ - STRIP_UNNEEDED, /* Strip unnecessary symbols. */ - STRIP_NONDEBUG, /* Strip everything but debug info. */ - STRIP_ALL /* Strip all symbols. */ - }; - -/* Which symbols to remove. */ -static enum strip_action strip_symbols; - -enum locals_action - { - LOCALS_UNDEF, - LOCALS_START_L, /* Discard locals starting with L. */ - LOCALS_ALL /* Discard all locals. */ - }; - -/* Which local symbols to remove. Overrides STRIP_ALL. */ -static enum locals_action discard_locals; - -/* What kind of change to perform. */ -enum change_action -{ - CHANGE_IGNORE, - CHANGE_MODIFY, - CHANGE_SET -}; - -/* Structure used to hold lists of sections and actions to take. */ -struct section_list -{ - struct section_list * next; /* Next section to change. */ - const char * name; /* Section name. */ - bfd_boolean used; /* Whether this entry was used. */ - bfd_boolean remove; /* Whether to remove this section. */ - bfd_boolean copy; /* Whether to copy this section. */ - enum change_action change_vma;/* Whether to change or set VMA. */ - bfd_vma vma_val; /* Amount to change by or set to. */ - enum change_action change_lma;/* Whether to change or set LMA. */ - bfd_vma lma_val; /* Amount to change by or set to. */ - bfd_boolean set_flags; /* Whether to set the section flags. */ - flagword flags; /* What to set the section flags to. */ -}; - -static struct section_list *change_sections; - -/* TRUE if some sections are to be removed. */ -static bfd_boolean sections_removed; - -/* TRUE if only some sections are to be copied. */ -static bfd_boolean sections_copied; - -/* Changes to the start address. */ -static bfd_vma change_start = 0; -static bfd_boolean set_start_set = FALSE; -static bfd_vma set_start; - -/* Changes to section addresses. */ -static bfd_vma change_section_address = 0; - -/* Filling gaps between sections. */ -static bfd_boolean gap_fill_set = FALSE; -static bfd_byte gap_fill = 0; - -/* Pad to a given address. */ -static bfd_boolean pad_to_set = FALSE; -static bfd_vma pad_to; - -/* Use alternative machine code? */ -static unsigned long use_alt_mach_code = 0; - -/* Output BFD flags user wants to set or clear */ -static flagword bfd_flags_to_set; -static flagword bfd_flags_to_clear; - -/* List of sections to add. */ -struct section_add -{ - /* Next section to add. */ - struct section_add *next; - /* Name of section to add. */ - const char *name; - /* Name of file holding section contents. */ - const char *filename; - /* Size of file. */ - size_t size; - /* Contents of file. */ - bfd_byte *contents; - /* BFD section, after it has been added. */ - asection *section; -}; - -/* List of sections to add to the output BFD. */ -static struct section_add *add_sections; - -/* If non-NULL the argument to --add-gnu-debuglink. - This should be the filename to store in the .gnu_debuglink section. */ -static const char * gnu_debuglink_filename = NULL; - -/* Whether to convert debugging information. */ -static bfd_boolean convert_debugging = FALSE; - -/* Whether to compress/decompress DWARF debug sections. */ -static enum -{ - nothing, - compress, - decompress -} do_debug_sections = nothing; - -/* Whether to change the leading character in symbol names. */ -static bfd_boolean change_leading_char = FALSE; - -/* Whether to remove the leading character from global symbol names. */ -static bfd_boolean remove_leading_char = FALSE; - -/* Whether to permit wildcard in symbol comparison. */ -static bfd_boolean wildcard = FALSE; - -/* True if --localize-hidden is in effect. */ -static bfd_boolean localize_hidden = FALSE; - -/* List of symbols to strip, keep, localize, keep-global, weaken, - or redefine. */ -static htab_t strip_specific_htab = NULL; -static htab_t strip_unneeded_htab = NULL; -static htab_t keep_specific_htab = NULL; -static htab_t localize_specific_htab = NULL; -static htab_t globalize_specific_htab = NULL; -static htab_t keepglobal_specific_htab = NULL; -static htab_t weaken_specific_htab = NULL; -static struct redefine_node *redefine_sym_list = NULL; - -/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */ -static bfd_boolean weaken = FALSE; - -/* If this is TRUE, we retain BSF_FILE symbols. */ -static bfd_boolean keep_file_symbols = FALSE; - -/* Prefix symbols/sections. */ -static char *prefix_symbols_string = 0; -static char *prefix_sections_string = 0; -static char *prefix_alloc_sections_string = 0; - -/* True if --extract-symbol was passed on the command line. */ -static bfd_boolean extract_symbol = FALSE; - -/* If `reverse_bytes' is nonzero, then reverse the order of every chunk - of bytes within each output section. */ -static int reverse_bytes = 0; - -/* For Coff objects, we may want to allow or disallow long section names, - or preserve them where found in the inputs. Debug info relies on them. */ -enum long_section_name_handling - { - DISABLE, - ENABLE, - KEEP - }; - -/* The default long section handling mode is to preserve them. - This is also the only behaviour for 'strip'. */ -static enum long_section_name_handling long_section_names = KEEP; - -/* 150 isn't special; it's just an arbitrary non-ASCII char value. */ -enum command_line_switch - { - OPTION_ADD_SECTION=150, - OPTION_CHANGE_ADDRESSES, - OPTION_CHANGE_LEADING_CHAR, - OPTION_CHANGE_START, - OPTION_CHANGE_SECTION_ADDRESS, - OPTION_CHANGE_SECTION_LMA, - OPTION_CHANGE_SECTION_VMA, - OPTION_CHANGE_WARNINGS, - OPTION_COMPRESS_DEBUG_SECTIONS, - OPTION_DEBUGGING, - OPTION_DECOMPRESS_DEBUG_SECTIONS, - OPTION_GAP_FILL, - OPTION_NO_CHANGE_WARNINGS, - OPTION_PAD_TO, - OPTION_REMOVE_LEADING_CHAR, - OPTION_SET_SECTION_FLAGS, - OPTION_SET_START, - OPTION_STRIP_UNNEEDED, - OPTION_WEAKEN, - OPTION_REDEFINE_SYM, - OPTION_REDEFINE_SYMS, - OPTION_SREC_LEN, - OPTION_SREC_FORCES3, - OPTION_STRIP_SYMBOLS, - OPTION_STRIP_UNNEEDED_SYMBOL, - OPTION_STRIP_UNNEEDED_SYMBOLS, - OPTION_KEEP_SYMBOLS, - OPTION_LOCALIZE_HIDDEN, - OPTION_LOCALIZE_SYMBOLS, - OPTION_LONG_SECTION_NAMES, - OPTION_GLOBALIZE_SYMBOL, - OPTION_GLOBALIZE_SYMBOLS, - OPTION_KEEPGLOBAL_SYMBOLS, - OPTION_WEAKEN_SYMBOLS, - OPTION_RENAME_SECTION, - OPTION_ALT_MACH_CODE, - OPTION_PREFIX_SYMBOLS, - OPTION_PREFIX_SECTIONS, - OPTION_PREFIX_ALLOC_SECTIONS, - OPTION_FORMATS_INFO, - OPTION_ADD_GNU_DEBUGLINK, - OPTION_ONLY_KEEP_DEBUG, - OPTION_KEEP_FILE_SYMBOLS, - OPTION_READONLY_TEXT, - OPTION_WRITABLE_TEXT, - OPTION_PURE, - OPTION_IMPURE, - OPTION_EXTRACT_SYMBOL, - OPTION_REVERSE_BYTES, - OPTION_FILE_ALIGNMENT, - OPTION_HEAP, - OPTION_IMAGE_BASE, - OPTION_SECTION_ALIGNMENT, - OPTION_STACK, - OPTION_INTERLEAVE_WIDTH, - OPTION_SUBSYSTEM - }; - -/* Options to handle if running as "strip". */ - -static struct option strip_options[] = -{ - {"discard-all", no_argument, 0, 'x'}, - {"discard-locals", no_argument, 0, 'X'}, - {"format", required_argument, 0, 'F'}, /* Obsolete */ - {"help", no_argument, 0, 'h'}, - {"info", no_argument, 0, OPTION_FORMATS_INFO}, - {"input-format", required_argument, 0, 'I'}, /* Obsolete */ - {"input-target", required_argument, 0, 'I'}, - {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, - {"keep-symbol", required_argument, 0, 'K'}, - {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG}, - {"output-format", required_argument, 0, 'O'}, /* Obsolete */ - {"output-target", required_argument, 0, 'O'}, - {"output-file", required_argument, 0, 'o'}, - {"preserve-dates", no_argument, 0, 'p'}, - {"remove-section", required_argument, 0, 'R'}, - {"strip-all", no_argument, 0, 's'}, - {"strip-debug", no_argument, 0, 'S'}, - {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, - {"strip-symbol", required_argument, 0, 'N'}, - {"target", required_argument, 0, 'F'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"wildcard", no_argument, 0, 'w'}, - {0, no_argument, 0, 0} -}; - -/* Options to handle if running as "objcopy". */ - -static struct option copy_options[] = -{ - {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK}, - {"add-section", required_argument, 0, OPTION_ADD_SECTION}, - {"adjust-start", required_argument, 0, OPTION_CHANGE_START}, - {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES}, - {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, - {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, - {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, - {"binary-architecture", required_argument, 0, 'B'}, - {"byte", required_argument, 0, 'b'}, - {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, - {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, - {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, - {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, - {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, - {"change-start", required_argument, 0, OPTION_CHANGE_START}, - {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, - {"compress-debug-sections", no_argument, 0, OPTION_COMPRESS_DEBUG_SECTIONS}, - {"debugging", no_argument, 0, OPTION_DEBUGGING}, - {"decompress-debug-sections", no_argument, 0, OPTION_DECOMPRESS_DEBUG_SECTIONS}, - {"discard-all", no_argument, 0, 'x'}, - {"discard-locals", no_argument, 0, 'X'}, - {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL}, - {"format", required_argument, 0, 'F'}, /* Obsolete */ - {"gap-fill", required_argument, 0, OPTION_GAP_FILL}, - {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL}, - {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS}, - {"help", no_argument, 0, 'h'}, - {"impure", no_argument, 0, OPTION_IMPURE}, - {"info", no_argument, 0, OPTION_FORMATS_INFO}, - {"input-format", required_argument, 0, 'I'}, /* Obsolete */ - {"input-target", required_argument, 0, 'I'}, - {"interleave", optional_argument, 0, 'i'}, - {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH}, - {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS}, - {"keep-global-symbol", required_argument, 0, 'G'}, - {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS}, - {"keep-symbol", required_argument, 0, 'K'}, - {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS}, - {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN}, - {"localize-symbol", required_argument, 0, 'L'}, - {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS}, - {"long-section-names", required_argument, 0, OPTION_LONG_SECTION_NAMES}, - {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, - {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS}, - {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG}, - {"only-section", required_argument, 0, 'j'}, - {"output-format", required_argument, 0, 'O'}, /* Obsolete */ - {"output-target", required_argument, 0, 'O'}, - {"pad-to", required_argument, 0, OPTION_PAD_TO}, - {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS}, - {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS}, - {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS}, - {"preserve-dates", no_argument, 0, 'p'}, - {"pure", no_argument, 0, OPTION_PURE}, - {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT}, - {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM}, - {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS}, - {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, - {"remove-section", required_argument, 0, 'R'}, - {"rename-section", required_argument, 0, OPTION_RENAME_SECTION}, - {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES}, - {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS}, - {"set-start", required_argument, 0, OPTION_SET_START}, - {"srec-len", required_argument, 0, OPTION_SREC_LEN}, - {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3}, - {"strip-all", no_argument, 0, 'S'}, - {"strip-debug", no_argument, 0, 'g'}, - {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED}, - {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL}, - {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS}, - {"strip-symbol", required_argument, 0, 'N'}, - {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS}, - {"target", required_argument, 0, 'F'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"weaken", no_argument, 0, OPTION_WEAKEN}, - {"weaken-symbol", required_argument, 0, 'W'}, - {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS}, - {"wildcard", no_argument, 0, 'w'}, - {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT}, - {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT}, - {"heap", required_argument, 0, OPTION_HEAP}, - {"image-base", required_argument, 0 , OPTION_IMAGE_BASE}, - {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT}, - {"stack", required_argument, 0, OPTION_STACK}, - {"subsystem", required_argument, 0, OPTION_SUBSYSTEM}, - {0, no_argument, 0, 0} -}; - -/* IMPORTS */ -extern char *program_name; - -/* This flag distinguishes between strip and objcopy: - 1 means this is 'strip'; 0 means this is 'objcopy'. - -1 means if we should use argv[0] to decide. */ -extern int is_strip; - -/* The maximum length of an S record. This variable is declared in srec.c - and can be modified by the --srec-len parameter. */ -extern unsigned int Chunk; - -/* Restrict the generation of Srecords to type S3 only. - This variable is declare in bfd/srec.c and can be toggled - on by the --srec-forceS3 command line switch. */ -extern bfd_boolean S3Forced; - -/* Forward declarations. */ -static void setup_section (bfd *, asection *, void *); -static void setup_bfd_headers (bfd *, bfd *); -static void copy_section (bfd *, asection *, void *); -static void get_sections (bfd *, asection *, void *); -static int compare_section_lma (const void *, const void *); -static void mark_symbols_used_in_relocations (bfd *, asection *, void *); -static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***); -static const char *lookup_sym_redefinition (const char *); - -static void -copy_usage (FILE *stream, int exit_status) -{ - fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); - fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n")); - fprintf (stream, _(" The options are:\n")); - fprintf (stream, _("\ - -I --input-target Assume input file is in format \n\ - -O --output-target Create an output file in format \n\ - -B --binary-architecture Set output arch, when input is arch-less\n\ - -F --target Set both input and output format to \n\ - --debugging Convert debugging information, if possible\n\ - -p --preserve-dates Copy modified/access timestamps to the output\n\ - -j --only-section Only copy section into the output\n\ - --add-gnu-debuglink= Add section .gnu_debuglink linking to \n\ - -R --remove-section Remove section from the output\n\ - -S --strip-all Remove all symbol and relocation information\n\ - -g --strip-debug Remove all debugging symbols & sections\n\ - --strip-unneeded Remove all symbols not needed by relocations\n\ - -N --strip-symbol Do not copy symbol \n\ - --strip-unneeded-symbol \n\ - Do not copy symbol unless needed by\n\ - relocations\n\ - --only-keep-debug Strip everything but the debug information\n\ - --extract-symbol Remove section contents but keep symbols\n\ - -K --keep-symbol Do not strip symbol \n\ - --keep-file-symbols Do not strip file symbol(s)\n\ - --localize-hidden Turn all ELF hidden symbols into locals\n\ - -L --localize-symbol Force symbol to be marked as a local\n\ - --globalize-symbol Force symbol to be marked as a global\n\ - -G --keep-global-symbol Localize all symbols except \n\ - -W --weaken-symbol Force symbol to be marked as a weak\n\ - --weaken Force all global symbols to be marked as weak\n\ - -w --wildcard Permit wildcard in symbol comparison\n\ - -x --discard-all Remove all non-global symbols\n\ - -X --discard-locals Remove any compiler-generated symbols\n\ - -i --interleave [] Only copy N out of every bytes\n\ - --interleave-width Set N for --interleave\n\ - -b --byte Select byte in every interleaved block\n\ - --gap-fill Fill gaps between sections with \n\ - --pad-to Pad the last section up to address \n\ - --set-start Set the start address to \n\ - {--change-start|--adjust-start} \n\ - Add to the start address\n\ - {--change-addresses|--adjust-vma} \n\ - Add to LMA, VMA and start addresses\n\ - {--change-section-address|--adjust-section-vma} {=|+|-}\n\ - Change LMA and VMA of section by \n\ - --change-section-lma {=|+|-}\n\ - Change the LMA of section by \n\ - --change-section-vma {=|+|-}\n\ - Change the VMA of section by \n\ - {--[no-]change-warnings|--[no-]adjust-warnings}\n\ - Warn if a named section does not exist\n\ - --set-section-flags =\n\ - Set section 's properties to \n\ - --add-section = Add section found in to output\n\ - --rename-section =[,] Rename section to \n\ - --long-section-names {enable|disable|keep}\n\ - Handle long section names in Coff objects.\n\ - --change-leading-char Force output format's leading character style\n\ - --remove-leading-char Remove leading character from global symbols\n\ - --reverse-bytes= Reverse bytes at a time, in output sections with content\n\ - --redefine-sym = Redefine symbol name to \n\ - --redefine-syms --redefine-sym for all symbol pairs \n\ - listed in \n\ - --srec-len Restrict the length of generated Srecords\n\ - --srec-forceS3 Restrict the type of generated Srecords to S3\n\ - --strip-symbols -N for all symbols listed in \n\ - --strip-unneeded-symbols \n\ - --strip-unneeded-symbol for all symbols listed\n\ - in \n\ - --keep-symbols -K for all symbols listed in \n\ - --localize-symbols -L for all symbols listed in \n\ - --globalize-symbols --globalize-symbol for all in \n\ - --keep-global-symbols -G for all symbols listed in \n\ - --weaken-symbols -W for all symbols listed in \n\ - --alt-machine-code Use the target's 'th alternative machine\n\ - --writable-text Mark the output text as writable\n\ - --readonly-text Make the output text write protected\n\ - --pure Mark the output file as demand paged\n\ - --impure Mark the output file as impure\n\ - --prefix-symbols Add to start of every symbol name\n\ - --prefix-sections Add to start of every section name\n\ - --prefix-alloc-sections \n\ - Add to start of every allocatable\n\ - section name\n\ - --file-alignment Set PE file alignment to \n\ - --heap [,] Set PE reserve/commit heap to /\n\ - \n\ - --image-base

Set PE image base to
\n\ - --section-alignment Set PE section alignment to \n\ - --stack [,] Set PE reserve/commit stack to /\n\ - \n\ - --subsystem [:]\n\ - Set PE subsystem to [& ]\n\ - --compress-debug-sections Compress DWARF debug sections using zlib\n\ - --decompress-debug-sections Decompress DWARF debug sections using zlib\n\ - -v --verbose List all object files modified\n\ - @ Read options from \n\ - -V --version Display this program's version number\n\ - -h --help Display this output\n\ - --info List object formats & architectures supported\n\ -")); - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && exit_status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (exit_status); -} - -static void -strip_usage (FILE *stream, int exit_status) -{ - fprintf (stream, _("Usage: %s in-file(s)\n"), program_name); - fprintf (stream, _(" Removes symbols and sections from files\n")); - fprintf (stream, _(" The options are:\n")); - fprintf (stream, _("\ - -I --input-target= Assume input file is in format \n\ - -O --output-target= Create an output file in format \n\ - -F --target= Set both input and output format to \n\ - -p --preserve-dates Copy modified/access timestamps to the output\n\ - -R --remove-section= Remove section from the output\n\ - -s --strip-all Remove all symbol and relocation information\n\ - -g -S -d --strip-debug Remove all debugging symbols & sections\n\ - --strip-unneeded Remove all symbols not needed by relocations\n\ - --only-keep-debug Strip everything but the debug information\n\ - -N --strip-symbol= Do not copy symbol \n\ - -K --keep-symbol= Do not strip symbol \n\ - --keep-file-symbols Do not strip file symbol(s)\n\ - -w --wildcard Permit wildcard in symbol comparison\n\ - -x --discard-all Remove all non-global symbols\n\ - -X --discard-locals Remove any compiler-generated symbols\n\ - -v --verbose List all object files modified\n\ - -V --version Display this program's version number\n\ - -h --help Display this output\n\ - --info List object formats & architectures supported\n\ - -o Place stripped output into \n\ -")); - - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && exit_status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (exit_status); -} - -/* Parse section flags into a flagword, with a fatal error if the - string can't be parsed. */ - -static flagword -parse_flags (const char *s) -{ - flagword ret; - const char *snext; - int len; - - ret = SEC_NO_FLAGS; - - do - { - snext = strchr (s, ','); - if (snext == NULL) - len = strlen (s); - else - { - len = snext - s; - ++snext; - } - - if (0) ; -#define PARSE_FLAG(fname,fval) \ - else if (strncasecmp (fname, s, len) == 0) ret |= fval - PARSE_FLAG ("alloc", SEC_ALLOC); - PARSE_FLAG ("load", SEC_LOAD); - PARSE_FLAG ("noload", SEC_NEVER_LOAD); - PARSE_FLAG ("readonly", SEC_READONLY); - PARSE_FLAG ("debug", SEC_DEBUGGING); - PARSE_FLAG ("code", SEC_CODE); - PARSE_FLAG ("data", SEC_DATA); - PARSE_FLAG ("rom", SEC_ROM); - PARSE_FLAG ("share", SEC_COFF_SHARED); - PARSE_FLAG ("contents", SEC_HAS_CONTENTS); -#undef PARSE_FLAG - else - { - char *copy; - - copy = (char *) xmalloc (len + 1); - strncpy (copy, s, len); - copy[len] = '\0'; - non_fatal (_("unrecognized section flag `%s'"), copy); - fatal (_("supported flags: %s"), - "alloc, load, noload, readonly, debug, code, data, rom, share, contents"); - } - - s = snext; - } - while (s != NULL); - - return ret; -} - -/* Find and optionally add an entry in the change_sections list. */ - -static struct section_list * -find_section_list (const char *name, bfd_boolean add) -{ - struct section_list *p; - - for (p = change_sections; p != NULL; p = p->next) - if (strcmp (p->name, name) == 0) - return p; - - if (! add) - return NULL; - - p = (struct section_list *) xmalloc (sizeof (struct section_list)); - p->name = name; - p->used = FALSE; - p->remove = FALSE; - p->copy = FALSE; - p->change_vma = CHANGE_IGNORE; - p->change_lma = CHANGE_IGNORE; - p->vma_val = 0; - p->lma_val = 0; - p->set_flags = FALSE; - p->flags = 0; - - p->next = change_sections; - change_sections = p; - - return p; -} - -/* There is htab_hash_string but no htab_eq_string. Makes sense. */ - -static int -eq_string (const void *s1, const void *s2) -{ - return strcmp ((const char *) s1, (const char *) s2) == 0; -} - -static htab_t -create_symbol_htab (void) -{ - return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free); -} - -static void -create_symbol_htabs (void) -{ - strip_specific_htab = create_symbol_htab (); - strip_unneeded_htab = create_symbol_htab (); - keep_specific_htab = create_symbol_htab (); - localize_specific_htab = create_symbol_htab (); - globalize_specific_htab = create_symbol_htab (); - keepglobal_specific_htab = create_symbol_htab (); - weaken_specific_htab = create_symbol_htab (); -} - -/* Add a symbol to strip_specific_list. */ - -static void -add_specific_symbol (const char *name, htab_t htab) -{ - *htab_find_slot (htab, name, INSERT) = (char *) name; -} - -/* Add symbols listed in `filename' to strip_specific_list. */ - -#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t') -#define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0') - -static void -add_specific_symbols (const char *filename, htab_t htab) -{ - off_t size; - FILE * f; - char * line; - char * buffer; - unsigned int line_count; - - size = get_file_size (filename); - if (size == 0) - { - status = 1; - return; - } - - buffer = (char *) xmalloc (size + 2); - f = fopen (filename, FOPEN_RT); - if (f == NULL) - fatal (_("cannot open '%s': %s"), filename, strerror (errno)); - - if (fread (buffer, 1, size, f) == 0 || ferror (f)) - fatal (_("%s: fread failed"), filename); - - fclose (f); - buffer [size] = '\n'; - buffer [size + 1] = '\0'; - - line_count = 1; - - for (line = buffer; * line != '\0'; line ++) - { - char * eol; - char * name; - char * name_end; - int finished = FALSE; - - for (eol = line;; eol ++) - { - switch (* eol) - { - case '\n': - * eol = '\0'; - /* Cope with \n\r. */ - if (eol[1] == '\r') - ++ eol; - finished = TRUE; - break; - - case '\r': - * eol = '\0'; - /* Cope with \r\n. */ - if (eol[1] == '\n') - ++ eol; - finished = TRUE; - break; - - case 0: - finished = TRUE; - break; - - case '#': - /* Line comment, Terminate the line here, in case a - name is present and then allow the rest of the - loop to find the real end of the line. */ - * eol = '\0'; - break; - - default: - break; - } - - if (finished) - break; - } - - /* A name may now exist somewhere between 'line' and 'eol'. - Strip off leading whitespace and trailing whitespace, - then add it to the list. */ - for (name = line; IS_WHITESPACE (* name); name ++) - ; - for (name_end = name; - (! IS_WHITESPACE (* name_end)) - && (! IS_LINE_TERMINATOR (* name_end)); - name_end ++) - ; - - if (! IS_LINE_TERMINATOR (* name_end)) - { - char * extra; - - for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++) - ; - - if (! IS_LINE_TERMINATOR (* extra)) - non_fatal (_("%s:%d: Ignoring rubbish found on this line"), - filename, line_count); - } - - * name_end = '\0'; - - if (name_end > name) - add_specific_symbol (name, htab); - - /* Advance line pointer to end of line. The 'eol ++' in the for - loop above will then advance us to the start of the next line. */ - line = eol; - line_count ++; - } -} - -/* See whether a symbol should be stripped or kept - based on strip_specific_list and keep_symbols. */ - -static int -is_specified_symbol_predicate (void **slot, void *data) -{ - struct is_specified_symbol_predicate_data *d = - (struct is_specified_symbol_predicate_data *) data; - const char *slot_name = (char *) *slot; - - if (*slot_name != '!') - { - if (! fnmatch (slot_name, d->name, 0)) - { - d->found = TRUE; - /* Stop traversal. */ - return 0; - } - } - else - { - if (fnmatch (slot_name + 1, d->name, 0)) - { - d->found = TRUE; - /* Stop traversal. */ - return 0; - } - } - - /* Continue traversal. */ - return 1; -} - -static bfd_boolean -is_specified_symbol (const char *name, htab_t htab) -{ - if (wildcard) - { - struct is_specified_symbol_predicate_data data; - - data.name = name; - data.found = FALSE; - - htab_traverse (htab, is_specified_symbol_predicate, &data); - - return data.found; - } - - return htab_find (htab, name) != NULL; -} - -/* Return a pointer to the symbol used as a signature for GROUP. */ - -static asymbol * -group_signature (asection *group) -{ - bfd *abfd = group->owner; - Elf_Internal_Shdr *ghdr; - - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - return NULL; - - ghdr = &elf_section_data (group)->this_hdr; - if (ghdr->sh_link < elf_numsections (abfd)) - { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link]; - - if (symhdr->sh_type == SHT_SYMTAB - && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym) - return isympp[ghdr->sh_info - 1]; - } - return NULL; -} - -/* See if a non-group section is being removed. */ - -static bfd_boolean -is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) -{ - if (sections_removed || sections_copied) - { - struct section_list *p; - - p = find_section_list (bfd_get_section_name (abfd, sec), FALSE); - - if (sections_removed && p != NULL && p->remove) - return TRUE; - if (sections_copied && (p == NULL || ! p->copy)) - return TRUE; - } - - if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0) - { - if (strip_symbols == STRIP_DEBUG - || strip_symbols == STRIP_UNNEEDED - || strip_symbols == STRIP_ALL - || discard_locals == LOCALS_ALL - || convert_debugging) - return TRUE; - - if (strip_symbols == STRIP_NONDEBUG) - return FALSE; - } - - return FALSE; -} - -/* See if a section is being removed. */ - -static bfd_boolean -is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) -{ - if (is_strip_section_1 (abfd, sec)) - return TRUE; - - if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0) - { - asymbol *gsym; - const char *gname; - asection *elt, *first; - - /* PR binutils/3181 - If we are going to strip the group signature symbol, then - strip the group section too. */ - gsym = group_signature (sec); - if (gsym != NULL) - gname = gsym->name; - else - gname = sec->name; - if ((strip_symbols == STRIP_ALL - && !is_specified_symbol (gname, keep_specific_htab)) - || is_specified_symbol (gname, strip_specific_htab)) - return TRUE; - - /* Remove the group section if all members are removed. */ - first = elt = elf_next_in_group (sec); - while (elt != NULL) - { - if (!is_strip_section_1 (abfd, elt)) - return FALSE; - elt = elf_next_in_group (elt); - if (elt == first) - break; - } - - return TRUE; - } - - return FALSE; -} - -/* Return true if SYM is a hidden symbol. */ - -static bfd_boolean -is_hidden_symbol (asymbol *sym) -{ - elf_symbol_type *elf_sym; - - elf_sym = elf_symbol_from (sym->the_bfd, sym); - if (elf_sym != NULL) - switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other)) - { - case STV_HIDDEN: - case STV_INTERNAL: - return TRUE; - } - return FALSE; -} - -/* Choose which symbol entries to copy; put the result in OSYMS. - We don't copy in place, because that confuses the relocs. - Return the number of symbols to print. */ - -static unsigned int -filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms, - asymbol **isyms, long symcount) -{ - asymbol **from = isyms, **to = osyms; - long src_count = 0, dst_count = 0; - int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; - - for (; src_count < symcount; src_count++) - { - asymbol *sym = from[src_count]; - flagword flags = sym->flags; - char *name = (char *) bfd_asymbol_name (sym); - bfd_boolean keep; - bfd_boolean used_in_reloc = FALSE; - bfd_boolean undefined; - bfd_boolean rem_leading_char; - bfd_boolean add_leading_char; - - undefined = bfd_is_und_section (bfd_get_section (sym)); - - if (redefine_sym_list) - { - char *old_name, *new_name; - - old_name = (char *) bfd_asymbol_name (sym); - new_name = (char *) lookup_sym_redefinition (old_name); - bfd_asymbol_name (sym) = new_name; - name = new_name; - } - - /* Check if we will remove the current leading character. */ - rem_leading_char = - (name[0] == bfd_get_symbol_leading_char (abfd)) - && (change_leading_char - || (remove_leading_char - && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0 - || undefined - || bfd_is_com_section (bfd_get_section (sym))))); - - /* Check if we will add a new leading character. */ - add_leading_char = - change_leading_char - && (bfd_get_symbol_leading_char (obfd) != '\0') - && (bfd_get_symbol_leading_char (abfd) == '\0' - || (name[0] == bfd_get_symbol_leading_char (abfd))); - - /* Short circuit for change_leading_char if we can do it in-place. */ - if (rem_leading_char && add_leading_char && !prefix_symbols_string) - { - name[0] = bfd_get_symbol_leading_char (obfd); - bfd_asymbol_name (sym) = name; - rem_leading_char = FALSE; - add_leading_char = FALSE; - } - - /* Remove leading char. */ - if (rem_leading_char) - bfd_asymbol_name (sym) = ++name; - - /* Add new leading char and/or prefix. */ - if (add_leading_char || prefix_symbols_string) - { - char *n, *ptr; - - ptr = n = (char *) xmalloc (1 + strlen (prefix_symbols_string) - + strlen (name) + 1); - if (add_leading_char) - *ptr++ = bfd_get_symbol_leading_char (obfd); - - if (prefix_symbols_string) - { - strcpy (ptr, prefix_symbols_string); - ptr += strlen (prefix_symbols_string); - } - - strcpy (ptr, name); - bfd_asymbol_name (sym) = n; - name = n; - } - - if (strip_symbols == STRIP_ALL) - keep = FALSE; - else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */ - || ((flags & BSF_SECTION_SYM) != 0 - && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags - & BSF_KEEP) != 0)) - { - keep = TRUE; - used_in_reloc = TRUE; - } - else if (relocatable /* Relocatable file. */ - && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0 - || bfd_is_com_section (bfd_get_section (sym)))) - keep = TRUE; - else if (bfd_decode_symclass (sym) == 'I') - /* Global symbols in $idata sections need to be retained - even if relocatable is FALSE. External users of the - library containing the $idata section may reference these - symbols. */ - keep = TRUE; - else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */ - || (flags & BSF_WEAK) != 0 - || undefined - || bfd_is_com_section (bfd_get_section (sym))) - keep = strip_symbols != STRIP_UNNEEDED; - else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ - keep = (strip_symbols != STRIP_DEBUG - && strip_symbols != STRIP_UNNEEDED - && ! convert_debugging); - else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) - /* COMDAT sections store special information in local - symbols, so we cannot risk stripping any of them. */ - keep = TRUE; - else /* Local symbol. */ - keep = (strip_symbols != STRIP_UNNEEDED - && (discard_locals != LOCALS_ALL - && (discard_locals != LOCALS_START_L - || ! bfd_is_local_label (abfd, sym)))); - - if (keep && is_specified_symbol (name, strip_specific_htab)) - { - /* There are multiple ways to set 'keep' above, but if it - was the relocatable symbol case, then that's an error. */ - if (used_in_reloc) - { - non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name); - status = 1; - } - else - keep = FALSE; - } - - if (keep - && !(flags & BSF_KEEP) - && is_specified_symbol (name, strip_unneeded_htab)) - keep = FALSE; - - if (!keep - && ((keep_file_symbols && (flags & BSF_FILE)) - || is_specified_symbol (name, keep_specific_htab))) - keep = TRUE; - - if (keep && is_strip_section (abfd, bfd_get_section (sym))) - keep = FALSE; - - if (keep) - { - if ((flags & BSF_GLOBAL) != 0 - && (weaken || is_specified_symbol (name, weaken_specific_htab))) - { - sym->flags &= ~ BSF_GLOBAL; - sym->flags |= BSF_WEAK; - } - - if (!undefined - && (flags & (BSF_GLOBAL | BSF_WEAK)) - && (is_specified_symbol (name, localize_specific_htab) - || (htab_elements (keepglobal_specific_htab) != 0 - && ! is_specified_symbol (name, keepglobal_specific_htab)) - || (localize_hidden && is_hidden_symbol (sym)))) - { - sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK); - sym->flags |= BSF_LOCAL; - } - - if (!undefined - && (flags & BSF_LOCAL) - && is_specified_symbol (name, globalize_specific_htab)) - { - sym->flags &= ~ BSF_LOCAL; - sym->flags |= BSF_GLOBAL; - } - - to[dst_count++] = sym; - } - } - - to[dst_count] = NULL; - - return dst_count; -} - -/* Find the redefined name of symbol SOURCE. */ - -static const char * -lookup_sym_redefinition (const char *source) -{ - struct redefine_node *list; - - for (list = redefine_sym_list; list != NULL; list = list->next) - if (strcmp (source, list->source) == 0) - return list->target; - - return source; -} - -/* Add a node to a symbol redefine list. */ - -static void -redefine_list_append (const char *cause, const char *source, const char *target) -{ - struct redefine_node **p; - struct redefine_node *list; - struct redefine_node *new_node; - - for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next) - { - if (strcmp (source, list->source) == 0) - fatal (_("%s: Multiple redefinition of symbol \"%s\""), - cause, source); - - if (strcmp (target, list->target) == 0) - fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"), - cause, target); - } - - new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node)); - - new_node->source = strdup (source); - new_node->target = strdup (target); - new_node->next = NULL; - - *p = new_node; -} - -/* Handle the --redefine-syms option. Read lines containing "old new" - from the file, and add them to the symbol redefine list. */ - -static void -add_redefine_syms_file (const char *filename) -{ - FILE *file; - char *buf; - size_t bufsize; - size_t len; - size_t outsym_off; - int c, lineno; - - file = fopen (filename, "r"); - if (file == NULL) - fatal (_("couldn't open symbol redefinition file %s (error: %s)"), - filename, strerror (errno)); - - bufsize = 100; - buf = (char *) xmalloc (bufsize + 1 /* For the terminating NUL. */); - - lineno = 1; - c = getc (file); - len = 0; - outsym_off = 0; - while (c != EOF) - { - /* Collect the input symbol name. */ - while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF) - { - if (c == '#') - goto comment; - buf[len++] = c; - if (len >= bufsize) - { - bufsize *= 2; - buf = (char *) xrealloc (buf, bufsize + 1); - } - c = getc (file); - } - buf[len++] = '\0'; - if (c == EOF) - break; - - /* Eat white space between the symbol names. */ - while (IS_WHITESPACE (c)) - c = getc (file); - if (c == '#' || IS_LINE_TERMINATOR (c)) - goto comment; - if (c == EOF) - break; - - /* Collect the output symbol name. */ - outsym_off = len; - while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF) - { - if (c == '#') - goto comment; - buf[len++] = c; - if (len >= bufsize) - { - bufsize *= 2; - buf = (char *) xrealloc (buf, bufsize + 1); - } - c = getc (file); - } - buf[len++] = '\0'; - if (c == EOF) - break; - - /* Eat white space at end of line. */ - while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c)) - c = getc (file); - if (c == '#') - goto comment; - /* Handle \r\n. */ - if ((c == '\r' && (c = getc (file)) == '\n') - || c == '\n' || c == EOF) - { - end_of_line: - /* Append the redefinition to the list. */ - if (buf[0] != '\0') - redefine_list_append (filename, &buf[0], &buf[outsym_off]); - - lineno++; - len = 0; - outsym_off = 0; - if (c == EOF) - break; - c = getc (file); - continue; - } - else - fatal (_("%s:%d: garbage found at end of line"), filename, lineno); - comment: - if (len != 0 && (outsym_off == 0 || outsym_off == len)) - fatal (_("%s:%d: missing new symbol name"), filename, lineno); - buf[len++] = '\0'; - - /* Eat the rest of the line and finish it. */ - while (c != '\n' && c != EOF) - c = getc (file); - goto end_of_line; - } - - if (len != 0) - fatal (_("%s:%d: premature end of file"), filename, lineno); - - free (buf); -} - -/* Copy unkown object file IBFD onto OBFD. - Returns TRUE upon success, FALSE otherwise. */ - -static bfd_boolean -copy_unknown_object (bfd *ibfd, bfd *obfd) -{ - char *cbuf; - int tocopy; - long ncopied; - long size; - struct stat buf; - - if (bfd_stat_arch_elt (ibfd, &buf) != 0) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return FALSE; - } - - size = buf.st_size; - if (size < 0) - { - non_fatal (_("stat returns negative size for `%s'"), - bfd_get_archive_filename (ibfd)); - return FALSE; - } - - if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0) - { - bfd_nonfatal (bfd_get_archive_filename (ibfd)); - return FALSE; - } - - if (verbose) - printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"), - bfd_get_archive_filename (ibfd), bfd_get_filename (obfd)); - - cbuf = (char *) xmalloc (BUFSIZE); - ncopied = 0; - while (ncopied < size) - { - tocopy = size - ncopied; - if (tocopy > BUFSIZE) - tocopy = BUFSIZE; - - if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd) - != (bfd_size_type) tocopy) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - free (cbuf); - return FALSE; - } - - if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd) - != (bfd_size_type) tocopy) - { - bfd_nonfatal_message (NULL, obfd, NULL, NULL); - free (cbuf); - return FALSE; - } - - ncopied += tocopy; - } - - /* We should at least to be able to read it back when copying an - unknown object in an archive. */ - chmod (bfd_get_filename (obfd), buf.st_mode | S_IRUSR); - free (cbuf); - return TRUE; -} - -/* Copy object file IBFD onto OBFD. - Returns TRUE upon success, FALSE otherwise. */ - -static bfd_boolean -copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch) -{ - bfd_vma start; - long symcount; - asection **osections = NULL; - asection *gnu_debuglink_section = NULL; - bfd_size_type *gaps = NULL; - bfd_size_type max_gap = 0; - long symsize; - void *dhandle; - enum bfd_architecture iarch; - unsigned int imach; - - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - fatal (_("Unable to change endianness of input file(s)")); - - if (!bfd_set_format (obfd, bfd_get_format (ibfd))) - { - bfd_nonfatal_message (NULL, obfd, NULL, NULL); - return FALSE; - } - - if (verbose) - printf (_("copy from `%s' [%s] to `%s' [%s]\n"), - bfd_get_archive_filename (ibfd), bfd_get_target (ibfd), - bfd_get_filename (obfd), bfd_get_target (obfd)); - - if (extract_symbol) - start = 0; - else - { - if (set_start_set) - start = set_start; - else - start = bfd_get_start_address (ibfd); - start += change_start; - } - - /* Neither the start address nor the flags - need to be set for a core file. */ - if (bfd_get_format (obfd) != bfd_core) - { - flagword flags; - - flags = bfd_get_file_flags (ibfd); - flags |= bfd_flags_to_set; - flags &= ~bfd_flags_to_clear; - flags &= bfd_applicable_file_flags (obfd); - - if (strip_symbols == STRIP_ALL) - flags &= ~HAS_RELOC; - - if (!bfd_set_start_address (obfd, start) - || !bfd_set_file_flags (obfd, flags)) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return FALSE; - } - } - - /* Copy architecture of input file to output file. */ - iarch = bfd_get_arch (ibfd); - imach = bfd_get_mach (ibfd); - if (input_arch) - { - if (bfd_get_arch_info (ibfd) == NULL - || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown) - { - iarch = input_arch->arch; - imach = input_arch->mach; - } - else - non_fatal (_("Input file `%s' ignores binary architecture parameter."), - bfd_get_archive_filename (ibfd)); - } - if (!bfd_set_arch_mach (obfd, iarch, imach) - && (ibfd->target_defaulted - || bfd_get_arch (ibfd) != bfd_get_arch (obfd))) - { - if (bfd_get_arch (ibfd) == bfd_arch_unknown) - non_fatal (_("Unable to recognise the format of the input file `%s'"), - bfd_get_archive_filename (ibfd)); - else - non_fatal (_("Output file cannot represent architecture `%s'"), - bfd_printable_arch_mach (bfd_get_arch (ibfd), - bfd_get_mach (ibfd))); - return FALSE; - } - - if (!bfd_set_format (obfd, bfd_get_format (ibfd))) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return FALSE; - } - - if (bfd_get_flavour (obfd) == bfd_target_coff_flavour - && bfd_pei_p (obfd)) - { - /* Set up PE parameters. */ - pe_data_type *pe = pe_data (obfd); - - /* Copy PE parameters before changing them. */ - if (ibfd->xvec->flavour == bfd_target_coff_flavour - && bfd_pei_p (ibfd)) - pe->pe_opthdr = pe_data (ibfd)->pe_opthdr; - - if (pe_file_alignment != (bfd_vma) -1) - pe->pe_opthdr.FileAlignment = pe_file_alignment; - else - pe_file_alignment = PE_DEF_FILE_ALIGNMENT; - - if (pe_heap_commit != (bfd_vma) -1) - pe->pe_opthdr.SizeOfHeapCommit = pe_heap_commit; - - if (pe_heap_reserve != (bfd_vma) -1) - pe->pe_opthdr.SizeOfHeapCommit = pe_heap_reserve; - - if (pe_image_base != (bfd_vma) -1) - pe->pe_opthdr.ImageBase = pe_image_base; - - if (pe_section_alignment != (bfd_vma) -1) - pe->pe_opthdr.SectionAlignment = pe_section_alignment; - else - pe_section_alignment = PE_DEF_SECTION_ALIGNMENT; - - if (pe_stack_commit != (bfd_vma) -1) - pe->pe_opthdr.SizeOfStackCommit = pe_stack_commit; - - if (pe_stack_reserve != (bfd_vma) -1) - pe->pe_opthdr.SizeOfStackCommit = pe_stack_reserve; - - if (pe_subsystem != -1) - pe->pe_opthdr.Subsystem = pe_subsystem; - - if (pe_major_subsystem_version != -1) - pe->pe_opthdr.MajorSubsystemVersion = pe_major_subsystem_version; - - if (pe_minor_subsystem_version != -1) - pe->pe_opthdr.MinorSubsystemVersion = pe_minor_subsystem_version; - - if (pe_file_alignment > pe_section_alignment) - { - char file_alignment[20], section_alignment[20]; - - sprintf_vma (file_alignment, pe_file_alignment); - sprintf_vma (section_alignment, pe_section_alignment); - non_fatal (_("warning: file alignment (0x%s) > section alignment (0x%s)"), - - file_alignment, section_alignment); - } - } - - if (isympp) - free (isympp); - - if (osympp != isympp) - free (osympp); - - isympp = NULL; - osympp = NULL; - - symsize = bfd_get_symtab_upper_bound (ibfd); - if (symsize < 0) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return FALSE; - } - - osympp = isympp = (asymbol **) xmalloc (symsize); - symcount = bfd_canonicalize_symtab (ibfd, isympp); - if (symcount < 0) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return FALSE; - } - - /* BFD mandates that all output sections be created and sizes set before - any output is done. Thus, we traverse all sections multiple times. */ - bfd_map_over_sections (ibfd, setup_section, obfd); - - if (!extract_symbol) - setup_bfd_headers (ibfd, obfd); - - if (add_sections != NULL) - { - struct section_add *padd; - struct section_list *pset; - - for (padd = add_sections; padd != NULL; padd = padd->next) - { - flagword flags; - - pset = find_section_list (padd->name, FALSE); - if (pset != NULL) - pset->used = TRUE; - - flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA; - if (pset != NULL && pset->set_flags) - flags = pset->flags | SEC_HAS_CONTENTS; - - /* bfd_make_section_with_flags() does not return very helpful - error codes, so check for the most likely user error first. */ - if (bfd_get_section_by_name (obfd, padd->name)) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("can't add section '%s'"), padd->name); - return FALSE; - } - else - { - /* We use LINKER_CREATED here so that the backend hooks - will create any special section type information, - instead of presuming we know what we're doing merely - because we set the flags. */ - padd->section = bfd_make_section_with_flags - (obfd, padd->name, flags | SEC_LINKER_CREATED); - if (padd->section == NULL) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("can't create section `%s'"), - padd->name); - return FALSE; - } - } - - if (! bfd_set_section_size (obfd, padd->section, padd->size)) - { - bfd_nonfatal_message (NULL, obfd, padd->section, NULL); - return FALSE; - } - - if (pset != NULL) - { - if (pset->change_vma != CHANGE_IGNORE) - if (! bfd_set_section_vma (obfd, padd->section, - pset->vma_val)) - { - bfd_nonfatal_message (NULL, obfd, padd->section, NULL); - return FALSE; - } - - if (pset->change_lma != CHANGE_IGNORE) - { - padd->section->lma = pset->lma_val; - - if (! bfd_set_section_alignment - (obfd, padd->section, - bfd_section_alignment (obfd, padd->section))) - { - bfd_nonfatal_message (NULL, obfd, padd->section, NULL); - return FALSE; - } - } - } - } - } - - if (gnu_debuglink_filename != NULL) - { - gnu_debuglink_section = bfd_create_gnu_debuglink_section - (obfd, gnu_debuglink_filename); - - if (gnu_debuglink_section == NULL) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("cannot create debug link section `%s'"), - gnu_debuglink_filename); - return FALSE; - } - - /* Special processing for PE format files. We - have no way to distinguish PE from COFF here. */ - if (bfd_get_flavour (obfd) == bfd_target_coff_flavour) - { - bfd_vma debuglink_vma; - asection * highest_section; - asection * sec; - - /* The PE spec requires that all sections be adjacent and sorted - in ascending order of VMA. It also specifies that debug - sections should be last. This is despite the fact that debug - sections are not loaded into memory and so in theory have no - use for a VMA. - - This means that the debuglink section must be given a non-zero - VMA which makes it contiguous with other debug sections. So - walk the current section list, find the section with the - highest VMA and start the debuglink section after that one. */ - for (sec = obfd->sections, highest_section = NULL; - sec != NULL; - sec = sec->next) - if (sec->vma > 0 - && (highest_section == NULL - || sec->vma > highest_section->vma)) - highest_section = sec; - - if (highest_section) - debuglink_vma = BFD_ALIGN (highest_section->vma - + highest_section->size, - /* FIXME: We ought to be using - COFF_PAGE_SIZE here or maybe - bfd_get_section_alignment() (if it - was set) but since this is for PE - and we know the required alignment - it is easier just to hard code it. */ - 0x1000); - else - /* Umm, not sure what to do in this case. */ - debuglink_vma = 0x1000; - - bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma); - } - } - - if (bfd_count_sections (obfd) != 0 - && (gap_fill_set || pad_to_set)) - { - asection **set; - unsigned int c, i; - - /* We must fill in gaps between the sections and/or we must pad - the last section to a specified address. We do this by - grabbing a list of the sections, sorting them by VMA, and - increasing the section sizes as required to fill the gaps. - We write out the gap contents below. */ - - c = bfd_count_sections (obfd); - osections = (asection **) xmalloc (c * sizeof (asection *)); - set = osections; - bfd_map_over_sections (obfd, get_sections, &set); - - qsort (osections, c, sizeof (asection *), compare_section_lma); - - gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type)); - memset (gaps, 0, c * sizeof (bfd_size_type)); - - if (gap_fill_set) - { - for (i = 0; i < c - 1; i++) - { - flagword flags; - bfd_size_type size; - bfd_vma gap_start, gap_stop; - - flags = bfd_get_section_flags (obfd, osections[i]); - if ((flags & SEC_HAS_CONTENTS) == 0 - || (flags & SEC_LOAD) == 0) - continue; - - size = bfd_section_size (obfd, osections[i]); - gap_start = bfd_section_lma (obfd, osections[i]) + size; - gap_stop = bfd_section_lma (obfd, osections[i + 1]); - if (gap_start < gap_stop) - { - if (! bfd_set_section_size (obfd, osections[i], - size + (gap_stop - gap_start))) - { - bfd_nonfatal_message (NULL, obfd, osections[i], - _("Can't fill gap after section")); - status = 1; - break; - } - gaps[i] = gap_stop - gap_start; - if (max_gap < gap_stop - gap_start) - max_gap = gap_stop - gap_start; - } - } - } - - if (pad_to_set) - { - bfd_vma lma; - bfd_size_type size; - - lma = bfd_section_lma (obfd, osections[c - 1]); - size = bfd_section_size (obfd, osections[c - 1]); - if (lma + size < pad_to) - { - if (! bfd_set_section_size (obfd, osections[c - 1], - pad_to - lma)) - { - bfd_nonfatal_message (NULL, obfd, osections[c - 1], - _("can't add padding")); - status = 1; - } - else - { - gaps[c - 1] = pad_to - (lma + size); - if (max_gap < pad_to - (lma + size)) - max_gap = pad_to - (lma + size); - } - } - } - } - - /* Symbol filtering must happen after the output sections - have been created, but before their contents are set. */ - dhandle = NULL; - if (convert_debugging) - dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE); - - if (strip_symbols == STRIP_DEBUG - || strip_symbols == STRIP_ALL - || strip_symbols == STRIP_UNNEEDED - || strip_symbols == STRIP_NONDEBUG - || discard_locals != LOCALS_UNDEF - || localize_hidden - || htab_elements (strip_specific_htab) != 0 - || htab_elements (keep_specific_htab) != 0 - || htab_elements (localize_specific_htab) != 0 - || htab_elements (globalize_specific_htab) != 0 - || htab_elements (keepglobal_specific_htab) != 0 - || htab_elements (weaken_specific_htab) != 0 - || prefix_symbols_string - || sections_removed - || sections_copied - || convert_debugging - || change_leading_char - || remove_leading_char - || redefine_sym_list - || weaken) - { - /* Mark symbols used in output relocations so that they - are kept, even if they are local labels or static symbols. - - Note we iterate over the input sections examining their - relocations since the relocations for the output sections - haven't been set yet. mark_symbols_used_in_relocations will - ignore input sections which have no corresponding output - section. */ - if (strip_symbols != STRIP_ALL) - bfd_map_over_sections (ibfd, - mark_symbols_used_in_relocations, - isympp); - osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *)); - symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount); - } - - if (convert_debugging && dhandle != NULL) - { - if (! write_debugging_info (obfd, dhandle, &symcount, &osympp)) - { - status = 1; - return FALSE; - } - } - - bfd_set_symtab (obfd, osympp, symcount); - - /* This has to happen after the symbol table has been set. */ - bfd_map_over_sections (ibfd, copy_section, obfd); - - if (add_sections != NULL) - { - struct section_add *padd; - - for (padd = add_sections; padd != NULL; padd = padd->next) - { - if (! bfd_set_section_contents (obfd, padd->section, padd->contents, - 0, padd->size)) - { - bfd_nonfatal_message (NULL, obfd, padd->section, NULL); - return FALSE; - } - } - } - - if (gnu_debuglink_filename != NULL) - { - if (! bfd_fill_in_gnu_debuglink_section - (obfd, gnu_debuglink_section, gnu_debuglink_filename)) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("cannot fill debug link section `%s'"), - gnu_debuglink_filename); - return FALSE; - } - } - - if (gap_fill_set || pad_to_set) - { - bfd_byte *buf; - int c, i; - - /* Fill in the gaps. */ - if (max_gap > 8192) - max_gap = 8192; - buf = (bfd_byte *) xmalloc (max_gap); - memset (buf, gap_fill, max_gap); - - c = bfd_count_sections (obfd); - for (i = 0; i < c; i++) - { - if (gaps[i] != 0) - { - bfd_size_type left; - file_ptr off; - - left = gaps[i]; - off = bfd_section_size (obfd, osections[i]) - left; - - while (left > 0) - { - bfd_size_type now; - - if (left > 8192) - now = 8192; - else - now = left; - - if (! bfd_set_section_contents (obfd, osections[i], buf, - off, now)) - { - bfd_nonfatal_message (NULL, obfd, osections[i], NULL); - return FALSE; - } - - left -= now; - off += now; - } - } - } - } - - /* Do not copy backend data if --extract-symbol is passed; anything - that needs to look at the section contents will fail. */ - if (extract_symbol) - return TRUE; - - /* Allow the BFD backend to copy any private data it understands - from the input BFD to the output BFD. This is done last to - permit the routine to look at the filtered symbol table, which is - important for the ECOFF code at least. */ - if (! bfd_copy_private_bfd_data (ibfd, obfd)) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("error copying private BFD data")); - return FALSE; - } - - /* Switch to the alternate machine code. We have to do this at the - very end, because we only initialize the header when we create - the first section. */ - if (use_alt_mach_code != 0) - { - if (! bfd_alt_mach_code (obfd, use_alt_mach_code)) - { - non_fatal (_("this target does not support %lu alternative machine codes"), - use_alt_mach_code); - if (bfd_get_flavour (obfd) == bfd_target_elf_flavour) - { - non_fatal (_("treating that number as an absolute e_machine value instead")); - elf_elfheader (obfd)->e_machine = use_alt_mach_code; - } - else - non_fatal (_("ignoring the alternative value")); - } - } - - return TRUE; -} - -/* Read each archive element in turn from IBFD, copy the - contents to temp file, and keep the temp file handle. - If 'force_output_target' is TRUE then make sure that - all elements in the new archive are of the type - 'output_target'. */ - -static void -copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, - bfd_boolean force_output_target, - const bfd_arch_info_type *input_arch) -{ - struct name_list - { - struct name_list *next; - const char *name; - bfd *obfd; - } *list, *l; - bfd **ptr = &obfd->archive_head; - bfd *this_element; - char *dir; - const char *filename; - - /* Make a temp directory to hold the contents. */ - dir = make_tempdir (bfd_get_filename (obfd)); - if (dir == NULL) - fatal (_("cannot create tempdir for archive copying (error: %s)"), - strerror (errno)); - - obfd->has_armap = ibfd->has_armap; - obfd->is_thin_archive = ibfd->is_thin_archive; - - list = NULL; - - this_element = bfd_openr_next_archived_file (ibfd, NULL); - - if (!bfd_set_format (obfd, bfd_get_format (ibfd))) - { - status = 1; - bfd_nonfatal_message (NULL, obfd, NULL, NULL); - return; - } - - while (!status && this_element != NULL) - { - char *output_name; - bfd *output_bfd; - bfd *last_element; - struct stat buf; - int stat_status = 0; - bfd_boolean del = TRUE; - bfd_boolean ok_object; - - /* Create an output file for this member. */ - output_name = concat (dir, "/", - bfd_get_filename (this_element), (char *) 0); - - /* If the file already exists, make another temp dir. */ - if (stat (output_name, &buf) >= 0) - { - output_name = make_tempdir (output_name); - if (output_name == NULL) - fatal (_("cannot create tempdir for archive copying (error: %s)"), - strerror (errno)); - - l = (struct name_list *) xmalloc (sizeof (struct name_list)); - l->name = output_name; - l->next = list; - l->obfd = NULL; - list = l; - output_name = concat (output_name, "/", - bfd_get_filename (this_element), (char *) 0); - } - - if (preserve_dates) - { - stat_status = bfd_stat_arch_elt (this_element, &buf); - - if (stat_status != 0) - non_fatal (_("internal stat error on %s"), - bfd_get_filename (this_element)); - } - - l = (struct name_list *) xmalloc (sizeof (struct name_list)); - l->name = output_name; - l->next = list; - l->obfd = NULL; - list = l; - - ok_object = bfd_check_format (this_element, bfd_object); - if (!ok_object) - bfd_nonfatal_message (NULL, this_element, NULL, - _("Unable to recognise the format of file")); - - /* PR binutils/3110: Cope with archives - containing multiple target types. */ - if (force_output_target || !ok_object) - output_bfd = bfd_openw (output_name, output_target); - else - output_bfd = bfd_openw (output_name, bfd_get_target (this_element)); - - if (output_bfd == NULL) - { - bfd_nonfatal_message (output_name, NULL, NULL, NULL); - status = 1; - return; - } - - if (ok_object) - { - del = !copy_object (this_element, output_bfd, input_arch); - - if (del && bfd_get_arch (this_element) == bfd_arch_unknown) - /* Try again as an unknown object file. */ - ok_object = FALSE; - else if (!bfd_close (output_bfd)) - { - bfd_nonfatal_message (output_name, NULL, NULL, NULL); - /* Error in new object file. Don't change archive. */ - status = 1; - } - } - - if (!ok_object) - { - del = !copy_unknown_object (this_element, output_bfd); - if (!bfd_close_all_done (output_bfd)) - { - bfd_nonfatal_message (output_name, NULL, NULL, NULL); - /* Error in new object file. Don't change archive. */ - status = 1; - } - } - - if (del) - { - unlink (output_name); - status = 1; - } - else - { - if (preserve_dates && stat_status == 0) - set_times (output_name, &buf); - - /* Open the newly output file and attach to our list. */ - output_bfd = bfd_openr (output_name, output_target); - - l->obfd = output_bfd; - - *ptr = output_bfd; - ptr = &output_bfd->archive_next; - - last_element = this_element; - - this_element = bfd_openr_next_archived_file (ibfd, last_element); - - bfd_close (last_element); - } - } - *ptr = NULL; - - filename = bfd_get_filename (obfd); - if (!bfd_close (obfd)) - { - status = 1; - bfd_nonfatal_message (filename, NULL, NULL, NULL); - return; - } - - filename = bfd_get_filename (ibfd); - if (!bfd_close (ibfd)) - { - status = 1; - bfd_nonfatal_message (filename, NULL, NULL, NULL); - return; - } - - /* Delete all the files that we opened. */ - for (l = list; l != NULL; l = l->next) - { - if (l->obfd == NULL) - rmdir (l->name); - else - { - bfd_close (l->obfd); - unlink (l->name); - } - } - rmdir (dir); -} - -static void -set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style) -{ - /* This is only relevant to Coff targets. */ - if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour) - { - if (style == KEEP - && bfd_get_flavour (input_bfd) == bfd_target_coff_flavour) - style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE; - bfd_coff_set_long_section_names (output_bfd, style != DISABLE); - } -} - -/* The top-level control. */ - -static void -copy_file (const char *input_filename, const char *output_filename, - const char *input_target, const char *output_target, - const bfd_arch_info_type *input_arch) -{ - bfd *ibfd; - char **obj_matching; - char **core_matching; - off_t size = get_file_size (input_filename); - - if (size < 1) - { - if (size == 0) - non_fatal (_("error: the input file '%s' is empty"), - input_filename); - status = 1; - return; - } - - /* To allow us to do "strip *" without dying on the first - non-object file, failures are nonfatal. */ - ibfd = bfd_openr (input_filename, input_target); - if (ibfd == NULL) - { - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); - status = 1; - return; - } - - switch (do_debug_sections) - { - case compress: - ibfd->flags |= BFD_COMPRESS; - break; - case decompress: - ibfd->flags |= BFD_DECOMPRESS; - break; - default: - break; - } - - if (bfd_check_format (ibfd, bfd_archive)) - { - bfd_boolean force_output_target; - bfd *obfd; - - /* bfd_get_target does not return the correct value until - bfd_check_format succeeds. */ - if (output_target == NULL) - { - output_target = bfd_get_target (ibfd); - force_output_target = FALSE; - } - else - force_output_target = TRUE; - - obfd = bfd_openw (output_filename, output_target); - if (obfd == NULL) - { - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); - status = 1; - return; - } - /* This is a no-op on non-Coff targets. */ - set_long_section_mode (obfd, ibfd, long_section_names); - - copy_archive (ibfd, obfd, output_target, force_output_target, input_arch); - } - else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching)) - { - bfd *obfd; - do_copy: - - /* bfd_get_target does not return the correct value until - bfd_check_format succeeds. */ - if (output_target == NULL) - output_target = bfd_get_target (ibfd); - - obfd = bfd_openw (output_filename, output_target); - if (obfd == NULL) - { - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); - status = 1; - return; - } - /* This is a no-op on non-Coff targets. */ - set_long_section_mode (obfd, ibfd, long_section_names); - - if (! copy_object (ibfd, obfd, input_arch)) - status = 1; - - if (!bfd_close (obfd)) - { - status = 1; - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); - return; - } - - if (!bfd_close (ibfd)) - { - status = 1; - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); - return; - } - } - else - { - bfd_error_type obj_error = bfd_get_error (); - bfd_error_type core_error; - - if (bfd_check_format_matches (ibfd, bfd_core, &core_matching)) - { - /* This probably can't happen.. */ - if (obj_error == bfd_error_file_ambiguously_recognized) - free (obj_matching); - goto do_copy; - } - - core_error = bfd_get_error (); - /* Report the object error in preference to the core error. */ - if (obj_error != core_error) - bfd_set_error (obj_error); - - bfd_nonfatal_message (input_filename, NULL, NULL, NULL); - - if (obj_error == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (obj_matching); - free (obj_matching); - } - if (core_error == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (core_matching); - free (core_matching); - } - - status = 1; - } -} - -/* Add a name to the section renaming list. */ - -static void -add_section_rename (const char * old_name, const char * new_name, - flagword flags) -{ - section_rename * srename; - - /* Check for conflicts first. */ - for (srename = section_rename_list; srename != NULL; srename = srename->next) - if (strcmp (srename->old_name, old_name) == 0) - { - /* Silently ignore duplicate definitions. */ - if (strcmp (srename->new_name, new_name) == 0 - && srename->flags == flags) - return; - - fatal (_("Multiple renames of section %s"), old_name); - } - - srename = (section_rename *) xmalloc (sizeof (* srename)); - - srename->old_name = old_name; - srename->new_name = new_name; - srename->flags = flags; - srename->next = section_rename_list; - - section_rename_list = srename; -} - -/* Check the section rename list for a new name of the input section - ISECTION. Return the new name if one is found. - Also set RETURNED_FLAGS to the flags to be used for this section. */ - -static const char * -find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection, - flagword * returned_flags) -{ - const char * old_name = bfd_section_name (ibfd, isection); - section_rename * srename; - - /* Default to using the flags of the input section. */ - * returned_flags = bfd_get_section_flags (ibfd, isection); - - for (srename = section_rename_list; srename != NULL; srename = srename->next) - if (strcmp (srename->old_name, old_name) == 0) - { - if (srename->flags != (flagword) -1) - * returned_flags = srename->flags; - - return srename->new_name; - } - - return old_name; -} - -/* Once each of the sections is copied, we may still need to do some - finalization work for private section headers. Do that here. */ - -static void -setup_bfd_headers (bfd *ibfd, bfd *obfd) -{ - /* Allow the BFD backend to copy any private data it understands - from the input section to the output section. */ - if (! bfd_copy_private_header_data (ibfd, obfd)) - { - status = 1; - bfd_nonfatal_message (NULL, ibfd, NULL, - _("error in private header data")); - return; - } - - /* All went well. */ - return; -} - -/* Create a section in OBFD with the same - name and attributes as ISECTION in IBFD. */ - -static void -setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) -{ - bfd *obfd = (bfd *) obfdarg; - struct section_list *p; - sec_ptr osection; - bfd_size_type size; - bfd_vma vma; - bfd_vma lma; - flagword flags; - const char *err; - const char * name; - char *prefix = NULL; - bfd_boolean make_nobits; - - if (is_strip_section (ibfd, isection)) - return; - - p = find_section_list (bfd_section_name (ibfd, isection), FALSE); - if (p != NULL) - p->used = TRUE; - - /* Get the, possibly new, name of the output section. */ - name = find_section_rename (ibfd, isection, & flags); - - /* Prefix sections. */ - if ((prefix_alloc_sections_string) - && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC)) - prefix = prefix_alloc_sections_string; - else if (prefix_sections_string) - prefix = prefix_sections_string; - - if (prefix) - { - char *n; - - n = (char *) xmalloc (strlen (prefix) + strlen (name) + 1); - strcpy (n, prefix); - strcat (n, name); - name = n; - } - - make_nobits = FALSE; - if (p != NULL && p->set_flags) - flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC)); - else if (strip_symbols == STRIP_NONDEBUG - && (flags & (SEC_ALLOC | SEC_GROUP)) != 0 - && !(ibfd->xvec->flavour == bfd_target_elf_flavour - && elf_section_type (isection) == SHT_NOTE)) - { - flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP); - if (obfd->xvec->flavour == bfd_target_elf_flavour) - { - make_nobits = TRUE; - - /* Twiddle the input section flags so that it seems to - elf.c:copy_private_bfd_data that section flags have not - changed between input and output sections. This hack - prevents wholesale rewriting of the program headers. */ - isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP); - } - } - - osection = bfd_make_section_anyway_with_flags (obfd, name, flags); - - if (osection == NULL) - { - err = _("failed to create output section"); - goto loser; - } - - if (make_nobits) - elf_section_type (osection) = SHT_NOBITS; - - size = bfd_section_size (ibfd, isection); - if (copy_byte >= 0) - size = (size + interleave - 1) / interleave * copy_width; - else if (extract_symbol) - size = 0; - if (! bfd_set_section_size (obfd, osection, size)) - { - err = _("failed to set size"); - goto loser; - } - - vma = bfd_section_vma (ibfd, isection); - if (p != NULL && p->change_vma == CHANGE_MODIFY) - vma += p->vma_val; - else if (p != NULL && p->change_vma == CHANGE_SET) - vma = p->vma_val; - else - vma += change_section_address; - - if (! bfd_set_section_vma (obfd, osection, vma)) - { - err = _("failed to set vma"); - goto loser; - } - - lma = isection->lma; - if ((p != NULL) && p->change_lma != CHANGE_IGNORE) - { - if (p->change_lma == CHANGE_MODIFY) - lma += p->lma_val; - else if (p->change_lma == CHANGE_SET) - lma = p->lma_val; - else - abort (); - } - else - lma += change_section_address; - - osection->lma = lma; - - /* FIXME: This is probably not enough. If we change the LMA we - may have to recompute the header for the file as well. */ - if (!bfd_set_section_alignment (obfd, - osection, - bfd_section_alignment (ibfd, isection))) - { - err = _("failed to set alignment"); - goto loser; - } - - /* Copy merge entity size. */ - osection->entsize = isection->entsize; - - /* This used to be mangle_section; we do here to avoid using - bfd_get_section_by_name since some formats allow multiple - sections with the same name. */ - isection->output_section = osection; - isection->output_offset = 0; - - /* Do not copy backend data if --extract-symbol is passed; anything - that needs to look at the section contents will fail. */ - if (extract_symbol) - return; - - if ((isection->flags & SEC_GROUP) != 0) - { - asymbol *gsym = group_signature (isection); - - if (gsym != NULL) - { - gsym->flags |= BSF_KEEP; - if (ibfd->xvec->flavour == bfd_target_elf_flavour) - elf_group_id (isection) = gsym; - } - } - - /* Allow the BFD backend to copy any private data it understands - from the input section to the output section. */ - if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) - { - err = _("failed to copy private data"); - goto loser; - } - - /* All went well. */ - return; - -loser: - status = 1; - bfd_nonfatal_message (NULL, obfd, osection, err); -} - -/* Copy the data of input section ISECTION of IBFD - to an output section with the same name in OBFD. - If stripping then don't copy any relocation info. */ - -static void -copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg) -{ - bfd *obfd = (bfd *) obfdarg; - struct section_list *p; - arelent **relpp; - long relcount; - sec_ptr osection; - bfd_size_type size; - long relsize; - flagword flags; - - /* If we have already failed earlier on, - do not keep on generating complaints now. */ - if (status != 0) - return; - - if (is_strip_section (ibfd, isection)) - return; - - flags = bfd_get_section_flags (ibfd, isection); - if ((flags & SEC_GROUP) != 0) - return; - - osection = isection->output_section; - size = bfd_get_section_size (isection); - - if (size == 0 || osection == 0) - return; - - if (extract_symbol) - return; - - p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE); - - /* Core files do not need to be relocated. */ - if (bfd_get_format (obfd) == bfd_core) - relsize = 0; - else - { - relsize = bfd_get_reloc_upper_bound (ibfd, isection); - - if (relsize < 0) - { - /* Do not complain if the target does not support relocations. */ - if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation) - relsize = 0; - else - { - status = 1; - bfd_nonfatal_message (NULL, ibfd, isection, NULL); - return; - } - } - } - - if (relsize == 0) - bfd_set_reloc (obfd, osection, NULL, 0); - else - { - relpp = (arelent **) xmalloc (relsize); - relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); - if (relcount < 0) - { - status = 1; - bfd_nonfatal_message (NULL, ibfd, isection, - _("relocation count is negative")); - return; - } - - if (strip_symbols == STRIP_ALL) - { - /* Remove relocations which are not in - keep_strip_specific_list. */ - arelent **temp_relpp; - long temp_relcount = 0; - long i; - - temp_relpp = (arelent **) xmalloc (relsize); - for (i = 0; i < relcount; i++) - if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr), - keep_specific_htab)) - temp_relpp [temp_relcount++] = relpp [i]; - relcount = temp_relcount; - free (relpp); - relpp = temp_relpp; - } - - bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount); - if (relcount == 0) - free (relpp); - } - - if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS - && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS) - { - bfd_byte *memhunk = NULL; - - if (!bfd_get_full_section_contents (ibfd, isection, &memhunk)) - { - status = 1; - bfd_nonfatal_message (NULL, ibfd, isection, NULL); - return; - } - - if (reverse_bytes) - { - /* We don't handle leftover bytes (too many possible behaviors, - and we don't know what the user wants). The section length - must be a multiple of the number of bytes to swap. */ - if ((size % reverse_bytes) == 0) - { - unsigned long i, j; - bfd_byte b; - - for (i = 0; i < size; i += reverse_bytes) - for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++) - { - bfd_byte *m = (bfd_byte *) memhunk; - - b = m[i + j]; - m[i + j] = m[(i + reverse_bytes) - (j + 1)]; - m[(i + reverse_bytes) - (j + 1)] = b; - } - } - else - /* User must pad the section up in order to do this. */ - fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"), - bfd_section_name (ibfd, isection), reverse_bytes); - } - - if (copy_byte >= 0) - { - /* Keep only every `copy_byte'th byte in MEMHUNK. */ - char *from = (char *) memhunk + copy_byte; - char *to = (char *) memhunk; - char *end = (char *) memhunk + size; - int i; - - for (; from < end; from += interleave) - for (i = 0; i < copy_width; i++) - *to++ = from[i]; - - size = (size + interleave - 1 - copy_byte) / interleave * copy_width; - osection->lma /= interleave; - } - - if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size)) - { - status = 1; - bfd_nonfatal_message (NULL, obfd, osection, NULL); - return; - } - free (memhunk); - } - else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0) - { - void *memhunk = xmalloc (size); - - /* We don't permit the user to turn off the SEC_HAS_CONTENTS - flag--they can just remove the section entirely and add it - back again. However, we do permit them to turn on the - SEC_HAS_CONTENTS flag, and take it to mean that the section - contents should be zeroed out. */ - - memset (memhunk, 0, size); - if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size)) - { - status = 1; - bfd_nonfatal_message (NULL, obfd, osection, NULL); - return; - } - free (memhunk); - } -} - -/* Get all the sections. This is used when --gap-fill or --pad-to is - used. */ - -static void -get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg) -{ - asection ***secppp = (asection ***) secppparg; - - **secppp = osection; - ++(*secppp); -} - -/* Sort sections by VMA. This is called via qsort, and is used when - --gap-fill or --pad-to is used. We force non loadable or empty - sections to the front, where they are easier to ignore. */ - -static int -compare_section_lma (const void *arg1, const void *arg2) -{ - const asection *const *sec1 = (const asection * const *) arg1; - const asection *const *sec2 = (const asection * const *) arg2; - flagword flags1, flags2; - - /* Sort non loadable sections to the front. */ - flags1 = (*sec1)->flags; - flags2 = (*sec2)->flags; - if ((flags1 & SEC_HAS_CONTENTS) == 0 - || (flags1 & SEC_LOAD) == 0) - { - if ((flags2 & SEC_HAS_CONTENTS) != 0 - && (flags2 & SEC_LOAD) != 0) - return -1; - } - else - { - if ((flags2 & SEC_HAS_CONTENTS) == 0 - || (flags2 & SEC_LOAD) == 0) - return 1; - } - - /* Sort sections by LMA. */ - if ((*sec1)->lma > (*sec2)->lma) - return 1; - else if ((*sec1)->lma < (*sec2)->lma) - return -1; - - /* Sort sections with the same LMA by size. */ - if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2)) - return 1; - else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2)) - return -1; - - return 0; -} - -/* Mark all the symbols which will be used in output relocations with - the BSF_KEEP flag so that those symbols will not be stripped. - - Ignore relocations which will not appear in the output file. */ - -static void -mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg) -{ - asymbol **symbols = (asymbol **) symbolsarg; - long relsize; - arelent **relpp; - long relcount, i; - - /* Ignore an input section with no corresponding output section. */ - if (isection->output_section == NULL) - return; - - relsize = bfd_get_reloc_upper_bound (ibfd, isection); - if (relsize < 0) - { - /* Do not complain if the target does not support relocations. */ - if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation) - return; - bfd_fatal (bfd_get_filename (ibfd)); - } - - if (relsize == 0) - return; - - relpp = (arelent **) xmalloc (relsize); - relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols); - if (relcount < 0) - bfd_fatal (bfd_get_filename (ibfd)); - - /* Examine each symbol used in a relocation. If it's not one of the - special bfd section symbols, then mark it with BSF_KEEP. */ - for (i = 0; i < relcount; i++) - { - if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol - && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol - && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol) - (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP; - } - - if (relpp != NULL) - free (relpp); -} - -/* Write out debugging information. */ - -static bfd_boolean -write_debugging_info (bfd *obfd, void *dhandle, - long *symcountp ATTRIBUTE_UNUSED, - asymbol ***symppp ATTRIBUTE_UNUSED) -{ - if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour) - return write_ieee_debugging_info (obfd, dhandle); - - if (bfd_get_flavour (obfd) == bfd_target_coff_flavour - || bfd_get_flavour (obfd) == bfd_target_elf_flavour) - { - bfd_byte *syms, *strings; - bfd_size_type symsize, stringsize; - asection *stabsec, *stabstrsec; - flagword flags; - - if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms, - &symsize, &strings, - &stringsize)) - return FALSE; - - flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING; - stabsec = bfd_make_section_with_flags (obfd, ".stab", flags); - stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags); - if (stabsec == NULL - || stabstrsec == NULL - || ! bfd_set_section_size (obfd, stabsec, symsize) - || ! bfd_set_section_size (obfd, stabstrsec, stringsize) - || ! bfd_set_section_alignment (obfd, stabsec, 2) - || ! bfd_set_section_alignment (obfd, stabstrsec, 0)) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("can't create debugging section")); - return FALSE; - } - - /* We can get away with setting the section contents now because - the next thing the caller is going to do is copy over the - real sections. We may someday have to split the contents - setting out of this function. */ - if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize) - || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0, - stringsize)) - { - bfd_nonfatal_message (NULL, obfd, NULL, - _("can't set debugging section contents")); - return FALSE; - } - - return TRUE; - } - - bfd_nonfatal_message (NULL, obfd, NULL, - _("don't know how to write debugging information for %s"), - bfd_get_target (obfd)); - return FALSE; -} - -static int -strip_main (int argc, char *argv[]) -{ - char *input_target = NULL; - char *output_target = NULL; - bfd_boolean show_version = FALSE; - bfd_boolean formats_info = FALSE; - int c; - int i; - struct section_list *p; - char *output_file = NULL; - - while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw", - strip_options, (int *) 0)) != EOF) - { - switch (c) - { - case 'I': - input_target = optarg; - break; - case 'O': - output_target = optarg; - break; - case 'F': - input_target = output_target = optarg; - break; - case 'R': - p = find_section_list (optarg, TRUE); - p->remove = TRUE; - sections_removed = TRUE; - break; - case 's': - strip_symbols = STRIP_ALL; - break; - case 'S': - case 'g': - case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */ - strip_symbols = STRIP_DEBUG; - break; - case OPTION_STRIP_UNNEEDED: - strip_symbols = STRIP_UNNEEDED; - break; - case 'K': - add_specific_symbol (optarg, keep_specific_htab); - break; - case 'N': - add_specific_symbol (optarg, strip_specific_htab); - break; - case 'o': - output_file = optarg; - break; - case 'p': - preserve_dates = TRUE; - break; - case 'x': - discard_locals = LOCALS_ALL; - break; - case 'X': - discard_locals = LOCALS_START_L; - break; - case 'v': - verbose = TRUE; - break; - case 'V': - show_version = TRUE; - break; - case OPTION_FORMATS_INFO: - formats_info = TRUE; - break; - case OPTION_ONLY_KEEP_DEBUG: - strip_symbols = STRIP_NONDEBUG; - break; - case OPTION_KEEP_FILE_SYMBOLS: - keep_file_symbols = 1; - break; - case 0: - /* We've been given a long option. */ - break; - case 'w': - wildcard = TRUE; - break; - case 'H': - case 'h': - strip_usage (stdout, 0); - default: - strip_usage (stderr, 1); - } - } - - if (formats_info) - { - display_info (); - return 0; - } - - if (show_version) - print_version ("strip"); - - /* Default is to strip all symbols. */ - if (strip_symbols == STRIP_UNDEF - && discard_locals == LOCALS_UNDEF - && htab_elements (strip_specific_htab) == 0) - strip_symbols = STRIP_ALL; - - if (output_target == NULL) - output_target = input_target; - - i = optind; - if (i == argc - || (output_file != NULL && (i + 1) < argc)) - strip_usage (stderr, 1); - - for (; i < argc; i++) - { - int hold_status = status; - struct stat statbuf; - char *tmpname; - - if (get_file_size (argv[i]) < 1) - { - status = 1; - continue; - } - - if (preserve_dates) - /* No need to check the return value of stat(). - It has already been checked in get_file_size(). */ - stat (argv[i], &statbuf); - - if (output_file == NULL - || filename_cmp (argv[i], output_file) == 0) - tmpname = make_tempname (argv[i]); - else - tmpname = output_file; - - if (tmpname == NULL) - { - bfd_nonfatal_message (argv[i], NULL, NULL, - _("could not create temporary file to hold stripped copy")); - status = 1; - continue; - } - - status = 0; - copy_file (argv[i], tmpname, input_target, output_target, NULL); - if (status == 0) - { - if (preserve_dates) - set_times (tmpname, &statbuf); - if (output_file != tmpname) - status = (smart_rename (tmpname, - output_file ? output_file : argv[i], - preserve_dates) != 0); - if (status == 0) - status = hold_status; - } - else - unlink_if_ordinary (tmpname); - if (output_file != tmpname) - free (tmpname); - } - - return status; -} - -/* Set up PE subsystem. */ - -static void -set_pe_subsystem (const char *s) -{ - const char *version, *subsystem; - size_t i; - static const struct - { - const char *name; - const char set_def; - const short value; - } - v[] = - { - { "native", 0, IMAGE_SUBSYSTEM_NATIVE }, - { "windows", 0, IMAGE_SUBSYSTEM_WINDOWS_GUI }, - { "console", 0, IMAGE_SUBSYSTEM_WINDOWS_CUI }, - { "posix", 0, IMAGE_SUBSYSTEM_POSIX_CUI }, - { "wince", 0, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI }, - { "efi-app", 1, IMAGE_SUBSYSTEM_EFI_APPLICATION }, - { "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER }, - { "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER }, - { "sal-rtd", 1, IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER }, - { "xbox", 0, IMAGE_SUBSYSTEM_XBOX } - }; - short value; - char *copy; - int set_def = -1; - - /* Check for the presence of a version number. */ - version = strchr (s, ':'); - if (version == NULL) - subsystem = s; - else - { - int len = version - s; - copy = xstrdup (s); - subsystem = copy; - copy[len] = '\0'; - version = copy + 1 + len; - pe_major_subsystem_version = strtoul (version, ©, 0); - if (*copy == '.') - pe_minor_subsystem_version = strtoul (copy + 1, ©, 0); - if (*copy != '\0') - non_fatal (_("%s: bad version in PE subsystem"), s); - } - - /* Check for numeric subsystem. */ - value = (short) strtol (subsystem, ©, 0); - if (*copy == '\0') - { - for (i = 0; i < ARRAY_SIZE (v); i++) - if (v[i].value == value) - { - pe_subsystem = value; - set_def = v[i].set_def; - break; - } - } - else - { - /* Search for subsystem by name. */ - for (i = 0; i < ARRAY_SIZE (v); i++) - if (strcmp (subsystem, v[i].name) == 0) - { - pe_subsystem = v[i].value; - set_def = v[i].set_def; - break; - } - } - - switch (set_def) - { - case -1: - fatal (_("unknown PE subsystem: %s"), s); - break; - case 0: - break; - default: - if (pe_file_alignment == (bfd_vma) -1) - pe_file_alignment = PE_DEF_FILE_ALIGNMENT; - if (pe_section_alignment == (bfd_vma) -1) - pe_section_alignment = PE_DEF_SECTION_ALIGNMENT; - break; - } - if (s != subsystem) - free ((char *) subsystem); -} - -/* Convert EFI target to PEI target. */ - -static void -convert_efi_target (char *efi) -{ - efi[0] = 'p'; - efi[1] = 'e'; - efi[2] = 'i'; - - if (strcmp (efi + 4, "ia32") == 0) - { - /* Change ia32 to i386. */ - efi[5]= '3'; - efi[6]= '8'; - efi[7]= '6'; - } - else if (strcmp (efi + 4, "x86_64") == 0) - { - /* Change x86_64 to x86-64. */ - efi[7] = '-'; - } -} - -static int -copy_main (int argc, char *argv[]) -{ - char *input_filename = NULL; - char *output_filename = NULL; - char *tmpname; - char *input_target = NULL; - char *output_target = NULL; - bfd_boolean show_version = FALSE; - bfd_boolean change_warn = TRUE; - bfd_boolean formats_info = FALSE; - int c; - struct section_list *p; - struct stat statbuf; - const bfd_arch_info_type *input_arch = NULL; - - while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w", - copy_options, (int *) 0)) != EOF) - { - switch (c) - { - case 'b': - copy_byte = atoi (optarg); - if (copy_byte < 0) - fatal (_("byte number must be non-negative")); - break; - - case 'B': - input_arch = bfd_scan_arch (optarg); - if (input_arch == NULL) - fatal (_("architecture %s unknown"), optarg); - break; - - case 'i': - if (optarg) - { - interleave = atoi (optarg); - if (interleave < 1) - fatal (_("interleave must be positive")); - } - else - interleave = 4; - break; - - case OPTION_INTERLEAVE_WIDTH: - copy_width = atoi (optarg); - if (copy_width < 1) - fatal(_("interleave width must be positive")); - break; - - case 'I': - case 's': /* "source" - 'I' is preferred */ - input_target = optarg; - break; - - case 'O': - case 'd': /* "destination" - 'O' is preferred */ - output_target = optarg; - break; - - case 'F': - input_target = output_target = optarg; - break; - - case 'j': - p = find_section_list (optarg, TRUE); - if (p->remove) - fatal (_("%s both copied and removed"), optarg); - p->copy = TRUE; - sections_copied = TRUE; - break; - - case 'R': - p = find_section_list (optarg, TRUE); - if (p->copy) - fatal (_("%s both copied and removed"), optarg); - p->remove = TRUE; - sections_removed = TRUE; - break; - - case 'S': - strip_symbols = STRIP_ALL; - break; - - case 'g': - strip_symbols = STRIP_DEBUG; - break; - - case OPTION_STRIP_UNNEEDED: - strip_symbols = STRIP_UNNEEDED; - break; - - case OPTION_ONLY_KEEP_DEBUG: - strip_symbols = STRIP_NONDEBUG; - break; - - case OPTION_KEEP_FILE_SYMBOLS: - keep_file_symbols = 1; - break; - - case OPTION_ADD_GNU_DEBUGLINK: - gnu_debuglink_filename = optarg; - break; - - case 'K': - add_specific_symbol (optarg, keep_specific_htab); - break; - - case 'N': - add_specific_symbol (optarg, strip_specific_htab); - break; - - case OPTION_STRIP_UNNEEDED_SYMBOL: - add_specific_symbol (optarg, strip_unneeded_htab); - break; - - case 'L': - add_specific_symbol (optarg, localize_specific_htab); - break; - - case OPTION_GLOBALIZE_SYMBOL: - add_specific_symbol (optarg, globalize_specific_htab); - break; - - case 'G': - add_specific_symbol (optarg, keepglobal_specific_htab); - break; - - case 'W': - add_specific_symbol (optarg, weaken_specific_htab); - break; - - case 'p': - preserve_dates = TRUE; - break; - - case 'w': - wildcard = TRUE; - break; - - case 'x': - discard_locals = LOCALS_ALL; - break; - - case 'X': - discard_locals = LOCALS_START_L; - break; - - case 'v': - verbose = TRUE; - break; - - case 'V': - show_version = TRUE; - break; - - case OPTION_FORMATS_INFO: - formats_info = TRUE; - break; - - case OPTION_WEAKEN: - weaken = TRUE; - break; - - case OPTION_ADD_SECTION: - { - const char *s; - size_t off, alloc; - struct section_add *pa; - FILE *f; - - s = strchr (optarg, '='); - - if (s == NULL) - fatal (_("bad format for %s"), "--add-section"); - - pa = (struct section_add *) xmalloc (sizeof (struct section_add)); - pa->name = xstrndup (optarg, s - optarg); - pa->filename = s + 1; - - /* We don't use get_file_size so that we can do - --add-section .note.GNU_stack=/dev/null - get_file_size doesn't work on /dev/null. */ - - f = fopen (pa->filename, FOPEN_RB); - if (f == NULL) - fatal (_("cannot open: %s: %s"), - pa->filename, strerror (errno)); - - off = 0; - alloc = 4096; - pa->contents = (bfd_byte *) xmalloc (alloc); - while (!feof (f)) - { - off_t got; - - if (off == alloc) - { - alloc <<= 1; - pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc); - } - - got = fread (pa->contents + off, 1, alloc - off, f); - if (ferror (f)) - fatal (_("%s: fread failed"), pa->filename); - - off += got; - } - - pa->size = off; - - fclose (f); - - pa->next = add_sections; - add_sections = pa; - } - break; - - case OPTION_CHANGE_START: - change_start = parse_vma (optarg, "--change-start"); - break; - - case OPTION_CHANGE_SECTION_ADDRESS: - case OPTION_CHANGE_SECTION_LMA: - case OPTION_CHANGE_SECTION_VMA: - { - const char *s; - int len; - char *name; - char *option = NULL; - bfd_vma val; - enum change_action what = CHANGE_IGNORE; - - switch (c) - { - case OPTION_CHANGE_SECTION_ADDRESS: - option = "--change-section-address"; - break; - case OPTION_CHANGE_SECTION_LMA: - option = "--change-section-lma"; - break; - case OPTION_CHANGE_SECTION_VMA: - option = "--change-section-vma"; - break; - } - - s = strchr (optarg, '='); - if (s == NULL) - { - s = strchr (optarg, '+'); - if (s == NULL) - { - s = strchr (optarg, '-'); - if (s == NULL) - fatal (_("bad format for %s"), option); - } - } - - len = s - optarg; - name = (char *) xmalloc (len + 1); - strncpy (name, optarg, len); - name[len] = '\0'; - - p = find_section_list (name, TRUE); - - val = parse_vma (s + 1, option); - - switch (*s) - { - case '=': what = CHANGE_SET; break; - case '-': val = - val; /* Drop through. */ - case '+': what = CHANGE_MODIFY; break; - } - - switch (c) - { - case OPTION_CHANGE_SECTION_ADDRESS: - p->change_vma = what; - p->vma_val = val; - /* Drop through. */ - - case OPTION_CHANGE_SECTION_LMA: - p->change_lma = what; - p->lma_val = val; - break; - - case OPTION_CHANGE_SECTION_VMA: - p->change_vma = what; - p->vma_val = val; - break; - } - } - break; - - case OPTION_CHANGE_ADDRESSES: - change_section_address = parse_vma (optarg, "--change-addresses"); - change_start = change_section_address; - break; - - case OPTION_CHANGE_WARNINGS: - change_warn = TRUE; - break; - - case OPTION_CHANGE_LEADING_CHAR: - change_leading_char = TRUE; - break; - - case OPTION_COMPRESS_DEBUG_SECTIONS: - do_debug_sections = compress; - break; - - case OPTION_DEBUGGING: - convert_debugging = TRUE; - break; - - case OPTION_DECOMPRESS_DEBUG_SECTIONS: - do_debug_sections = decompress; - break; - - case OPTION_GAP_FILL: - { - bfd_vma gap_fill_vma; - - gap_fill_vma = parse_vma (optarg, "--gap-fill"); - gap_fill = (bfd_byte) gap_fill_vma; - if ((bfd_vma) gap_fill != gap_fill_vma) - { - char buff[20]; - - sprintf_vma (buff, gap_fill_vma); - - non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"), - buff, gap_fill); - } - gap_fill_set = TRUE; - } - break; - - case OPTION_NO_CHANGE_WARNINGS: - change_warn = FALSE; - break; - - case OPTION_PAD_TO: - pad_to = parse_vma (optarg, "--pad-to"); - pad_to_set = TRUE; - break; - - case OPTION_REMOVE_LEADING_CHAR: - remove_leading_char = TRUE; - break; - - case OPTION_REDEFINE_SYM: - { - /* Push this redefinition onto redefine_symbol_list. */ - - int len; - const char *s; - const char *nextarg; - char *source, *target; - - s = strchr (optarg, '='); - if (s == NULL) - fatal (_("bad format for %s"), "--redefine-sym"); - - len = s - optarg; - source = (char *) xmalloc (len + 1); - strncpy (source, optarg, len); - source[len] = '\0'; - - nextarg = s + 1; - len = strlen (nextarg); - target = (char *) xmalloc (len + 1); - strcpy (target, nextarg); - - redefine_list_append ("--redefine-sym", source, target); - - free (source); - free (target); - } - break; - - case OPTION_REDEFINE_SYMS: - add_redefine_syms_file (optarg); - break; - - case OPTION_SET_SECTION_FLAGS: - { - const char *s; - int len; - char *name; - - s = strchr (optarg, '='); - if (s == NULL) - fatal (_("bad format for %s"), "--set-section-flags"); - - len = s - optarg; - name = (char *) xmalloc (len + 1); - strncpy (name, optarg, len); - name[len] = '\0'; - - p = find_section_list (name, TRUE); - - p->set_flags = TRUE; - p->flags = parse_flags (s + 1); - } - break; - - case OPTION_RENAME_SECTION: - { - flagword flags; - const char *eq, *fl; - char *old_name; - char *new_name; - unsigned int len; - - eq = strchr (optarg, '='); - if (eq == NULL) - fatal (_("bad format for %s"), "--rename-section"); - - len = eq - optarg; - if (len == 0) - fatal (_("bad format for %s"), "--rename-section"); - - old_name = (char *) xmalloc (len + 1); - strncpy (old_name, optarg, len); - old_name[len] = 0; - - eq++; - fl = strchr (eq, ','); - if (fl) - { - flags = parse_flags (fl + 1); - len = fl - eq; - } - else - { - flags = -1; - len = strlen (eq); - } - - if (len == 0) - fatal (_("bad format for %s"), "--rename-section"); - - new_name = (char *) xmalloc (len + 1); - strncpy (new_name, eq, len); - new_name[len] = 0; - - add_section_rename (old_name, new_name, flags); - } - break; - - case OPTION_SET_START: - set_start = parse_vma (optarg, "--set-start"); - set_start_set = TRUE; - break; - - case OPTION_SREC_LEN: - Chunk = parse_vma (optarg, "--srec-len"); - break; - - case OPTION_SREC_FORCES3: - S3Forced = TRUE; - break; - - case OPTION_STRIP_SYMBOLS: - add_specific_symbols (optarg, strip_specific_htab); - break; - - case OPTION_STRIP_UNNEEDED_SYMBOLS: - add_specific_symbols (optarg, strip_unneeded_htab); - break; - - case OPTION_KEEP_SYMBOLS: - add_specific_symbols (optarg, keep_specific_htab); - break; - - case OPTION_LOCALIZE_HIDDEN: - localize_hidden = TRUE; - break; - - case OPTION_LOCALIZE_SYMBOLS: - add_specific_symbols (optarg, localize_specific_htab); - break; - - case OPTION_LONG_SECTION_NAMES: - if (!strcmp ("enable", optarg)) - long_section_names = ENABLE; - else if (!strcmp ("disable", optarg)) - long_section_names = DISABLE; - else if (!strcmp ("keep", optarg)) - long_section_names = KEEP; - else - fatal (_("unknown long section names option '%s'"), optarg); - break; - - case OPTION_GLOBALIZE_SYMBOLS: - add_specific_symbols (optarg, globalize_specific_htab); - break; - - case OPTION_KEEPGLOBAL_SYMBOLS: - add_specific_symbols (optarg, keepglobal_specific_htab); - break; - - case OPTION_WEAKEN_SYMBOLS: - add_specific_symbols (optarg, weaken_specific_htab); - break; - - case OPTION_ALT_MACH_CODE: - use_alt_mach_code = strtoul (optarg, NULL, 0); - if (use_alt_mach_code == 0) - fatal (_("unable to parse alternative machine code")); - break; - - case OPTION_PREFIX_SYMBOLS: - prefix_symbols_string = optarg; - break; - - case OPTION_PREFIX_SECTIONS: - prefix_sections_string = optarg; - break; - - case OPTION_PREFIX_ALLOC_SECTIONS: - prefix_alloc_sections_string = optarg; - break; - - case OPTION_READONLY_TEXT: - bfd_flags_to_set |= WP_TEXT; - bfd_flags_to_clear &= ~WP_TEXT; - break; - - case OPTION_WRITABLE_TEXT: - bfd_flags_to_clear |= WP_TEXT; - bfd_flags_to_set &= ~WP_TEXT; - break; - - case OPTION_PURE: - bfd_flags_to_set |= D_PAGED; - bfd_flags_to_clear &= ~D_PAGED; - break; - - case OPTION_IMPURE: - bfd_flags_to_clear |= D_PAGED; - bfd_flags_to_set &= ~D_PAGED; - break; - - case OPTION_EXTRACT_SYMBOL: - extract_symbol = TRUE; - break; - - case OPTION_REVERSE_BYTES: - { - int prev = reverse_bytes; - - reverse_bytes = atoi (optarg); - if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0)) - fatal (_("number of bytes to reverse must be positive and even")); - - if (prev && prev != reverse_bytes) - non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"), - prev); - break; - } - - case OPTION_FILE_ALIGNMENT: - pe_file_alignment = parse_vma (optarg, "--file-alignment"); - break; - - case OPTION_HEAP: - { - char *end; - pe_heap_reserve = strtoul (optarg, &end, 0); - if (end == optarg - || (*end != '.' && *end != '\0')) - non_fatal (_("%s: invalid reserve value for --heap"), - optarg); - else if (*end != '\0') - { - pe_heap_commit = strtoul (end + 1, &end, 0); - if (*end != '\0') - non_fatal (_("%s: invalid commit value for --heap"), - optarg); - } - } - break; - - case OPTION_IMAGE_BASE: - pe_image_base = parse_vma (optarg, "--image-base"); - break; - - case OPTION_SECTION_ALIGNMENT: - pe_section_alignment = parse_vma (optarg, - "--section-alignment"); - break; - - case OPTION_SUBSYSTEM: - set_pe_subsystem (optarg); - break; - - case OPTION_STACK: - { - char *end; - pe_stack_reserve = strtoul (optarg, &end, 0); - if (end == optarg - || (*end != '.' && *end != '\0')) - non_fatal (_("%s: invalid reserve value for --stack"), - optarg); - else if (*end != '\0') - { - pe_stack_commit = strtoul (end + 1, &end, 0); - if (*end != '\0') - non_fatal (_("%s: invalid commit value for --stack"), - optarg); - } - } - break; - - case 0: - /* We've been given a long option. */ - break; - - case 'H': - case 'h': - copy_usage (stdout, 0); - - default: - copy_usage (stderr, 1); - } - } - - if (formats_info) - { - display_info (); - return 0; - } - - if (show_version) - print_version ("objcopy"); - - if (interleave && copy_byte == -1) - fatal (_("interleave start byte must be set with --byte")); - - if (copy_byte >= interleave) - fatal (_("byte number must be less than interleave")); - - if (copy_width > interleave - copy_byte) - fatal (_("interleave width must be less than or equal to interleave - byte`")); - - if (optind == argc || optind + 2 < argc) - copy_usage (stderr, 1); - - input_filename = argv[optind]; - if (optind + 1 < argc) - output_filename = argv[optind + 1]; - - /* Default is to strip no symbols. */ - if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF) - strip_symbols = STRIP_NONE; - - if (output_target == NULL) - output_target = input_target; - - /* Convert input EFI target to PEI target. */ - if (input_target != NULL - && strncmp (input_target, "efi-", 4) == 0) - { - char *efi; - - efi = xstrdup (output_target + 4); - if (strncmp (efi, "bsdrv-", 6) == 0 - || strncmp (efi, "rtdrv-", 6) == 0) - efi += 2; - else if (strncmp (efi, "app-", 4) != 0) - fatal (_("unknown input EFI target: %s"), input_target); - - input_target = efi; - convert_efi_target (efi); - } - - /* Convert output EFI target to PEI target. */ - if (output_target != NULL - && strncmp (output_target, "efi-", 4) == 0) - { - char *efi; - - efi = xstrdup (output_target + 4); - if (strncmp (efi, "app-", 4) == 0) - { - if (pe_subsystem == -1) - pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION; - } - else if (strncmp (efi, "bsdrv-", 6) == 0) - { - if (pe_subsystem == -1) - pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - efi += 2; - } - else if (strncmp (efi, "rtdrv-", 6) == 0) - { - if (pe_subsystem == -1) - pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; - efi += 2; - } - else - fatal (_("unknown output EFI target: %s"), output_target); - - if (pe_file_alignment == (bfd_vma) -1) - pe_file_alignment = PE_DEF_FILE_ALIGNMENT; - if (pe_section_alignment == (bfd_vma) -1) - pe_section_alignment = PE_DEF_SECTION_ALIGNMENT; - - output_target = efi; - convert_efi_target (efi); - } - - if (preserve_dates) - if (stat (input_filename, & statbuf) < 0) - fatal (_("warning: could not locate '%s'. System error message: %s"), - input_filename, strerror (errno)); - - /* If there is no destination file, or the source and destination files - are the same, then create a temp and rename the result into the input. */ - if (output_filename == NULL - || filename_cmp (input_filename, output_filename) == 0) - tmpname = make_tempname (input_filename); - else - tmpname = output_filename; - - if (tmpname == NULL) - fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"), - input_filename, strerror (errno)); - - copy_file (input_filename, tmpname, input_target, output_target, input_arch); - if (status == 0) - { - if (preserve_dates) - set_times (tmpname, &statbuf); - if (tmpname != output_filename) - status = (smart_rename (tmpname, input_filename, - preserve_dates) != 0); - } - else - unlink_if_ordinary (tmpname); - - if (change_warn) - { - for (p = change_sections; p != NULL; p = p->next) - { - if (! p->used) - { - if (p->change_vma != CHANGE_IGNORE) - { - char buff [20]; - - sprintf_vma (buff, p->vma_val); - - /* xgettext:c-format */ - non_fatal (_("%s %s%c0x%s never used"), - "--change-section-vma", - p->name, - p->change_vma == CHANGE_SET ? '=' : '+', - buff); - } - - if (p->change_lma != CHANGE_IGNORE) - { - char buff [20]; - - sprintf_vma (buff, p->lma_val); - - /* xgettext:c-format */ - non_fatal (_("%s %s%c0x%s never used"), - "--change-section-lma", - p->name, - p->change_lma == CHANGE_SET ? '=' : '+', - buff); - } - } - } - } - - return 0; -} - -int -main (int argc, char *argv[]) -{ -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = argv[0]; - xmalloc_set_program_name (program_name); - - START_PROGRESS (program_name, 0); - - expandargv (&argc, &argv); - - strip_symbols = STRIP_UNDEF; - discard_locals = LOCALS_UNDEF; - - bfd_init (); - set_default_bfd_target (); - - if (is_strip < 0) - { - int i = strlen (program_name); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* Drop the .exe suffix, if any. */ - if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0) - { - i -= 4; - program_name[i] = '\0'; - } -#endif - is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0); - } - - create_symbol_htabs (); - - if (is_strip) - strip_main (argc, argv); - else - copy_main (argc, argv); - - END_PROGRESS (program_name); - - return status; -} diff --git a/contrib/binutils-2.22/binutils/objdump.c b/contrib/binutils-2.22/binutils/objdump.c deleted file mode 100644 index 784ead27e0..0000000000 --- a/contrib/binutils-2.22/binutils/objdump.c +++ /dev/null @@ -1,3638 +0,0 @@ -/* objdump.c -- dump information about an object file. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - - -/* Objdump overview. - - Objdump displays information about one or more object files, either on - their own, or inside libraries. It is commonly used as a disassembler, - but it can also display information about file headers, symbol tables, - relocations, debugging directives and more. - - The flow of execution is as follows: - - 1. Command line arguments are checked for control switches and the - information to be displayed is selected. - - 2. Any remaining arguments are assumed to be object files, and they are - processed in order by display_bfd(). If the file is an archive each - of its elements is processed in turn. - - 3. The file's target architecture and binary file format are determined - by bfd_check_format(). If they are recognised, then dump_bfd() is - called. - - 4. dump_bfd() in turn calls separate functions to display the requested - item(s) of information(s). For example disassemble_data() is called if - a disassembly has been requested. - - When disassembling the code loops through blocks of instructions bounded - by symbols, calling disassemble_bytes() on each block. The actual - disassembling is done by the libopcodes library, via a function pointer - supplied by the disassembler() function. */ - -#include "sysdep.h" -#include "bfd.h" -#include "elf-bfd.h" -#include "progress.h" -#include "bucomm.h" -#include "elfcomm.h" -#include "dwarf.h" -#include "getopt.h" -#include "safe-ctype.h" -#include "dis-asm.h" -#include "libiberty.h" -#include "demangle.h" -#include "filenames.h" -#include "debug.h" -#include "budbg.h" -#include "objdump.h" - -#ifdef HAVE_MMAP -#include -#endif - -#include - -/* Internal headers for the ELF .stab-dump code - sorry. */ -#define BYTES_IN_WORD 32 -#include "aout/aout64.h" - -/* Exit status. */ -static int exit_status = 0; - -static char *default_target = NULL; /* Default at runtime. */ - -/* The following variables are set based on arguments passed on the - command line. */ -static int show_version = 0; /* Show the version number. */ -static int dump_section_contents; /* -s */ -static int dump_section_headers; /* -h */ -static bfd_boolean dump_file_header; /* -f */ -static int dump_symtab; /* -t */ -static int dump_dynamic_symtab; /* -T */ -static int dump_reloc_info; /* -r */ -static int dump_dynamic_reloc_info; /* -R */ -static int dump_ar_hdrs; /* -a */ -static int dump_private_headers; /* -p */ -static char *dump_private_options; /* -P */ -static int prefix_addresses; /* --prefix-addresses */ -static int with_line_numbers; /* -l */ -static bfd_boolean with_source_code; /* -S */ -static int show_raw_insn; /* --show-raw-insn */ -static int dump_dwarf_section_info; /* --dwarf */ -static int dump_stab_section_info; /* --stabs */ -static int do_demangle; /* -C, --demangle */ -static bfd_boolean disassemble; /* -d */ -static bfd_boolean disassemble_all; /* -D */ -static int disassemble_zeroes; /* --disassemble-zeroes */ -static bfd_boolean formats_info; /* -i */ -static int wide_output; /* -w */ -static int insn_width; /* --insn-width */ -static bfd_vma start_address = (bfd_vma) -1; /* --start-address */ -static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */ -static int dump_debugging; /* --debugging */ -static int dump_debugging_tags; /* --debugging-tags */ -static int suppress_bfd_header; -static int dump_special_syms = 0; /* --special-syms */ -static bfd_vma adjust_section_vma = 0; /* --adjust-vma */ -static int file_start_context = 0; /* --file-start-context */ -static bfd_boolean display_file_offsets;/* -F */ -static const char *prefix; /* --prefix */ -static int prefix_strip; /* --prefix-strip */ -static size_t prefix_length; - -/* A structure to record the sections mentioned in -j switches. */ -struct only -{ - const char * name; /* The name of the section. */ - bfd_boolean seen; /* A flag to indicate that the section has been found in one or more input files. */ - struct only * next; /* Pointer to the next structure in the list. */ -}; -/* Pointer to an array of 'only' structures. - This pointer is NULL if the -j switch has not been used. */ -static struct only * only_list = NULL; - -/* Variables for handling include file path table. */ -static const char **include_paths; -static int include_path_count; - -/* Extra info to pass to the section disassembler and address printing - function. */ -struct objdump_disasm_info -{ - bfd * abfd; - asection * sec; - bfd_boolean require_sec; - arelent ** dynrelbuf; - long dynrelcount; - disassembler_ftype disassemble_fn; - arelent * reloc; -}; - -/* Architecture to disassemble for, or default if NULL. */ -static char *machine = NULL; - -/* Target specific options to the disassembler. */ -static char *disassembler_options = NULL; - -/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */ -static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN; - -/* The symbol table. */ -static asymbol **syms; - -/* Number of symbols in `syms'. */ -static long symcount = 0; - -/* The sorted symbol table. */ -static asymbol **sorted_syms; - -/* Number of symbols in `sorted_syms'. */ -static long sorted_symcount = 0; - -/* The dynamic symbol table. */ -static asymbol **dynsyms; - -/* The synthetic symbol table. */ -static asymbol *synthsyms; -static long synthcount = 0; - -/* Number of symbols in `dynsyms'. */ -static long dynsymcount = 0; - -static bfd_byte *stabs; -static bfd_size_type stab_size; - -static char *strtab; -static bfd_size_type stabstr_size; - -static bfd_boolean is_relocatable = FALSE; - -/* Handlers for -P/--private. */ -static const struct objdump_private_desc * const objdump_private_vectors[] = - { - OBJDUMP_PRIVATE_VECTORS - NULL - }; - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, _("Usage: %s \n"), program_name); - fprintf (stream, _(" Display information from object .\n")); - fprintf (stream, _(" At least one of the following switches must be given:\n")); - fprintf (stream, _("\ - -a, --archive-headers Display archive header information\n\ - -f, --file-headers Display the contents of the overall file header\n\ - -p, --private-headers Display object format specific file header contents\n\ - -P, --private=OPT,OPT... Display object format specific contents\n\ - -h, --[section-]headers Display the contents of the section headers\n\ - -x, --all-headers Display the contents of all headers\n\ - -d, --disassemble Display assembler contents of executable sections\n\ - -D, --disassemble-all Display assembler contents of all sections\n\ - -S, --source Intermix source code with disassembly\n\ - -s, --full-contents Display the full contents of all sections requested\n\ - -g, --debugging Display debug information in object file\n\ - -e, --debugging-tags Display debug information using ctags style\n\ - -G, --stabs Display (in raw form) any STABS info in the file\n\ - -W[lLiaprmfFsoRt] or\n\ - --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ - =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\ - =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\ - Display DWARF info in the file\n\ - -t, --syms Display the contents of the symbol table(s)\n\ - -T, --dynamic-syms Display the contents of the dynamic symbol table\n\ - -r, --reloc Display the relocation entries in the file\n\ - -R, --dynamic-reloc Display the dynamic relocation entries in the file\n\ - @ Read options from \n\ - -v, --version Display this program's version number\n\ - -i, --info List object formats and architectures supported\n\ - -H, --help Display this information\n\ -")); - if (status != 2) - { - const struct objdump_private_desc * const *desc; - - fprintf (stream, _("\n The following switches are optional:\n")); - fprintf (stream, _("\ - -b, --target=BFDNAME Specify the target object format as BFDNAME\n\ - -m, --architecture=MACHINE Specify the target architecture as MACHINE\n\ - -j, --section=NAME Only display information for section NAME\n\ - -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\ - -EB --endian=big Assume big endian format when disassembling\n\ - -EL --endian=little Assume little endian format when disassembling\n\ - --file-start-context Include context from start of file (with -S)\n\ - -I, --include=DIR Add DIR to search list for source files\n\ - -l, --line-numbers Include line numbers and filenames in output\n\ - -F, --file-offsets Include file offsets when displaying information\n\ - -C, --demangle[=STYLE] Decode mangled/processed symbol names\n\ - The STYLE, if specified, can be `auto', `gnu',\n\ - `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\ - or `gnat'\n\ - -w, --wide Format output for more than 80 columns\n\ - -z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\ - --start-address=ADDR Only process data whose address is >= ADDR\n\ - --stop-address=ADDR Only process data whose address is <= ADDR\n\ - --prefix-addresses Print complete address alongside disassembly\n\ - --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ - --insn-width=WIDTH Display WIDTH bytes on a single line for -d\n\ - --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\ - --special-syms Include special symbols in symbol dumps\n\ - --prefix=PREFIX Add PREFIX to absolute paths for -S\n\ - --prefix-strip=LEVEL Strip initial directory names for -S\n")); - fprintf (stream, _("\ - --dwarf-depth=N Do not display DIEs at depth N or greater\n\ - --dwarf-start=N Display DIEs starting with N, at the same depth\n\ - or deeper\n\n")); - list_supported_targets (program_name, stream); - list_supported_architectures (program_name, stream); - - disassembler_usage (stream); - - if (objdump_private_vectors[0] != NULL) - { - fprintf (stream, - _("\nOptions supported for -P/--private switch:\n")); - for (desc = objdump_private_vectors; *desc != NULL; desc++) - (*desc)->help (stream); - } - } - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO); - exit (status); -} - -/* 150 isn't special; it's just an arbitrary non-ASCII char value. */ -enum option_values - { - OPTION_ENDIAN=150, - OPTION_START_ADDRESS, - OPTION_STOP_ADDRESS, - OPTION_DWARF, - OPTION_PREFIX, - OPTION_PREFIX_STRIP, - OPTION_INSN_WIDTH, - OPTION_ADJUST_VMA, - OPTION_DWARF_DEPTH, - OPTION_DWARF_START - }; - -static struct option long_options[]= -{ - {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA}, - {"all-headers", no_argument, NULL, 'x'}, - {"private-headers", no_argument, NULL, 'p'}, - {"private", required_argument, NULL, 'P'}, - {"architecture", required_argument, NULL, 'm'}, - {"archive-headers", no_argument, NULL, 'a'}, - {"debugging", no_argument, NULL, 'g'}, - {"debugging-tags", no_argument, NULL, 'e'}, - {"demangle", optional_argument, NULL, 'C'}, - {"disassemble", no_argument, NULL, 'd'}, - {"disassemble-all", no_argument, NULL, 'D'}, - {"disassembler-options", required_argument, NULL, 'M'}, - {"disassemble-zeroes", no_argument, NULL, 'z'}, - {"dynamic-reloc", no_argument, NULL, 'R'}, - {"dynamic-syms", no_argument, NULL, 'T'}, - {"endian", required_argument, NULL, OPTION_ENDIAN}, - {"file-headers", no_argument, NULL, 'f'}, - {"file-offsets", no_argument, NULL, 'F'}, - {"file-start-context", no_argument, &file_start_context, 1}, - {"full-contents", no_argument, NULL, 's'}, - {"headers", no_argument, NULL, 'h'}, - {"help", no_argument, NULL, 'H'}, - {"info", no_argument, NULL, 'i'}, - {"line-numbers", no_argument, NULL, 'l'}, - {"no-show-raw-insn", no_argument, &show_raw_insn, -1}, - {"prefix-addresses", no_argument, &prefix_addresses, 1}, - {"reloc", no_argument, NULL, 'r'}, - {"section", required_argument, NULL, 'j'}, - {"section-headers", no_argument, NULL, 'h'}, - {"show-raw-insn", no_argument, &show_raw_insn, 1}, - {"source", no_argument, NULL, 'S'}, - {"special-syms", no_argument, &dump_special_syms, 1}, - {"include", required_argument, NULL, 'I'}, - {"dwarf", optional_argument, NULL, OPTION_DWARF}, - {"stabs", no_argument, NULL, 'G'}, - {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, - {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, - {"syms", no_argument, NULL, 't'}, - {"target", required_argument, NULL, 'b'}, - {"version", no_argument, NULL, 'V'}, - {"wide", no_argument, NULL, 'w'}, - {"prefix", required_argument, NULL, OPTION_PREFIX}, - {"prefix-strip", required_argument, NULL, OPTION_PREFIX_STRIP}, - {"insn-width", required_argument, NULL, OPTION_INSN_WIDTH}, - {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH}, - {"dwarf-start", required_argument, 0, OPTION_DWARF_START}, - {0, no_argument, 0, 0} -}; - -static void -nonfatal (const char *msg) -{ - bfd_nonfatal (msg); - exit_status = 1; -} - -/* Returns TRUE if the specified section should be dumped. */ - -static bfd_boolean -process_section_p (asection * section) -{ - struct only * only; - - if (only_list == NULL) - return TRUE; - - for (only = only_list; only; only = only->next) - if (strcmp (only->name, section->name) == 0) - { - only->seen = TRUE; - return TRUE; - } - - return FALSE; -} - -/* Add an entry to the 'only' list. */ - -static void -add_only (char * name) -{ - struct only * only; - - /* First check to make sure that we do not - already have an entry for this name. */ - for (only = only_list; only; only = only->next) - if (strcmp (only->name, name) == 0) - return; - - only = xmalloc (sizeof * only); - only->name = name; - only->seen = FALSE; - only->next = only_list; - only_list = only; -} - -/* Release the memory used by the 'only' list. - PR 11225: Issue a warning message for unseen sections. - Only do this if none of the sections were seen. This is mainly to support - tools like the GAS testsuite where an object file is dumped with a list of - generic section names known to be present in a range of different file - formats. */ - -static void -free_only_list (void) -{ - bfd_boolean at_least_one_seen = FALSE; - struct only * only; - struct only * next; - - if (only_list == NULL) - return; - - for (only = only_list; only; only = only->next) - if (only->seen) - { - at_least_one_seen = TRUE; - break; - } - - for (only = only_list; only; only = next) - { - if (! at_least_one_seen) - { - non_fatal (_("section '%s' mentioned in a -j option, " - "but not found in any input file"), - only->name); - exit_status = 1; - } - next = only->next; - free (only); - } -} - - -static void -dump_section_header (bfd *abfd, asection *section, - void *ignored ATTRIBUTE_UNUSED) -{ - char *comma = ""; - unsigned int opb = bfd_octets_per_byte (abfd); - - /* Ignore linker created section. See elfNN_ia64_object_p in - bfd/elfxx-ia64.c. */ - if (section->flags & SEC_LINKER_CREATED) - return; - - /* PR 10413: Skip sections that we are ignoring. */ - if (! process_section_p (section)) - return; - - printf ("%3d %-13s %08lx ", section->index, - bfd_get_section_name (abfd, section), - (unsigned long) bfd_section_size (abfd, section) / opb); - bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section)); - printf (" "); - bfd_printf_vma (abfd, section->lma); - printf (" %08lx 2**%u", (unsigned long) section->filepos, - bfd_get_section_alignment (abfd, section)); - if (! wide_output) - printf ("\n "); - printf (" "); - -#define PF(x, y) \ - if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; } - - PF (SEC_HAS_CONTENTS, "CONTENTS"); - PF (SEC_ALLOC, "ALLOC"); - PF (SEC_CONSTRUCTOR, "CONSTRUCTOR"); - PF (SEC_LOAD, "LOAD"); - PF (SEC_RELOC, "RELOC"); - PF (SEC_READONLY, "READONLY"); - PF (SEC_CODE, "CODE"); - PF (SEC_DATA, "DATA"); - PF (SEC_ROM, "ROM"); - PF (SEC_DEBUGGING, "DEBUGGING"); - PF (SEC_NEVER_LOAD, "NEVER_LOAD"); - PF (SEC_EXCLUDE, "EXCLUDE"); - PF (SEC_SORT_ENTRIES, "SORT_ENTRIES"); - if (bfd_get_arch (abfd) == bfd_arch_tic54x) - { - PF (SEC_TIC54X_BLOCK, "BLOCK"); - PF (SEC_TIC54X_CLINK, "CLINK"); - } - PF (SEC_SMALL_DATA, "SMALL_DATA"); - if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) - PF (SEC_COFF_SHARED, "SHARED"); - PF (SEC_THREAD_LOCAL, "THREAD_LOCAL"); - PF (SEC_GROUP, "GROUP"); - - if ((section->flags & SEC_LINK_ONCE) != 0) - { - const char *ls; - struct coff_comdat_info *comdat; - - switch (section->flags & SEC_LINK_DUPLICATES) - { - default: - abort (); - case SEC_LINK_DUPLICATES_DISCARD: - ls = "LINK_ONCE_DISCARD"; - break; - case SEC_LINK_DUPLICATES_ONE_ONLY: - ls = "LINK_ONCE_ONE_ONLY"; - break; - case SEC_LINK_DUPLICATES_SAME_SIZE: - ls = "LINK_ONCE_SAME_SIZE"; - break; - case SEC_LINK_DUPLICATES_SAME_CONTENTS: - ls = "LINK_ONCE_SAME_CONTENTS"; - break; - } - printf ("%s%s", comma, ls); - - comdat = bfd_coff_get_comdat_section (abfd, section); - if (comdat != NULL) - printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol); - - comma = ", "; - } - - printf ("\n"); -#undef PF -} - -static void -dump_headers (bfd *abfd) -{ - printf (_("Sections:\n")); - -#ifndef BFD64 - printf (_("Idx Name Size VMA LMA File off Algn")); -#else - /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses. */ - if (bfd_get_arch_size (abfd) == 32) - printf (_("Idx Name Size VMA LMA File off Algn")); - else - printf (_("Idx Name Size VMA LMA File off Algn")); -#endif - - if (wide_output) - printf (_(" Flags")); - printf ("\n"); - - bfd_map_over_sections (abfd, dump_section_header, NULL); -} - -static asymbol ** -slurp_symtab (bfd *abfd) -{ - asymbol **sy = NULL; - long storage; - - if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) - { - symcount = 0; - return NULL; - } - - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - bfd_fatal (bfd_get_filename (abfd)); - if (storage) - sy = (asymbol **) xmalloc (storage); - - symcount = bfd_canonicalize_symtab (abfd, sy); - if (symcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - return sy; -} - -/* Read in the dynamic symbols. */ - -static asymbol ** -slurp_dynamic_symtab (bfd *abfd) -{ - asymbol **sy = NULL; - long storage; - - storage = bfd_get_dynamic_symtab_upper_bound (abfd); - if (storage < 0) - { - if (!(bfd_get_file_flags (abfd) & DYNAMIC)) - { - non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd)); - exit_status = 1; - dynsymcount = 0; - return NULL; - } - - bfd_fatal (bfd_get_filename (abfd)); - } - if (storage) - sy = (asymbol **) xmalloc (storage); - - dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy); - if (dynsymcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - return sy; -} - -/* Filter out (in place) symbols that are useless for disassembly. - COUNT is the number of elements in SYMBOLS. - Return the number of useful symbols. */ - -static long -remove_useless_symbols (asymbol **symbols, long count) -{ - asymbol **in_ptr = symbols, **out_ptr = symbols; - - while (--count >= 0) - { - asymbol *sym = *in_ptr++; - - if (sym->name == NULL || sym->name[0] == '\0') - continue; - if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) - continue; - if (bfd_is_und_section (sym->section) - || bfd_is_com_section (sym->section)) - continue; - - *out_ptr++ = sym; - } - return out_ptr - symbols; -} - -/* Sort symbols into value order. */ - -static int -compare_symbols (const void *ap, const void *bp) -{ - const asymbol *a = * (const asymbol **) ap; - const asymbol *b = * (const asymbol **) bp; - const char *an; - const char *bn; - size_t anl; - size_t bnl; - bfd_boolean af; - bfd_boolean bf; - flagword aflags; - flagword bflags; - - if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) - return 1; - else if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) - return -1; - - if (a->section > b->section) - return 1; - else if (a->section < b->section) - return -1; - - an = bfd_asymbol_name (a); - bn = bfd_asymbol_name (b); - anl = strlen (an); - bnl = strlen (bn); - - /* The symbols gnu_compiled and gcc2_compiled convey no real - information, so put them after other symbols with the same value. */ - af = (strstr (an, "gnu_compiled") != NULL - || strstr (an, "gcc2_compiled") != NULL); - bf = (strstr (bn, "gnu_compiled") != NULL - || strstr (bn, "gcc2_compiled") != NULL); - - if (af && ! bf) - return 1; - if (! af && bf) - return -1; - - /* We use a heuristic for the file name, to try to sort it after - more useful symbols. It may not work on non Unix systems, but it - doesn't really matter; the only difference is precisely which - symbol names get printed. */ - -#define file_symbol(s, sn, snl) \ - (((s)->flags & BSF_FILE) != 0 \ - || ((sn)[(snl) - 2] == '.' \ - && ((sn)[(snl) - 1] == 'o' \ - || (sn)[(snl) - 1] == 'a'))) - - af = file_symbol (a, an, anl); - bf = file_symbol (b, bn, bnl); - - if (af && ! bf) - return 1; - if (! af && bf) - return -1; - - /* Try to sort global symbols before local symbols before function - symbols before debugging symbols. */ - - aflags = a->flags; - bflags = b->flags; - - if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING)) - { - if ((aflags & BSF_DEBUGGING) != 0) - return 1; - else - return -1; - } - if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION)) - { - if ((aflags & BSF_FUNCTION) != 0) - return -1; - else - return 1; - } - if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL)) - { - if ((aflags & BSF_LOCAL) != 0) - return 1; - else - return -1; - } - if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL)) - { - if ((aflags & BSF_GLOBAL) != 0) - return -1; - else - return 1; - } - - /* Symbols that start with '.' might be section names, so sort them - after symbols that don't start with '.'. */ - if (an[0] == '.' && bn[0] != '.') - return 1; - if (an[0] != '.' && bn[0] == '.') - return -1; - - /* Finally, if we can't distinguish them in any other way, try to - get consistent results by sorting the symbols by name. */ - return strcmp (an, bn); -} - -/* Sort relocs into address order. */ - -static int -compare_relocs (const void *ap, const void *bp) -{ - const arelent *a = * (const arelent **) ap; - const arelent *b = * (const arelent **) bp; - - if (a->address > b->address) - return 1; - else if (a->address < b->address) - return -1; - - /* So that associated relocations tied to the same address show up - in the correct order, we don't do any further sorting. */ - if (a > b) - return 1; - else if (a < b) - return -1; - else - return 0; -} - -/* Print an address (VMA) to the output stream in INFO. - If SKIP_ZEROES is TRUE, omit leading zeroes. */ - -static void -objdump_print_value (bfd_vma vma, struct disassemble_info *inf, - bfd_boolean skip_zeroes) -{ - char buf[30]; - char *p; - struct objdump_disasm_info *aux; - - aux = (struct objdump_disasm_info *) inf->application_data; - bfd_sprintf_vma (aux->abfd, buf, vma); - if (! skip_zeroes) - p = buf; - else - { - for (p = buf; *p == '0'; ++p) - ; - if (*p == '\0') - --p; - } - (*inf->fprintf_func) (inf->stream, "%s", p); -} - -/* Print the name of a symbol. */ - -static void -objdump_print_symname (bfd *abfd, struct disassemble_info *inf, - asymbol *sym) -{ - char *alloc; - const char *name; - - alloc = NULL; - name = bfd_asymbol_name (sym); - if (do_demangle && name[0] != '\0') - { - /* Demangle the name. */ - alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS); - if (alloc != NULL) - name = alloc; - } - - if (inf != NULL) - (*inf->fprintf_func) (inf->stream, "%s", name); - else - printf ("%s", name); - - if (alloc != NULL) - free (alloc); -} - -/* Locate a symbol given a bfd and a section (from INFO->application_data), - and a VMA. If INFO->application_data->require_sec is TRUE, then always - require the symbol to be in the section. Returns NULL if there is no - suitable symbol. If PLACE is not NULL, then *PLACE is set to the index - of the symbol in sorted_syms. */ - -static asymbol * -find_symbol_for_address (bfd_vma vma, - struct disassemble_info *inf, - long *place) -{ - /* @@ Would it speed things up to cache the last two symbols returned, - and maybe their address ranges? For many processors, only one memory - operand can be present at a time, so the 2-entry cache wouldn't be - constantly churned by code doing heavy memory accesses. */ - - /* Indices in `sorted_syms'. */ - long min = 0; - long max_count = sorted_symcount; - long thisplace; - struct objdump_disasm_info *aux; - bfd *abfd; - asection *sec; - unsigned int opb; - bfd_boolean want_section; - - if (sorted_symcount < 1) - return NULL; - - aux = (struct objdump_disasm_info *) inf->application_data; - abfd = aux->abfd; - sec = aux->sec; - opb = inf->octets_per_byte; - - /* Perform a binary search looking for the closest symbol to the - required value. We are searching the range (min, max_count]. */ - while (min + 1 < max_count) - { - asymbol *sym; - - thisplace = (max_count + min) / 2; - sym = sorted_syms[thisplace]; - - if (bfd_asymbol_value (sym) > vma) - max_count = thisplace; - else if (bfd_asymbol_value (sym) < vma) - min = thisplace; - else - { - min = thisplace; - break; - } - } - - /* The symbol we want is now in min, the low end of the range we - were searching. If there are several symbols with the same - value, we want the first one. */ - thisplace = min; - while (thisplace > 0 - && (bfd_asymbol_value (sorted_syms[thisplace]) - == bfd_asymbol_value (sorted_syms[thisplace - 1]))) - --thisplace; - - /* Prefer a symbol in the current section if we have multple symbols - with the same value, as can occur with overlays or zero size - sections. */ - min = thisplace; - while (min < max_count - && (bfd_asymbol_value (sorted_syms[min]) - == bfd_asymbol_value (sorted_syms[thisplace]))) - { - if (sorted_syms[min]->section == sec - && inf->symbol_is_valid (sorted_syms[min], inf)) - { - thisplace = min; - - if (place != NULL) - *place = thisplace; - - return sorted_syms[thisplace]; - } - ++min; - } - - /* If the file is relocatable, and the symbol could be from this - section, prefer a symbol from this section over symbols from - others, even if the other symbol's value might be closer. - - Note that this may be wrong for some symbol references if the - sections have overlapping memory ranges, but in that case there's - no way to tell what's desired without looking at the relocation - table. - - Also give the target a chance to reject symbols. */ - want_section = (aux->require_sec - || ((abfd->flags & HAS_RELOC) != 0 - && vma >= bfd_get_section_vma (abfd, sec) - && vma < (bfd_get_section_vma (abfd, sec) - + bfd_section_size (abfd, sec) / opb))); - if ((sorted_syms[thisplace]->section != sec && want_section) - || ! inf->symbol_is_valid (sorted_syms[thisplace], inf)) - { - long i; - long newplace = sorted_symcount; - - for (i = min - 1; i >= 0; i--) - { - if ((sorted_syms[i]->section == sec || !want_section) - && inf->symbol_is_valid (sorted_syms[i], inf)) - { - if (newplace == sorted_symcount) - newplace = i; - - if (bfd_asymbol_value (sorted_syms[i]) - != bfd_asymbol_value (sorted_syms[newplace])) - break; - - /* Remember this symbol and keep searching until we reach - an earlier address. */ - newplace = i; - } - } - - if (newplace != sorted_symcount) - thisplace = newplace; - else - { - /* We didn't find a good symbol with a smaller value. - Look for one with a larger value. */ - for (i = thisplace + 1; i < sorted_symcount; i++) - { - if ((sorted_syms[i]->section == sec || !want_section) - && inf->symbol_is_valid (sorted_syms[i], inf)) - { - thisplace = i; - break; - } - } - } - - if ((sorted_syms[thisplace]->section != sec && want_section) - || ! inf->symbol_is_valid (sorted_syms[thisplace], inf)) - /* There is no suitable symbol. */ - return NULL; - } - - if (place != NULL) - *place = thisplace; - - return sorted_syms[thisplace]; -} - -/* Print an address and the offset to the nearest symbol. */ - -static void -objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym, - bfd_vma vma, struct disassemble_info *inf, - bfd_boolean skip_zeroes) -{ - objdump_print_value (vma, inf, skip_zeroes); - - if (sym == NULL) - { - bfd_vma secaddr; - - (*inf->fprintf_func) (inf->stream, " <%s", - bfd_get_section_name (abfd, sec)); - secaddr = bfd_get_section_vma (abfd, sec); - if (vma < secaddr) - { - (*inf->fprintf_func) (inf->stream, "-0x"); - objdump_print_value (secaddr - vma, inf, TRUE); - } - else if (vma > secaddr) - { - (*inf->fprintf_func) (inf->stream, "+0x"); - objdump_print_value (vma - secaddr, inf, TRUE); - } - (*inf->fprintf_func) (inf->stream, ">"); - } - else - { - (*inf->fprintf_func) (inf->stream, " <"); - objdump_print_symname (abfd, inf, sym); - if (bfd_asymbol_value (sym) > vma) - { - (*inf->fprintf_func) (inf->stream, "-0x"); - objdump_print_value (bfd_asymbol_value (sym) - vma, inf, TRUE); - } - else if (vma > bfd_asymbol_value (sym)) - { - (*inf->fprintf_func) (inf->stream, "+0x"); - objdump_print_value (vma - bfd_asymbol_value (sym), inf, TRUE); - } - (*inf->fprintf_func) (inf->stream, ">"); - } - - if (display_file_offsets) - inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"), - (long int)(sec->filepos + (vma - sec->vma))); -} - -/* Print an address (VMA), symbolically if possible. - If SKIP_ZEROES is TRUE, don't output leading zeroes. */ - -static void -objdump_print_addr (bfd_vma vma, - struct disassemble_info *inf, - bfd_boolean skip_zeroes) -{ - struct objdump_disasm_info *aux; - asymbol *sym = NULL; - bfd_boolean skip_find = FALSE; - - aux = (struct objdump_disasm_info *) inf->application_data; - - if (sorted_symcount < 1) - { - (*inf->fprintf_func) (inf->stream, "0x"); - objdump_print_value (vma, inf, skip_zeroes); - - if (display_file_offsets) - inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"), - (long int)(aux->sec->filepos + (vma - aux->sec->vma))); - return; - } - - if (aux->reloc != NULL - && aux->reloc->sym_ptr_ptr != NULL - && * aux->reloc->sym_ptr_ptr != NULL) - { - sym = * aux->reloc->sym_ptr_ptr; - - /* Adjust the vma to the reloc. */ - vma += bfd_asymbol_value (sym); - - if (bfd_is_und_section (bfd_get_section (sym))) - skip_find = TRUE; - } - - if (!skip_find) - sym = find_symbol_for_address (vma, inf, NULL); - - objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, inf, - skip_zeroes); -} - -/* Print VMA to INFO. This function is passed to the disassembler - routine. */ - -static void -objdump_print_address (bfd_vma vma, struct disassemble_info *inf) -{ - objdump_print_addr (vma, inf, ! prefix_addresses); -} - -/* Determine if the given address has a symbol associated with it. */ - -static int -objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * inf) -{ - asymbol * sym; - - sym = find_symbol_for_address (vma, inf, NULL); - - return (sym != NULL && (bfd_asymbol_value (sym) == vma)); -} - -/* Hold the last function name and the last line number we displayed - in a disassembly. */ - -static char *prev_functionname; -static unsigned int prev_line; - -/* We keep a list of all files that we have seen when doing a - disassembly with source, so that we know how much of the file to - display. This can be important for inlined functions. */ - -struct print_file_list -{ - struct print_file_list *next; - const char *filename; - const char *modname; - const char *map; - size_t mapsize; - const char **linemap; - unsigned maxline; - unsigned last_line; - int first; -}; - -static struct print_file_list *print_files; - -/* The number of preceding context lines to show when we start - displaying a file for the first time. */ - -#define SHOW_PRECEDING_CONTEXT_LINES (5) - -/* Read a complete file into memory. */ - -static const char * -slurp_file (const char *fn, size_t *size) -{ -#ifdef HAVE_MMAP - int ps = getpagesize (); - size_t msize; -#endif - const char *map; - struct stat st; - int fd = open (fn, O_RDONLY | O_BINARY); - - if (fd < 0) - return NULL; - if (fstat (fd, &st) < 0) - return NULL; - *size = st.st_size; -#ifdef HAVE_MMAP - msize = (*size + ps - 1) & ~(ps - 1); - map = mmap (NULL, msize, PROT_READ, MAP_SHARED, fd, 0); - if (map != (char *)-1L) - { - close(fd); - return map; - } -#endif - map = (const char *) malloc (*size); - if (!map || (size_t) read (fd, (char *)map, *size) != *size) - { - free ((void *)map); - map = NULL; - } - close (fd); - return map; -} - -#define line_map_decrease 5 - -/* Precompute array of lines for a mapped file. */ - -static const char ** -index_file (const char *map, size_t size, unsigned int *maxline) -{ - const char *p, *lstart, *end; - int chars_per_line = 45; /* First iteration will use 40. */ - unsigned int lineno; - const char **linemap = NULL; - unsigned long line_map_size = 0; - - lineno = 0; - lstart = map; - end = map + size; - - for (p = map; p < end; p++) - { - if (*p == '\n') - { - if (p + 1 < end && p[1] == '\r') - p++; - } - else if (*p == '\r') - { - if (p + 1 < end && p[1] == '\n') - p++; - } - else - continue; - - /* End of line found. */ - - if (linemap == NULL || line_map_size < lineno + 1) - { - unsigned long newsize; - - chars_per_line -= line_map_decrease; - if (chars_per_line <= 1) - chars_per_line = 1; - line_map_size = size / chars_per_line + 1; - if (line_map_size < lineno + 1) - line_map_size = lineno + 1; - newsize = line_map_size * sizeof (char *); - linemap = (const char **) xrealloc (linemap, newsize); - } - - linemap[lineno++] = lstart; - lstart = p + 1; - } - - *maxline = lineno; - return linemap; -} - -/* Tries to open MODNAME, and if successful adds a node to print_files - linked list and returns that node. Returns NULL on failure. */ - -static struct print_file_list * -try_print_file_open (const char *origname, const char *modname) -{ - struct print_file_list *p; - - p = (struct print_file_list *) xmalloc (sizeof (struct print_file_list)); - - p->map = slurp_file (modname, &p->mapsize); - if (p->map == NULL) - { - free (p); - return NULL; - } - - p->linemap = index_file (p->map, p->mapsize, &p->maxline); - p->last_line = 0; - p->filename = origname; - p->modname = modname; - p->next = print_files; - p->first = 1; - print_files = p; - return p; -} - -/* If the the source file, as described in the symtab, is not found - try to locate it in one of the paths specified with -I - If found, add location to print_files linked list. */ - -static struct print_file_list * -update_source_path (const char *filename) -{ - struct print_file_list *p; - const char *fname; - int i; - - p = try_print_file_open (filename, filename); - if (p != NULL) - return p; - - if (include_path_count == 0) - return NULL; - - /* Get the name of the file. */ - fname = lbasename (filename); - - /* If file exists under a new path, we need to add it to the list - so that show_line knows about it. */ - for (i = 0; i < include_path_count; i++) - { - char *modname = concat (include_paths[i], "/", fname, (const char *) 0); - - p = try_print_file_open (filename, modname); - if (p) - return p; - - free (modname); - } - - return NULL; -} - -/* Print a source file line. */ - -static void -print_line (struct print_file_list *p, unsigned int linenum) -{ - const char *l; - size_t len; - - --linenum; - if (linenum >= p->maxline) - return; - l = p->linemap [linenum]; - /* Test fwrite return value to quiet glibc warning. */ - len = strcspn (l, "\n\r"); - if (len == 0 || fwrite (l, len, 1, stdout) == 1) - putchar ('\n'); -} - -/* Print a range of source code lines. */ - -static void -dump_lines (struct print_file_list *p, unsigned int start, unsigned int end) -{ - if (p->map == NULL) - return; - while (start <= end) - { - print_line (p, start); - start++; - } -} - -/* Show the line number, or the source line, in a disassembly - listing. */ - -static void -show_line (bfd *abfd, asection *section, bfd_vma addr_offset) -{ - const char *filename; - const char *functionname; - unsigned int linenumber; - bfd_boolean reloc; - - if (! with_line_numbers && ! with_source_code) - return; - - if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename, - &functionname, &linenumber)) - return; - - if (filename != NULL && *filename == '\0') - filename = NULL; - if (functionname != NULL && *functionname == '\0') - functionname = NULL; - - if (filename - && IS_ABSOLUTE_PATH (filename) - && prefix) - { - char *path_up; - const char *fname = filename; - char *path = (char *) alloca (prefix_length + PATH_MAX + 1); - - if (prefix_length) - memcpy (path, prefix, prefix_length); - path_up = path + prefix_length; - - /* Build relocated filename, stripping off leading directories - from the initial filename if requested. */ - if (prefix_strip > 0) - { - int level = 0; - const char *s; - - /* Skip selected directory levels. */ - for (s = fname + 1; *s != '\0' && level < prefix_strip; s++) - if (IS_DIR_SEPARATOR(*s)) - { - fname = s; - level++; - } - } - - /* Update complete filename. */ - strncpy (path_up, fname, PATH_MAX); - path_up[PATH_MAX] = '\0'; - - filename = path; - reloc = TRUE; - } - else - reloc = FALSE; - - if (with_line_numbers) - { - if (functionname != NULL - && (prev_functionname == NULL - || strcmp (functionname, prev_functionname) != 0)) - printf ("%s():\n", functionname); - if (linenumber > 0 && linenumber != prev_line) - printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); - } - - if (with_source_code - && filename != NULL - && linenumber > 0) - { - struct print_file_list **pp, *p; - unsigned l; - - for (pp = &print_files; *pp != NULL; pp = &(*pp)->next) - if (filename_cmp ((*pp)->filename, filename) == 0) - break; - p = *pp; - - if (p == NULL) - { - if (reloc) - filename = xstrdup (filename); - p = update_source_path (filename); - } - - if (p != NULL && linenumber != p->last_line) - { - if (file_start_context && p->first) - l = 1; - else - { - l = linenumber - SHOW_PRECEDING_CONTEXT_LINES; - if (l >= linenumber) - l = 1; - if (p->last_line >= l && p->last_line <= linenumber) - l = p->last_line + 1; - } - dump_lines (p, l, linenumber); - p->last_line = linenumber; - p->first = 0; - } - } - - if (functionname != NULL - && (prev_functionname == NULL - || strcmp (functionname, prev_functionname) != 0)) - { - if (prev_functionname != NULL) - free (prev_functionname); - prev_functionname = (char *) xmalloc (strlen (functionname) + 1); - strcpy (prev_functionname, functionname); - } - - if (linenumber > 0 && linenumber != prev_line) - prev_line = linenumber; -} - -/* Pseudo FILE object for strings. */ -typedef struct -{ - char *buffer; - size_t pos; - size_t alloc; -} SFILE; - -/* sprintf to a "stream". */ - -static int ATTRIBUTE_PRINTF_2 -objdump_sprintf (SFILE *f, const char *format, ...) -{ - size_t n; - va_list args; - - while (1) - { - size_t space = f->alloc - f->pos; - - va_start (args, format); - n = vsnprintf (f->buffer + f->pos, space, format, args); - va_end (args); - - if (space > n) - break; - - f->alloc = (f->alloc + n) * 2; - f->buffer = (char *) xrealloc (f->buffer, f->alloc); - } - f->pos += n; - - return n; -} - -/* The number of zeroes we want to see before we start skipping them. - The number is arbitrarily chosen. */ - -#define DEFAULT_SKIP_ZEROES 8 - -/* The number of zeroes to skip at the end of a section. If the - number of zeroes at the end is between SKIP_ZEROES_AT_END and - SKIP_ZEROES, they will be disassembled. If there are fewer than - SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic - attempt to avoid disassembling zeroes inserted by section - alignment. */ - -#define DEFAULT_SKIP_ZEROES_AT_END 3 - -/* Disassemble some data in memory between given values. */ - -static void -disassemble_bytes (struct disassemble_info * inf, - disassembler_ftype disassemble_fn, - bfd_boolean insns, - bfd_byte * data, - bfd_vma start_offset, - bfd_vma stop_offset, - bfd_vma rel_offset, - arelent *** relppp, - arelent ** relppend) -{ - struct objdump_disasm_info *aux; - asection *section; - int octets_per_line; - int skip_addr_chars; - bfd_vma addr_offset; - unsigned int opb = inf->octets_per_byte; - unsigned int skip_zeroes = inf->skip_zeroes; - unsigned int skip_zeroes_at_end = inf->skip_zeroes_at_end; - int octets = opb; - SFILE sfile; - - aux = (struct objdump_disasm_info *) inf->application_data; - section = aux->sec; - - sfile.alloc = 120; - sfile.buffer = (char *) xmalloc (sfile.alloc); - sfile.pos = 0; - - if (insn_width) - octets_per_line = insn_width; - else if (insns) - octets_per_line = 4; - else - octets_per_line = 16; - - /* Figure out how many characters to skip at the start of an - address, to make the disassembly look nicer. We discard leading - zeroes in chunks of 4, ensuring that there is always a leading - zero remaining. */ - skip_addr_chars = 0; - if (! prefix_addresses) - { - char buf[30]; - - bfd_sprintf_vma (aux->abfd, buf, section->vma + section->size / opb); - - while (buf[skip_addr_chars] == '0') - ++skip_addr_chars; - - /* Don't discard zeros on overflow. */ - if (buf[skip_addr_chars] == '\0' && section->vma != 0) - skip_addr_chars = 0; - - if (skip_addr_chars != 0) - skip_addr_chars = (skip_addr_chars - 1) & -4; - } - - inf->insn_info_valid = 0; - - addr_offset = start_offset; - while (addr_offset < stop_offset) - { - bfd_vma z; - bfd_boolean need_nl = FALSE; - int previous_octets; - - /* Remember the length of the previous instruction. */ - previous_octets = octets; - octets = 0; - - /* Make sure we don't use relocs from previous instructions. */ - aux->reloc = NULL; - - /* If we see more than SKIP_ZEROES octets of zeroes, we just - print `...'. */ - for (z = addr_offset * opb; z < stop_offset * opb; z++) - if (data[z] != 0) - break; - if (! disassemble_zeroes - && (inf->insn_info_valid == 0 - || inf->branch_delay_insns == 0) - && (z - addr_offset * opb >= skip_zeroes - || (z == stop_offset * opb && - z - addr_offset * opb < skip_zeroes_at_end))) - { - /* If there are more nonzero octets to follow, we only skip - zeroes in multiples of 4, to try to avoid running over - the start of an instruction which happens to start with - zero. */ - if (z != stop_offset * opb) - z = addr_offset * opb + ((z - addr_offset * opb) &~ 3); - - octets = z - addr_offset * opb; - - /* If we are going to display more data, and we are displaying - file offsets, then tell the user how many zeroes we skip - and the file offset from where we resume dumping. */ - if (display_file_offsets && ((addr_offset + (octets / opb)) < stop_offset)) - printf ("\t... (skipping %d zeroes, resuming at file offset: 0x%lx)\n", - octets / opb, - (unsigned long) (section->filepos - + (addr_offset + (octets / opb)))); - else - printf ("\t...\n"); - } - else - { - char buf[50]; - int bpc = 0; - int pb = 0; - - if (with_line_numbers || with_source_code) - show_line (aux->abfd, section, addr_offset); - - if (! prefix_addresses) - { - char *s; - - bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset); - for (s = buf + skip_addr_chars; *s == '0'; s++) - *s = ' '; - if (*s == '\0') - *--s = '0'; - printf ("%s:\t", buf + skip_addr_chars); - } - else - { - aux->require_sec = TRUE; - objdump_print_address (section->vma + addr_offset, inf); - aux->require_sec = FALSE; - putchar (' '); - } - - if (insns) - { - sfile.pos = 0; - inf->fprintf_func = (fprintf_ftype) objdump_sprintf; - inf->stream = &sfile; - inf->bytes_per_line = 0; - inf->bytes_per_chunk = 0; - inf->flags = disassemble_all ? DISASSEMBLE_DATA : 0; - if (machine) - inf->flags |= USER_SPECIFIED_MACHINE_TYPE; - - if (inf->disassembler_needs_relocs - && (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0 - && (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0 - && *relppp < relppend) - { - bfd_signed_vma distance_to_rel; - - distance_to_rel = (**relppp)->address - - (rel_offset + addr_offset); - - /* Check to see if the current reloc is associated with - the instruction that we are about to disassemble. */ - if (distance_to_rel == 0 - /* FIXME: This is wrong. We are trying to catch - relocs that are addressed part way through the - current instruction, as might happen with a packed - VLIW instruction. Unfortunately we do not know the - length of the current instruction since we have not - disassembled it yet. Instead we take a guess based - upon the length of the previous instruction. The - proper solution is to have a new target-specific - disassembler function which just returns the length - of an instruction at a given address without trying - to display its disassembly. */ - || (distance_to_rel > 0 - && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb))) - { - inf->flags |= INSN_HAS_RELOC; - aux->reloc = **relppp; - } - } - - octets = (*disassemble_fn) (section->vma + addr_offset, inf); - inf->fprintf_func = (fprintf_ftype) fprintf; - inf->stream = stdout; - if (insn_width == 0 && inf->bytes_per_line != 0) - octets_per_line = inf->bytes_per_line; - if (octets < (int) opb) - { - if (sfile.pos) - printf ("%s\n", sfile.buffer); - if (octets >= 0) - { - non_fatal (_("disassemble_fn returned length %d"), - octets); - exit_status = 1; - } - break; - } - } - else - { - bfd_vma j; - - octets = octets_per_line; - if (addr_offset + octets / opb > stop_offset) - octets = (stop_offset - addr_offset) * opb; - - for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j) - { - if (ISPRINT (data[j])) - buf[j - addr_offset * opb] = data[j]; - else - buf[j - addr_offset * opb] = '.'; - } - buf[j - addr_offset * opb] = '\0'; - } - - if (prefix_addresses - ? show_raw_insn > 0 - : show_raw_insn >= 0) - { - bfd_vma j; - - /* If ! prefix_addresses and ! wide_output, we print - octets_per_line octets per line. */ - pb = octets; - if (pb > octets_per_line && ! prefix_addresses && ! wide_output) - pb = octets_per_line; - - if (inf->bytes_per_chunk) - bpc = inf->bytes_per_chunk; - else - bpc = 1; - - for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc) - { - int k; - - if (bpc > 1 && inf->display_endian == BFD_ENDIAN_LITTLE) - { - for (k = bpc - 1; k >= 0; k--) - printf ("%02x", (unsigned) data[j + k]); - putchar (' '); - } - else - { - for (k = 0; k < bpc; k++) - printf ("%02x", (unsigned) data[j + k]); - putchar (' '); - } - } - - for (; pb < octets_per_line; pb += bpc) - { - int k; - - for (k = 0; k < bpc; k++) - printf (" "); - putchar (' '); - } - - /* Separate raw data from instruction by extra space. */ - if (insns) - putchar ('\t'); - else - printf (" "); - } - - if (! insns) - printf ("%s", buf); - else if (sfile.pos) - printf ("%s", sfile.buffer); - - if (prefix_addresses - ? show_raw_insn > 0 - : show_raw_insn >= 0) - { - while (pb < octets) - { - bfd_vma j; - char *s; - - putchar ('\n'); - j = addr_offset * opb + pb; - - bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb); - for (s = buf + skip_addr_chars; *s == '0'; s++) - *s = ' '; - if (*s == '\0') - *--s = '0'; - printf ("%s:\t", buf + skip_addr_chars); - - pb += octets_per_line; - if (pb > octets) - pb = octets; - for (; j < addr_offset * opb + pb; j += bpc) - { - int k; - - if (bpc > 1 && inf->display_endian == BFD_ENDIAN_LITTLE) - { - for (k = bpc - 1; k >= 0; k--) - printf ("%02x", (unsigned) data[j + k]); - putchar (' '); - } - else - { - for (k = 0; k < bpc; k++) - printf ("%02x", (unsigned) data[j + k]); - putchar (' '); - } - } - } - } - - if (!wide_output) - putchar ('\n'); - else - need_nl = TRUE; - } - - while ((*relppp) < relppend - && (**relppp)->address < rel_offset + addr_offset + octets / opb) - { - if (dump_reloc_info || dump_dynamic_reloc_info) - { - arelent *q; - - q = **relppp; - - if (wide_output) - putchar ('\t'); - else - printf ("\t\t\t"); - - objdump_print_value (section->vma - rel_offset + q->address, - inf, TRUE); - - if (q->howto == NULL) - printf (": *unknown*\t"); - else if (q->howto->name) - printf (": %s\t", q->howto->name); - else - printf (": %d\t", q->howto->type); - - if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL) - printf ("*unknown*"); - else - { - const char *sym_name; - - sym_name = bfd_asymbol_name (*q->sym_ptr_ptr); - if (sym_name != NULL && *sym_name != '\0') - objdump_print_symname (aux->abfd, inf, *q->sym_ptr_ptr); - else - { - asection *sym_sec; - - sym_sec = bfd_get_section (*q->sym_ptr_ptr); - sym_name = bfd_get_section_name (aux->abfd, sym_sec); - if (sym_name == NULL || *sym_name == '\0') - sym_name = "*unknown*"; - printf ("%s", sym_name); - } - } - - if (q->addend) - { - printf ("+0x"); - objdump_print_value (q->addend, inf, TRUE); - } - - printf ("\n"); - need_nl = FALSE; - } - ++(*relppp); - } - - if (need_nl) - printf ("\n"); - - addr_offset += octets / opb; - } - - free (sfile.buffer); -} - -static void -disassemble_section (bfd *abfd, asection *section, void *inf) -{ - const struct elf_backend_data * bed; - bfd_vma sign_adjust = 0; - struct disassemble_info * pinfo = (struct disassemble_info *) inf; - struct objdump_disasm_info * paux; - unsigned int opb = pinfo->octets_per_byte; - bfd_byte * data = NULL; - bfd_size_type datasize = 0; - arelent ** rel_pp = NULL; - arelent ** rel_ppstart = NULL; - arelent ** rel_ppend; - unsigned long stop_offset; - asymbol * sym = NULL; - long place = 0; - long rel_count; - bfd_vma rel_offset; - unsigned long addr_offset; - - /* Sections that do not contain machine - code are not normally disassembled. */ - if (! disassemble_all - && only_list == NULL - && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS)) - != (SEC_CODE | SEC_HAS_CONTENTS))) - return; - - if (! process_section_p (section)) - return; - - datasize = bfd_get_section_size (section); - if (datasize == 0) - return; - - /* Decide which set of relocs to use. Load them if necessary. */ - paux = (struct objdump_disasm_info *) pinfo->application_data; - if (paux->dynrelbuf) - { - rel_pp = paux->dynrelbuf; - rel_count = paux->dynrelcount; - /* Dynamic reloc addresses are absolute, non-dynamic are section - relative. REL_OFFSET specifies the reloc address corresponding - to the start of this section. */ - rel_offset = section->vma; - } - else - { - rel_count = 0; - rel_pp = NULL; - rel_offset = 0; - - if ((section->flags & SEC_RELOC) != 0 - && (dump_reloc_info || pinfo->disassembler_needs_relocs)) - { - long relsize; - - relsize = bfd_get_reloc_upper_bound (abfd, section); - if (relsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - - if (relsize > 0) - { - rel_ppstart = rel_pp = (arelent **) xmalloc (relsize); - rel_count = bfd_canonicalize_reloc (abfd, section, rel_pp, syms); - if (rel_count < 0) - bfd_fatal (bfd_get_filename (abfd)); - - /* Sort the relocs by address. */ - qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs); - } - } - } - rel_ppend = rel_pp + rel_count; - - data = (bfd_byte *) xmalloc (datasize); - - bfd_get_section_contents (abfd, section, data, 0, datasize); - - paux->sec = section; - pinfo->buffer = data; - pinfo->buffer_vma = section->vma; - pinfo->buffer_length = datasize; - pinfo->section = section; - - if (start_address == (bfd_vma) -1 - || start_address < pinfo->buffer_vma) - addr_offset = 0; - else - addr_offset = start_address - pinfo->buffer_vma; - - if (stop_address == (bfd_vma) -1) - stop_offset = datasize / opb; - else - { - if (stop_address < pinfo->buffer_vma) - stop_offset = 0; - else - stop_offset = stop_address - pinfo->buffer_vma; - if (stop_offset > pinfo->buffer_length / opb) - stop_offset = pinfo->buffer_length / opb; - } - - /* Skip over the relocs belonging to addresses below the - start address. */ - while (rel_pp < rel_ppend - && (*rel_pp)->address < rel_offset + addr_offset) - ++rel_pp; - - if (addr_offset < stop_offset) - printf (_("\nDisassembly of section %s:\n"), section->name); - - /* Find the nearest symbol forwards from our current position. */ - paux->require_sec = TRUE; - sym = (asymbol *) find_symbol_for_address (section->vma + addr_offset, - (struct disassemble_info *) inf, - &place); - paux->require_sec = FALSE; - - /* PR 9774: If the target used signed addresses then we must make - sure that we sign extend the value that we calculate for 'addr' - in the loop below. */ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && (bed = get_elf_backend_data (abfd)) != NULL - && bed->sign_extend_vma) - sign_adjust = (bfd_vma) 1 << (bed->s->arch_size - 1); - - /* Disassemble a block of instructions up to the address associated with - the symbol we have just found. Then print the symbol and find the - next symbol on. Repeat until we have disassembled the entire section - or we have reached the end of the address range we are interested in. */ - while (addr_offset < stop_offset) - { - bfd_vma addr; - asymbol *nextsym; - unsigned long nextstop_offset; - bfd_boolean insns; - - addr = section->vma + addr_offset; - addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust; - - if (sym != NULL && bfd_asymbol_value (sym) <= addr) - { - int x; - - for (x = place; - (x < sorted_symcount - && (bfd_asymbol_value (sorted_syms[x]) <= addr)); - ++x) - continue; - - pinfo->symbols = sorted_syms + place; - pinfo->num_symbols = x - place; - pinfo->symtab_pos = place; - } - else - { - pinfo->symbols = NULL; - pinfo->num_symbols = 0; - pinfo->symtab_pos = -1; - } - - if (! prefix_addresses) - { - pinfo->fprintf_func (pinfo->stream, "\n"); - objdump_print_addr_with_sym (abfd, section, sym, addr, - pinfo, FALSE); - pinfo->fprintf_func (pinfo->stream, ":\n"); - } - - if (sym != NULL && bfd_asymbol_value (sym) > addr) - nextsym = sym; - else if (sym == NULL) - nextsym = NULL; - else - { -#define is_valid_next_sym(SYM) \ - ((SYM)->section == section \ - && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \ - && pinfo->symbol_is_valid (SYM, pinfo)) - - /* Search forward for the next appropriate symbol in - SECTION. Note that all the symbols are sorted - together into one big array, and that some sections - may have overlapping addresses. */ - while (place < sorted_symcount - && ! is_valid_next_sym (sorted_syms [place])) - ++place; - - if (place >= sorted_symcount) - nextsym = NULL; - else - nextsym = sorted_syms[place]; - } - - if (sym != NULL && bfd_asymbol_value (sym) > addr) - nextstop_offset = bfd_asymbol_value (sym) - section->vma; - else if (nextsym == NULL) - nextstop_offset = stop_offset; - else - nextstop_offset = bfd_asymbol_value (nextsym) - section->vma; - - if (nextstop_offset > stop_offset - || nextstop_offset <= addr_offset) - nextstop_offset = stop_offset; - - /* If a symbol is explicitly marked as being an object - rather than a function, just dump the bytes without - disassembling them. */ - if (disassemble_all - || sym == NULL - || sym->section != section - || bfd_asymbol_value (sym) > addr - || ((sym->flags & BSF_OBJECT) == 0 - && (strstr (bfd_asymbol_name (sym), "gnu_compiled") - == NULL) - && (strstr (bfd_asymbol_name (sym), "gcc2_compiled") - == NULL)) - || (sym->flags & BSF_FUNCTION) != 0) - insns = TRUE; - else - insns = FALSE; - - disassemble_bytes (pinfo, paux->disassemble_fn, insns, data, - addr_offset, nextstop_offset, - rel_offset, &rel_pp, rel_ppend); - - addr_offset = nextstop_offset; - sym = nextsym; - } - - free (data); - - if (rel_ppstart != NULL) - free (rel_ppstart); -} - -/* Disassemble the contents of an object file. */ - -static void -disassemble_data (bfd *abfd) -{ - struct disassemble_info disasm_info; - struct objdump_disasm_info aux; - long i; - - print_files = NULL; - prev_functionname = NULL; - prev_line = -1; - - /* We make a copy of syms to sort. We don't want to sort syms - because that will screw up the relocs. */ - sorted_symcount = symcount ? symcount : dynsymcount; - sorted_syms = (asymbol **) xmalloc ((sorted_symcount + synthcount) - * sizeof (asymbol *)); - memcpy (sorted_syms, symcount ? syms : dynsyms, - sorted_symcount * sizeof (asymbol *)); - - sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount); - - for (i = 0; i < synthcount; ++i) - { - sorted_syms[sorted_symcount] = synthsyms + i; - ++sorted_symcount; - } - - /* Sort the symbols into section and symbol order. */ - qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); - - init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf); - - disasm_info.application_data = (void *) &aux; - aux.abfd = abfd; - aux.require_sec = FALSE; - aux.dynrelbuf = NULL; - aux.dynrelcount = 0; - aux.reloc = NULL; - - disasm_info.print_address_func = objdump_print_address; - disasm_info.symbol_at_address_func = objdump_symbol_at_address; - - if (machine != NULL) - { - const bfd_arch_info_type *inf = bfd_scan_arch (machine); - - if (inf == NULL) - fatal (_("can't use supplied machine %s"), machine); - - abfd->arch_info = inf; - } - - if (endian != BFD_ENDIAN_UNKNOWN) - { - struct bfd_target *xvec; - - xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target)); - memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); - xvec->byteorder = endian; - abfd->xvec = xvec; - } - - /* Use libopcodes to locate a suitable disassembler. */ - aux.disassemble_fn = disassembler (abfd); - if (!aux.disassemble_fn) - { - non_fatal (_("can't disassemble for architecture %s\n"), - bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); - exit_status = 1; - return; - } - - disasm_info.flavour = bfd_get_flavour (abfd); - disasm_info.arch = bfd_get_arch (abfd); - disasm_info.mach = bfd_get_mach (abfd); - disasm_info.disassembler_options = disassembler_options; - disasm_info.octets_per_byte = bfd_octets_per_byte (abfd); - disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; - disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; - disasm_info.disassembler_needs_relocs = FALSE; - - if (bfd_big_endian (abfd)) - disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; - else if (bfd_little_endian (abfd)) - disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; - else - /* ??? Aborting here seems too drastic. We could default to big or little - instead. */ - disasm_info.endian = BFD_ENDIAN_UNKNOWN; - - /* Allow the target to customize the info structure. */ - disassemble_init_for_target (& disasm_info); - - /* Pre-load the dynamic relocs if we are going - to be dumping them along with the disassembly. */ - if (dump_dynamic_reloc_info) - { - long relsize = bfd_get_dynamic_reloc_upper_bound (abfd); - - if (relsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - - if (relsize > 0) - { - aux.dynrelbuf = (arelent **) xmalloc (relsize); - aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, - aux.dynrelbuf, - dynsyms); - if (aux.dynrelcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - - /* Sort the relocs by address. */ - qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *), - compare_relocs); - } - } - disasm_info.symtab = sorted_syms; - disasm_info.symtab_size = sorted_symcount; - - bfd_map_over_sections (abfd, disassemble_section, & disasm_info); - - if (aux.dynrelbuf != NULL) - free (aux.dynrelbuf); - free (sorted_syms); -} - -static int -load_specific_debug_section (enum dwarf_section_display_enum debug, - asection *sec, void *file) -{ - struct dwarf_section *section = &debug_displays [debug].section; - bfd *abfd = (bfd *) file; - bfd_boolean ret; - - /* If it is already loaded, do nothing. */ - if (section->start != NULL) - return 1; - - section->address = 0; - section->size = bfd_get_section_size (sec); - section->start = NULL; - ret = bfd_get_full_section_contents (abfd, sec, §ion->start); - - if (! ret) - { - free_debug_section (debug); - printf (_("\nCan't get contents for section '%s'.\n"), - section->name); - return 0; - } - - if (is_relocatable && debug_displays [debug].relocate) - { - /* We want to relocate the data we've already read (and - decompressed), so we store a pointer to the data in - the bfd_section, and tell it that the contents are - already in memory. */ - sec->contents = section->start; - sec->flags |= SEC_IN_MEMORY; - sec->size = section->size; - - ret = bfd_simple_get_relocated_section_contents (abfd, - sec, - section->start, - syms) != NULL; - - if (! ret) - { - free_debug_section (debug); - printf (_("\nCan't get contents for section '%s'.\n"), - section->name); - return 0; - } - } - - return 1; -} - -int -load_debug_section (enum dwarf_section_display_enum debug, void *file) -{ - struct dwarf_section *section = &debug_displays [debug].section; - bfd *abfd = (bfd *) file; - asection *sec; - - /* If it is already loaded, do nothing. */ - if (section->start != NULL) - return 1; - - /* Locate the debug section. */ - sec = bfd_get_section_by_name (abfd, section->uncompressed_name); - if (sec != NULL) - section->name = section->uncompressed_name; - else - { - sec = bfd_get_section_by_name (abfd, section->compressed_name); - if (sec != NULL) - section->name = section->compressed_name; - } - if (sec == NULL) - return 0; - - return load_specific_debug_section (debug, sec, file); -} - -void -free_debug_section (enum dwarf_section_display_enum debug) -{ - struct dwarf_section *section = &debug_displays [debug].section; - - if (section->start == NULL) - return; - - free ((char *) section->start); - section->start = NULL; - section->address = 0; - section->size = 0; -} - -static void -dump_dwarf_section (bfd *abfd, asection *section, - void *arg ATTRIBUTE_UNUSED) -{ - const char *name = bfd_get_section_name (abfd, section); - const char *match; - int i; - - if (CONST_STRNEQ (name, ".gnu.linkonce.wi.")) - match = ".debug_info"; - else - match = name; - - for (i = 0; i < max; i++) - if ((strcmp (debug_displays [i].section.uncompressed_name, match) == 0 - || strcmp (debug_displays [i].section.compressed_name, match) == 0) - && debug_displays [i].enabled != NULL - && *debug_displays [i].enabled) - { - struct dwarf_section *sec = &debug_displays [i].section; - - if (strcmp (sec->uncompressed_name, match) == 0) - sec->name = sec->uncompressed_name; - else - sec->name = sec->compressed_name; - if (load_specific_debug_section ((enum dwarf_section_display_enum) i, - section, abfd)) - { - debug_displays [i].display (sec, abfd); - - if (i != info && i != abbrev) - free_debug_section ((enum dwarf_section_display_enum) i); - } - break; - } -} - -/* Dump the dwarf debugging information. */ - -static void -dump_dwarf (bfd *abfd) -{ - is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; - - eh_addr_size = bfd_arch_bits_per_address (abfd) / 8; - - if (bfd_big_endian (abfd)) - byte_get = byte_get_big_endian; - else if (bfd_little_endian (abfd)) - byte_get = byte_get_little_endian; - else - abort (); - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_i386: - switch (bfd_get_mach (abfd)) - { - case bfd_mach_x86_64: - case bfd_mach_x86_64_intel_syntax: - init_dwarf_regnames_x86_64 (); - break; - - default: - init_dwarf_regnames_i386 (); - break; - } - break; - - default: - break; - } - - bfd_map_over_sections (abfd, dump_dwarf_section, NULL); - - free_debug_memory (); -} - -/* Read ABFD's stabs section STABSECT_NAME, and return a pointer to - it. Return NULL on failure. */ - -static char * -read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr) -{ - asection *stabsect; - bfd_size_type size; - char *contents; - - stabsect = bfd_get_section_by_name (abfd, sect_name); - if (stabsect == NULL) - { - printf (_("No %s section present\n\n"), sect_name); - return FALSE; - } - - size = bfd_section_size (abfd, stabsect); - contents = (char *) xmalloc (size); - - if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size)) - { - non_fatal (_("reading %s section of %s failed: %s"), - sect_name, bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); - exit_status = 1; - free (contents); - return NULL; - } - - *size_ptr = size; - - return contents; -} - -/* Stabs entries use a 12 byte format: - 4 byte string table index - 1 byte stab type - 1 byte stab other field - 2 byte stab desc field - 4 byte stab value - FIXME: This will have to change for a 64 bit object format. */ - -#define STRDXOFF (0) -#define TYPEOFF (4) -#define OTHEROFF (5) -#define DESCOFF (6) -#define VALOFF (8) -#define STABSIZE (12) - -/* Print ABFD's stabs section STABSECT_NAME (in `stabs'), - using string table section STRSECT_NAME (in `strtab'). */ - -static void -print_section_stabs (bfd *abfd, - const char *stabsect_name, - unsigned *string_offset_ptr) -{ - int i; - unsigned file_string_table_offset = 0; - unsigned next_file_string_table_offset = *string_offset_ptr; - bfd_byte *stabp, *stabs_end; - - stabp = stabs; - stabs_end = stabp + stab_size; - - printf (_("Contents of %s section:\n\n"), stabsect_name); - printf ("Symnum n_type n_othr n_desc n_value n_strx String\n"); - - /* Loop through all symbols and print them. - - We start the index at -1 because there is a dummy symbol on - the front of stabs-in-{coff,elf} sections that supplies sizes. */ - for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++) - { - const char *name; - unsigned long strx; - unsigned char type, other; - unsigned short desc; - bfd_vma value; - - strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); - type = bfd_h_get_8 (abfd, stabp + TYPEOFF); - other = bfd_h_get_8 (abfd, stabp + OTHEROFF); - desc = bfd_h_get_16 (abfd, stabp + DESCOFF); - value = bfd_h_get_32 (abfd, stabp + VALOFF); - - printf ("\n%-6d ", i); - /* Either print the stab name, or, if unnamed, print its number - again (makes consistent formatting for tools like awk). */ - name = bfd_get_stab_name (type); - if (name != NULL) - printf ("%-6s", name); - else if (type == N_UNDF) - printf ("HdrSym"); - else - printf ("%-6d", type); - printf (" %-6d %-6d ", other, desc); - bfd_printf_vma (abfd, value); - printf (" %-6lu", strx); - - /* Symbols with type == 0 (N_UNDF) specify the length of the - string table associated with this file. We use that info - to know how to relocate the *next* file's string table indices. */ - if (type == N_UNDF) - { - file_string_table_offset = next_file_string_table_offset; - next_file_string_table_offset += value; - } - else - { - /* Using the (possibly updated) string table offset, print the - string (if any) associated with this symbol. */ - if ((strx + file_string_table_offset) < stabstr_size) - printf (" %s", &strtab[strx + file_string_table_offset]); - else - printf (" *"); - } - } - printf ("\n\n"); - *string_offset_ptr = next_file_string_table_offset; -} - -typedef struct -{ - const char * section_name; - const char * string_section_name; - unsigned string_offset; -} -stab_section_names; - -static void -find_stabs_section (bfd *abfd, asection *section, void *names) -{ - int len; - stab_section_names * sought = (stab_section_names *) names; - - /* Check for section names for which stabsect_name is a prefix, to - handle .stab.N, etc. */ - len = strlen (sought->section_name); - - /* If the prefix matches, and the files section name ends with a - nul or a digit, then we match. I.e., we want either an exact - match or a section followed by a number. */ - if (strncmp (sought->section_name, section->name, len) == 0 - && (section->name[len] == 0 - || (section->name[len] == '.' && ISDIGIT (section->name[len + 1])))) - { - if (strtab == NULL) - strtab = read_section_stabs (abfd, sought->string_section_name, - &stabstr_size); - - if (strtab) - { - stabs = (bfd_byte *) read_section_stabs (abfd, section->name, - &stab_size); - if (stabs) - print_section_stabs (abfd, section->name, &sought->string_offset); - } - } -} - -static void -dump_stabs_section (bfd *abfd, char *stabsect_name, char *strsect_name) -{ - stab_section_names s; - - s.section_name = stabsect_name; - s.string_section_name = strsect_name; - s.string_offset = 0; - - bfd_map_over_sections (abfd, find_stabs_section, & s); - - free (strtab); - strtab = NULL; -} - -/* Dump the any sections containing stabs debugging information. */ - -static void -dump_stabs (bfd *abfd) -{ - dump_stabs_section (abfd, ".stab", ".stabstr"); - dump_stabs_section (abfd, ".stab.excl", ".stab.exclstr"); - dump_stabs_section (abfd, ".stab.index", ".stab.indexstr"); - - /* For Darwin. */ - dump_stabs_section (abfd, "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr"); - - dump_stabs_section (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$"); -} - -static void -dump_bfd_header (bfd *abfd) -{ - char *comma = ""; - - printf (_("architecture: %s, "), - bfd_printable_arch_mach (bfd_get_arch (abfd), - bfd_get_mach (abfd))); - printf (_("flags 0x%08x:\n"), abfd->flags & ~BFD_FLAGS_FOR_BFD_USE_MASK); - -#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";} - PF (HAS_RELOC, "HAS_RELOC"); - PF (EXEC_P, "EXEC_P"); - PF (HAS_LINENO, "HAS_LINENO"); - PF (HAS_DEBUG, "HAS_DEBUG"); - PF (HAS_SYMS, "HAS_SYMS"); - PF (HAS_LOCALS, "HAS_LOCALS"); - PF (DYNAMIC, "DYNAMIC"); - PF (WP_TEXT, "WP_TEXT"); - PF (D_PAGED, "D_PAGED"); - PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE"); - PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE"); - printf (_("\nstart address 0x")); - bfd_printf_vma (abfd, abfd->start_address); - printf ("\n"); -} - - -static void -dump_bfd_private_header (bfd *abfd) -{ - bfd_print_private_bfd_data (abfd, stdout); -} - -static void -dump_target_specific (bfd *abfd) -{ - const struct objdump_private_desc * const *desc; - struct objdump_private_option *opt; - char *e, *b; - - /* Find the desc. */ - for (desc = objdump_private_vectors; *desc != NULL; desc++) - if ((*desc)->filter (abfd)) - break; - - if (desc == NULL) - { - non_fatal (_("option -P/--private not supported by this file")); - return; - } - - /* Clear all options. */ - for (opt = (*desc)->options; opt->name; opt++) - opt->selected = FALSE; - - /* Decode options. */ - b = dump_private_options; - do - { - e = strchr (b, ','); - - if (e) - *e = 0; - - for (opt = (*desc)->options; opt->name; opt++) - if (strcmp (opt->name, b) == 0) - { - opt->selected = TRUE; - break; - } - if (opt->name == NULL) - non_fatal (_("target specific dump '%s' not supported"), b); - - if (e) - { - *e = ','; - b = e + 1; - } - } - while (e != NULL); - - /* Dump. */ - (*desc)->dump (abfd); -} - -/* Display a section in hexadecimal format with associated characters. - Each line prefixed by the zero padded address. */ - -static void -dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) -{ - bfd_byte *data = 0; - bfd_size_type datasize; - bfd_size_type addr_offset; - bfd_size_type start_offset; - bfd_size_type stop_offset; - unsigned int opb = bfd_octets_per_byte (abfd); - /* Bytes per line. */ - const int onaline = 16; - char buf[64]; - int count; - int width; - - if ((section->flags & SEC_HAS_CONTENTS) == 0) - return; - - if (! process_section_p (section)) - return; - - if ((datasize = bfd_section_size (abfd, section)) == 0) - return; - - /* Compute the address range to display. */ - if (start_address == (bfd_vma) -1 - || start_address < section->vma) - start_offset = 0; - else - start_offset = start_address - section->vma; - - if (stop_address == (bfd_vma) -1) - stop_offset = datasize / opb; - else - { - if (stop_address < section->vma) - stop_offset = 0; - else - stop_offset = stop_address - section->vma; - - if (stop_offset > datasize / opb) - stop_offset = datasize / opb; - } - - if (start_offset >= stop_offset) - return; - - printf (_("Contents of section %s:"), section->name); - if (display_file_offsets) - printf (_(" (Starting at file offset: 0x%lx)"), - (unsigned long) (section->filepos + start_offset)); - printf ("\n"); - - if (!bfd_get_full_section_contents (abfd, section, &data)) - { - non_fatal (_("Reading section failed")); - return; - } - - width = 4; - - bfd_sprintf_vma (abfd, buf, start_offset + section->vma); - if (strlen (buf) >= sizeof (buf)) - abort (); - - count = 0; - while (buf[count] == '0' && buf[count+1] != '\0') - count++; - count = strlen (buf) - count; - if (count > width) - width = count; - - bfd_sprintf_vma (abfd, buf, stop_offset + section->vma - 1); - if (strlen (buf) >= sizeof (buf)) - abort (); - - count = 0; - while (buf[count] == '0' && buf[count+1] != '\0') - count++; - count = strlen (buf) - count; - if (count > width) - width = count; - - for (addr_offset = start_offset; - addr_offset < stop_offset; addr_offset += onaline / opb) - { - bfd_size_type j; - - bfd_sprintf_vma (abfd, buf, (addr_offset + section->vma)); - count = strlen (buf); - if ((size_t) count >= sizeof (buf)) - abort (); - - putchar (' '); - while (count < width) - { - putchar ('0'); - count++; - } - fputs (buf + count - width, stdout); - putchar (' '); - - for (j = addr_offset * opb; - j < addr_offset * opb + onaline; j++) - { - if (j < stop_offset * opb) - printf ("%02x", (unsigned) (data[j])); - else - printf (" "); - if ((j & 3) == 3) - printf (" "); - } - - printf (" "); - for (j = addr_offset * opb; - j < addr_offset * opb + onaline; j++) - { - if (j >= stop_offset * opb) - printf (" "); - else - printf ("%c", ISPRINT (data[j]) ? data[j] : '.'); - } - putchar ('\n'); - } - free (data); -} - -/* Actually display the various requested regions. */ - -static void -dump_data (bfd *abfd) -{ - bfd_map_over_sections (abfd, dump_section, NULL); -} - -/* Should perhaps share code and display with nm? */ - -static void -dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic) -{ - asymbol **current; - long max_count; - long count; - - if (dynamic) - { - current = dynsyms; - max_count = dynsymcount; - printf ("DYNAMIC SYMBOL TABLE:\n"); - } - else - { - current = syms; - max_count = symcount; - printf ("SYMBOL TABLE:\n"); - } - - if (max_count == 0) - printf (_("no symbols\n")); - - for (count = 0; count < max_count; count++) - { - bfd *cur_bfd; - - if (*current == NULL) - printf (_("no information for symbol number %ld\n"), count); - - else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL) - printf (_("could not determine the type of symbol number %ld\n"), - count); - - else if (process_section_p ((* current)->section) - && (dump_special_syms - || !bfd_is_target_special_symbol (cur_bfd, *current))) - { - const char *name = (*current)->name; - - if (do_demangle && name != NULL && *name != '\0') - { - char *alloc; - - /* If we want to demangle the name, we demangle it - here, and temporarily clobber it while calling - bfd_print_symbol. FIXME: This is a gross hack. */ - alloc = bfd_demangle (cur_bfd, name, DMGL_ANSI | DMGL_PARAMS); - if (alloc != NULL) - (*current)->name = alloc; - bfd_print_symbol (cur_bfd, stdout, *current, - bfd_print_symbol_all); - if (alloc != NULL) - { - (*current)->name = name; - free (alloc); - } - } - else - bfd_print_symbol (cur_bfd, stdout, *current, - bfd_print_symbol_all); - printf ("\n"); - } - - current++; - } - printf ("\n\n"); -} - -static void -dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) -{ - arelent **p; - char *last_filename, *last_functionname; - unsigned int last_line; - - /* Get column headers lined up reasonably. */ - { - static int width; - - if (width == 0) - { - char buf[30]; - - bfd_sprintf_vma (abfd, buf, (bfd_vma) -1); - width = strlen (buf) - 7; - } - printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, ""); - } - - last_filename = NULL; - last_functionname = NULL; - last_line = 0; - - for (p = relpp; relcount && *p != NULL; p++, relcount--) - { - arelent *q = *p; - const char *filename, *functionname; - unsigned int linenumber; - const char *sym_name; - const char *section_name; - bfd_vma addend2 = 0; - - if (start_address != (bfd_vma) -1 - && q->address < start_address) - continue; - if (stop_address != (bfd_vma) -1 - && q->address > stop_address) - continue; - - if (with_line_numbers - && sec != NULL - && bfd_find_nearest_line (abfd, sec, syms, q->address, - &filename, &functionname, &linenumber)) - { - if (functionname != NULL - && (last_functionname == NULL - || strcmp (functionname, last_functionname) != 0)) - { - printf ("%s():\n", functionname); - if (last_functionname != NULL) - free (last_functionname); - last_functionname = xstrdup (functionname); - } - - if (linenumber > 0 - && (linenumber != last_line - || (filename != NULL - && last_filename != NULL - && filename_cmp (filename, last_filename) != 0))) - { - printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); - last_line = linenumber; - if (last_filename != NULL) - free (last_filename); - if (filename == NULL) - last_filename = NULL; - else - last_filename = xstrdup (filename); - } - } - - if (q->sym_ptr_ptr && *q->sym_ptr_ptr) - { - sym_name = (*(q->sym_ptr_ptr))->name; - section_name = (*(q->sym_ptr_ptr))->section->name; - } - else - { - sym_name = NULL; - section_name = NULL; - } - - bfd_printf_vma (abfd, q->address); - if (q->howto == NULL) - printf (" *unknown* "); - else if (q->howto->name) - { - const char *name = q->howto->name; - - /* R_SPARC_OLO10 relocations contain two addends. - But because 'arelent' lacks enough storage to - store them both, the 64-bit ELF Sparc backend - records this as two relocations. One R_SPARC_LO10 - and one R_SPARC_13, both pointing to the same - address. This is merely so that we have some - place to store both addend fields. - - Undo this transformation, otherwise the output - will be confusing. */ - if (abfd->xvec->flavour == bfd_target_elf_flavour - && elf_tdata(abfd)->elf_header->e_machine == EM_SPARCV9 - && relcount > 1 - && !strcmp (q->howto->name, "R_SPARC_LO10")) - { - arelent *q2 = *(p + 1); - if (q2 != NULL - && q2->howto - && q->address == q2->address - && !strcmp (q2->howto->name, "R_SPARC_13")) - { - name = "R_SPARC_OLO10"; - addend2 = q2->addend; - p++; - } - } - printf (" %-16s ", name); - } - else - printf (" %-16d ", q->howto->type); - - if (sym_name) - { - objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr); - } - else - { - if (section_name == NULL) - section_name = "*unknown*"; - printf ("[%s]", section_name); - } - - if (q->addend) - { - printf ("+0x"); - bfd_printf_vma (abfd, q->addend); - } - if (addend2) - { - printf ("+0x"); - bfd_printf_vma (abfd, addend2); - } - - printf ("\n"); - } - - if (last_filename != NULL) - free (last_filename); - if (last_functionname != NULL) - free (last_functionname); -} - -static void -dump_relocs_in_section (bfd *abfd, - asection *section, - void *dummy ATTRIBUTE_UNUSED) -{ - arelent **relpp; - long relcount; - long relsize; - - if ( bfd_is_abs_section (section) - || bfd_is_und_section (section) - || bfd_is_com_section (section) - || (! process_section_p (section)) - || ((section->flags & SEC_RELOC) == 0)) - return; - - relsize = bfd_get_reloc_upper_bound (abfd, section); - if (relsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - - printf ("RELOCATION RECORDS FOR [%s]:", section->name); - - if (relsize == 0) - { - printf (" (none)\n\n"); - return; - } - - relpp = (arelent **) xmalloc (relsize); - relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); - - if (relcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - else if (relcount == 0) - printf (" (none)\n\n"); - else - { - printf ("\n"); - dump_reloc_set (abfd, section, relpp, relcount); - printf ("\n\n"); - } - free (relpp); -} - -static void -dump_relocs (bfd *abfd) -{ - bfd_map_over_sections (abfd, dump_relocs_in_section, NULL); -} - -static void -dump_dynamic_relocs (bfd *abfd) -{ - long relsize; - arelent **relpp; - long relcount; - - relsize = bfd_get_dynamic_reloc_upper_bound (abfd); - if (relsize < 0) - bfd_fatal (bfd_get_filename (abfd)); - - printf ("DYNAMIC RELOCATION RECORDS"); - - if (relsize == 0) - printf (" (none)\n\n"); - else - { - relpp = (arelent **) xmalloc (relsize); - relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms); - - if (relcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - else if (relcount == 0) - printf (" (none)\n\n"); - else - { - printf ("\n"); - dump_reloc_set (abfd, NULL, relpp, relcount); - printf ("\n\n"); - } - free (relpp); - } -} - -/* Creates a table of paths, to search for source files. */ - -static void -add_include_path (const char *path) -{ - if (path[0] == 0) - return; - include_path_count++; - include_paths = (const char **) - xrealloc (include_paths, include_path_count * sizeof (*include_paths)); -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - if (path[1] == ':' && path[2] == 0) - path = concat (path, ".", (const char *) 0); -#endif - include_paths[include_path_count - 1] = path; -} - -static void -adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED, - asection *section, - void *arg) -{ - if ((section->flags & SEC_DEBUGGING) == 0) - { - bfd_boolean *has_reloc_p = (bfd_boolean *) arg; - section->vma += adjust_section_vma; - if (*has_reloc_p) - section->lma += adjust_section_vma; - } -} - -/* Dump selected contents of ABFD. */ - -static void -dump_bfd (bfd *abfd) -{ - /* If we are adjusting section VMA's, change them all now. Changing - the BFD information is a hack. However, we must do it, or - bfd_find_nearest_line will not do the right thing. */ - if (adjust_section_vma != 0) - { - bfd_boolean has_reloc = (abfd->flags & HAS_RELOC); - bfd_map_over_sections (abfd, adjust_addresses, &has_reloc); - } - - if (! dump_debugging_tags && ! suppress_bfd_header) - printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), - abfd->xvec->name); - if (dump_ar_hdrs) - print_arelt_descr (stdout, abfd, TRUE); - if (dump_file_header) - dump_bfd_header (abfd); - if (dump_private_headers) - dump_bfd_private_header (abfd); - if (dump_private_options != NULL) - dump_target_specific (abfd); - if (! dump_debugging_tags && ! suppress_bfd_header) - putchar ('\n'); - if (dump_section_headers) - dump_headers (abfd); - - if (dump_symtab - || dump_reloc_info - || disassemble - || dump_debugging - || dump_dwarf_section_info) - syms = slurp_symtab (abfd); - if (dump_dynamic_symtab || dump_dynamic_reloc_info - || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0)) - dynsyms = slurp_dynamic_symtab (abfd); - if (disassemble) - { - synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, - dynsymcount, dynsyms, &synthsyms); - if (synthcount < 0) - synthcount = 0; - } - - if (dump_symtab) - dump_symbols (abfd, FALSE); - if (dump_dynamic_symtab) - dump_symbols (abfd, TRUE); - if (dump_dwarf_section_info) - dump_dwarf (abfd); - if (dump_stab_section_info) - dump_stabs (abfd); - if (dump_reloc_info && ! disassemble) - dump_relocs (abfd); - if (dump_dynamic_reloc_info && ! disassemble) - dump_dynamic_relocs (abfd); - if (dump_section_contents) - dump_data (abfd); - if (disassemble) - disassemble_data (abfd); - - if (dump_debugging) - { - void *dhandle; - - dhandle = read_debugging_info (abfd, syms, symcount, TRUE); - if (dhandle != NULL) - { - if (!print_debugging_info (stdout, dhandle, abfd, syms, - bfd_demangle, - dump_debugging_tags ? TRUE : FALSE)) - { - non_fatal (_("%s: printing debugging information failed"), - bfd_get_filename (abfd)); - exit_status = 1; - } - } - /* PR 6483: If there was no STABS or IEEE debug - info in the file, try DWARF instead. */ - else if (! dump_dwarf_section_info) - { - dump_dwarf (abfd); - } - } - - if (syms) - { - free (syms); - syms = NULL; - } - - if (dynsyms) - { - free (dynsyms); - dynsyms = NULL; - } - - if (synthsyms) - { - free (synthsyms); - synthsyms = NULL; - } - - symcount = 0; - dynsymcount = 0; - synthcount = 0; -} - -static void -display_bfd (bfd *abfd) -{ - char **matching; - - if (bfd_check_format_matches (abfd, bfd_object, &matching)) - { - dump_bfd (abfd); - return; - } - - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - nonfatal (bfd_get_filename (abfd)); - list_matching_formats (matching); - free (matching); - return; - } - - if (bfd_get_error () != bfd_error_file_not_recognized) - { - nonfatal (bfd_get_filename (abfd)); - return; - } - - if (bfd_check_format_matches (abfd, bfd_core, &matching)) - { - dump_bfd (abfd); - return; - } - - nonfatal (bfd_get_filename (abfd)); - - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } -} - -static void -display_file (char *filename, char *target) -{ - bfd *file; - bfd *arfile = NULL; - - if (get_file_size (filename) < 1) - { - exit_status = 1; - return; - } - - file = bfd_openr (filename, target); - if (file == NULL) - { - nonfatal (filename); - return; - } - - /* Decompress sections unless dumping the section contents. */ - if (!dump_section_contents) - file->flags |= BFD_DECOMPRESS; - - /* If the file is an archive, process all of its elements. */ - if (bfd_check_format (file, bfd_archive)) - { - bfd *last_arfile = NULL; - - printf (_("In archive %s:\n"), bfd_get_filename (file)); - for (;;) - { - bfd_set_error (bfd_error_no_error); - - arfile = bfd_openr_next_archived_file (file, arfile); - if (arfile == NULL) - { - if (bfd_get_error () != bfd_error_no_more_archived_files) - nonfatal (bfd_get_filename (file)); - break; - } - - display_bfd (arfile); - - if (last_arfile != NULL) - bfd_close (last_arfile); - last_arfile = arfile; - } - - if (last_arfile != NULL) - bfd_close (last_arfile); - } - else - display_bfd (file); - - bfd_close (file); -} - -int -main (int argc, char **argv) -{ - int c; - char *target = default_target; - bfd_boolean seenflag = FALSE; - -#if defined (HAVE_SETLOCALE) -#if defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif - setlocale (LC_CTYPE, ""); -#endif - - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = *argv; - xmalloc_set_program_name (program_name); - - START_PROGRESS (program_name, 0); - - expandargv (&argc, &argv); - - bfd_init (); - set_default_bfd_target (); - - while ((c = getopt_long (argc, argv, - "pP:ib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::", - long_options, (int *) 0)) - != EOF) - { - switch (c) - { - case 0: - break; /* We've been given a long option. */ - case 'm': - machine = optarg; - break; - case 'M': - if (disassembler_options) - /* Ignore potential memory leak for now. */ - disassembler_options = concat (disassembler_options, ",", - optarg, (const char *) NULL); - else - disassembler_options = optarg; - break; - case 'j': - add_only (optarg); - break; - case 'F': - display_file_offsets = TRUE; - break; - case 'l': - with_line_numbers = TRUE; - break; - case 'b': - target = optarg; - break; - case 'C': - do_demangle = TRUE; - if (optarg != NULL) - { - enum demangling_styles style; - - style = cplus_demangle_name_to_style (optarg); - if (style == unknown_demangling) - fatal (_("unknown demangling style `%s'"), - optarg); - - cplus_demangle_set_style (style); - } - break; - case 'w': - wide_output = TRUE; - break; - case OPTION_ADJUST_VMA: - adjust_section_vma = parse_vma (optarg, "--adjust-vma"); - break; - case OPTION_START_ADDRESS: - start_address = parse_vma (optarg, "--start-address"); - if ((stop_address != (bfd_vma) -1) && stop_address <= start_address) - fatal (_("error: the start address should be before the end address")); - break; - case OPTION_STOP_ADDRESS: - stop_address = parse_vma (optarg, "--stop-address"); - if ((start_address != (bfd_vma) -1) && stop_address <= start_address) - fatal (_("error: the stop address should be after the start address")); - break; - case OPTION_PREFIX: - prefix = optarg; - prefix_length = strlen (prefix); - /* Remove an unnecessary trailing '/' */ - while (IS_DIR_SEPARATOR (prefix[prefix_length - 1])) - prefix_length--; - break; - case OPTION_PREFIX_STRIP: - prefix_strip = atoi (optarg); - if (prefix_strip < 0) - fatal (_("error: prefix strip must be non-negative")); - break; - case OPTION_INSN_WIDTH: - insn_width = strtoul (optarg, NULL, 0); - if (insn_width <= 0) - fatal (_("error: instruction width must be positive")); - break; - case 'E': - if (strcmp (optarg, "B") == 0) - endian = BFD_ENDIAN_BIG; - else if (strcmp (optarg, "L") == 0) - endian = BFD_ENDIAN_LITTLE; - else - { - nonfatal (_("unrecognized -E option")); - usage (stderr, 1); - } - break; - case OPTION_ENDIAN: - if (strncmp (optarg, "big", strlen (optarg)) == 0) - endian = BFD_ENDIAN_BIG; - else if (strncmp (optarg, "little", strlen (optarg)) == 0) - endian = BFD_ENDIAN_LITTLE; - else - { - non_fatal (_("unrecognized --endian type `%s'"), optarg); - exit_status = 1; - usage (stderr, 1); - } - break; - - case 'f': - dump_file_header = TRUE; - seenflag = TRUE; - break; - case 'i': - formats_info = TRUE; - seenflag = TRUE; - break; - case 'I': - add_include_path (optarg); - break; - case 'p': - dump_private_headers = TRUE; - seenflag = TRUE; - break; - case 'P': - dump_private_options = optarg; - seenflag = TRUE; - break; - case 'x': - dump_private_headers = TRUE; - dump_symtab = TRUE; - dump_reloc_info = TRUE; - dump_file_header = TRUE; - dump_ar_hdrs = TRUE; - dump_section_headers = TRUE; - seenflag = TRUE; - break; - case 't': - dump_symtab = TRUE; - seenflag = TRUE; - break; - case 'T': - dump_dynamic_symtab = TRUE; - seenflag = TRUE; - break; - case 'd': - disassemble = TRUE; - seenflag = TRUE; - break; - case 'z': - disassemble_zeroes = TRUE; - break; - case 'D': - disassemble = TRUE; - disassemble_all = TRUE; - seenflag = TRUE; - break; - case 'S': - disassemble = TRUE; - with_source_code = TRUE; - seenflag = TRUE; - break; - case 'g': - dump_debugging = 1; - seenflag = TRUE; - break; - case 'e': - dump_debugging = 1; - dump_debugging_tags = 1; - do_demangle = TRUE; - seenflag = TRUE; - break; - case 'W': - dump_dwarf_section_info = TRUE; - seenflag = TRUE; - if (optarg) - dwarf_select_sections_by_letters (optarg); - else - dwarf_select_sections_all (); - break; - case OPTION_DWARF: - dump_dwarf_section_info = TRUE; - seenflag = TRUE; - if (optarg) - dwarf_select_sections_by_names (optarg); - else - dwarf_select_sections_all (); - break; - case OPTION_DWARF_DEPTH: - { - char *cp; - dwarf_cutoff_level = strtoul (optarg, & cp, 0); - } - break; - case OPTION_DWARF_START: - { - char *cp; - dwarf_start_die = strtoul (optarg, & cp, 0); - suppress_bfd_header = 1; - } - break; - case 'G': - dump_stab_section_info = TRUE; - seenflag = TRUE; - break; - case 's': - dump_section_contents = TRUE; - seenflag = TRUE; - break; - case 'r': - dump_reloc_info = TRUE; - seenflag = TRUE; - break; - case 'R': - dump_dynamic_reloc_info = TRUE; - seenflag = TRUE; - break; - case 'a': - dump_ar_hdrs = TRUE; - seenflag = TRUE; - break; - case 'h': - dump_section_headers = TRUE; - seenflag = TRUE; - break; - case 'H': - usage (stdout, 0); - seenflag = TRUE; - case 'v': - case 'V': - show_version = TRUE; - seenflag = TRUE; - break; - - default: - usage (stderr, 1); - } - } - - if (show_version) - print_version ("objdump"); - - if (!seenflag) - usage (stderr, 2); - - if (formats_info) - exit_status = display_info (); - else - { - if (optind == argc) - display_file ("a.out", target); - else - for (; optind < argc;) - display_file (argv[optind++], target); - } - - free_only_list (); - - END_PROGRESS (program_name); - - return exit_status; -} diff --git a/contrib/binutils-2.22/binutils/objdump.h b/contrib/binutils-2.22/binutils/objdump.h deleted file mode 100644 index 511898c495..0000000000 --- a/contrib/binutils-2.22/binutils/objdump.h +++ /dev/null @@ -1,50 +0,0 @@ -/* objdump.h - Copyright 2011 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include - -struct objdump_private_option -{ - /* Option name. */ - const char *name; - - /* TRUE if the option is selected. Automatically set and cleared by - objdump. */ - unsigned int selected; -}; - -struct objdump_private_desc -{ - /* Help displayed for --help. */ - void (*help)(FILE *stream); - - /* Return TRUE if these options can be applied to ABFD. */ - int (*filter)(bfd *abfd); - - /* Do the actual work: display whatever is requested according to the - options whose SELECTED field is set. */ - void (*dump)(bfd *abfd); - - /* List of options. Terminated by a NULL name. */ - struct objdump_private_option *options; -}; - -/* XCOFF specific target. */ -extern const struct objdump_private_desc objdump_private_desc_xcoff; diff --git a/contrib/binutils-2.22/binutils/od-xcoff.c b/contrib/binutils-2.22/binutils/od-xcoff.c deleted file mode 100644 index 5b8b5896eb..0000000000 --- a/contrib/binutils-2.22/binutils/od-xcoff.c +++ /dev/null @@ -1,1667 +0,0 @@ -/* od-xcoff.c -- dump information about an xcoff object file. - Copyright 2011 Free Software Foundation, Inc. - Written by Tristan Gingold, Adacore. - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include -#include -#include "sysdep.h" -#include "safe-ctype.h" -#include "bfd.h" -#include "objdump.h" -#include "bucomm.h" -#include "bfdlink.h" -/* Force the support of weak symbols. */ -#ifndef AIX_WEAK_SUPPORT -#define AIX_WEAK_SUPPORT 1 -#endif -#include "coff/internal.h" -#include "coff/rs6000.h" -#include "coff/xcoff.h" -#include "libcoff.h" -#include "libxcoff.h" - -/* Index of the options in the options[] array. */ -#define OPT_FILE_HEADER 0 -#define OPT_AOUT 1 -#define OPT_SECTIONS 2 -#define OPT_SYMS 3 -#define OPT_RELOCS 4 -#define OPT_LINENO 5 -#define OPT_LOADER 6 -#define OPT_EXCEPT 7 -#define OPT_TYPCHK 8 -#define OPT_TRACEBACK 9 -#define OPT_TOC 10 - -/* List of actions. */ -static struct objdump_private_option options[] = - { - { "header", 0 }, - { "aout", 0 }, - { "sections", 0 }, - { "syms", 0 }, - { "relocs", 0 }, - { "lineno", 0 }, - { "loader", 0 }, - { "except", 0 }, - { "typchk", 0 }, - { "traceback", 0 }, - { "toc", 0 }, - { NULL, 0 } - }; - -/* Display help. */ - -static void -xcoff_help (FILE *stream) -{ - fprintf (stream, _("\ -For XCOFF files:\n\ - header Display the file header\n\ - aout Display the auxiliary header\n\ - sections Display the section headers\n\ - syms Display the symbols table\n\ - relocs Display the relocation entries\n\ - lineno Display the line number entries\n\ - loader Display loader section\n\ - except Display exception table\n\ - typchk Display type-check section\n\ - traceback Display traceback tags\n\ - toc Display toc symbols\n\ -")); -} - -/* Return TRUE if ABFD is handled. */ - -static int -xcoff_filter (bfd *abfd) -{ - return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour; -} - -/* Translation entry type. The last entry must be {0, NULL}. */ - -struct xlat_table { - unsigned int val; - const char *name; -}; - -/* Display the list of name (from TABLE) for FLAGS, using comma to separate - them. A name is displayed if FLAGS & VAL is not 0. */ - -static void -dump_flags (const struct xlat_table *table, unsigned int flags) -{ - unsigned int r = flags; - int first = 1; - const struct xlat_table *t; - - for (t = table; t->name; t++) - if ((flags & t->val) != 0) - { - r &= ~t->val; - - if (first) - first = 0; - else - putchar (','); - fputs (t->name, stdout); - } - - /* Not decoded flags. */ - if (r != 0) - { - if (!first) - putchar (','); - printf ("0x%x", r); - } -} - -/* Display the name corresponding to VAL from TABLE, using at most - MAXLEN char (possibly passed with spaces). */ - -static void -dump_value (const struct xlat_table *table, unsigned int val, int maxlen) -{ - const struct xlat_table *t; - - for (t = table; t->name; t++) - if (t->val == val) - { - printf ("%-*s", maxlen, t->name); - return; - } - printf ("(%*x)", maxlen - 2, val); -} - -/* Names of f_flags. */ -static const struct xlat_table f_flag_xlat[] = - { - { F_RELFLG, "no-rel" }, - { F_EXEC, "exec" }, - { F_LNNO, "lineno" }, - { F_LSYMS, "lsyms" }, - - { F_FDPR_PROF, "fdpr-prof" }, - { F_FDPR_OPTI, "fdpr-opti" }, - { F_DSA, "dsa" }, - - { F_VARPG, "varprg" }, - - { F_DYNLOAD, "dynload" }, - { F_SHROBJ, "shrobj" }, - { F_NONEXEC, "nonexec" }, - - { 0, NULL } - }; - -/* Names of s_flags. */ -static const struct xlat_table s_flag_xlat[] = - { - { STYP_PAD, "pad" }, - { STYP_DWARF, "dwarf" }, - { STYP_TEXT, "text" }, - { STYP_DATA, "data" }, - { STYP_BSS, "bss" }, - - { STYP_EXCEPT, "except" }, - { STYP_INFO, "info" }, - { STYP_TDATA, "tdata" }, - { STYP_TBSS, "tbss" }, - - { STYP_LOADER, "loader" }, - { STYP_DEBUG, "debug" }, - { STYP_TYPCHK, "typchk" }, - { STYP_OVRFLO, "ovrflo" }, - { 0, NULL } - }; - -/* Names of storage class. */ -static const struct xlat_table sc_xlat[] = - { -#define SC_ENTRY(X) { C_##X, #X } - SC_ENTRY(NULL), - SC_ENTRY(AUTO), - SC_ENTRY(EXT), - SC_ENTRY(STAT), - SC_ENTRY(REG), - SC_ENTRY(EXTDEF), - SC_ENTRY(LABEL), - SC_ENTRY(ULABEL), - SC_ENTRY(MOS), - SC_ENTRY(ARG), - /* SC_ENTRY(STRARG), */ - SC_ENTRY(MOU), - SC_ENTRY(UNTAG), - SC_ENTRY(TPDEF), - SC_ENTRY(USTATIC), - SC_ENTRY(ENTAG), - SC_ENTRY(MOE), - SC_ENTRY(REGPARM), - SC_ENTRY(FIELD), - SC_ENTRY(BLOCK), - SC_ENTRY(FCN), - SC_ENTRY(EOS), - SC_ENTRY(FILE), - SC_ENTRY(LINE), - SC_ENTRY(ALIAS), - SC_ENTRY(HIDDEN), - SC_ENTRY(HIDEXT), - SC_ENTRY(BINCL), - SC_ENTRY(EINCL), - SC_ENTRY(INFO), - SC_ENTRY(WEAKEXT), - SC_ENTRY(DWARF), - - /* Stabs. */ - SC_ENTRY (GSYM), - SC_ENTRY (LSYM), - SC_ENTRY (PSYM), - SC_ENTRY (RSYM), - SC_ENTRY (RPSYM), - SC_ENTRY (STSYM), - SC_ENTRY (TCSYM), - SC_ENTRY (BCOMM), - SC_ENTRY (ECOML), - SC_ENTRY (ECOMM), - SC_ENTRY (DECL), - SC_ENTRY (ENTRY), - SC_ENTRY (FUN), - SC_ENTRY (BSTAT), - SC_ENTRY (ESTAT), - - { 0, NULL } -#undef SC_ENTRY - }; - -/* Names for symbol type. */ -static const struct xlat_table smtyp_xlat[] = - { - { XTY_ER, "ER" }, - { XTY_SD, "SD" }, - { XTY_LD, "LD" }, - { XTY_CM, "CM" }, - { XTY_EM, "EM" }, - { XTY_US, "US" }, - { 0, NULL } - }; - -/* Names for storage-mapping class. */ -static const struct xlat_table smclas_xlat[] = - { -#define SMCLAS_ENTRY(X) { XMC_##X, #X } - SMCLAS_ENTRY (PR), - SMCLAS_ENTRY (RO), - SMCLAS_ENTRY (DB), - SMCLAS_ENTRY (TC), - SMCLAS_ENTRY (UA), - SMCLAS_ENTRY (RW), - SMCLAS_ENTRY (GL), - SMCLAS_ENTRY (XO), - SMCLAS_ENTRY (SV), - SMCLAS_ENTRY (BS), - SMCLAS_ENTRY (DS), - SMCLAS_ENTRY (UC), - SMCLAS_ENTRY (TI), - SMCLAS_ENTRY (TB), - SMCLAS_ENTRY (TC0), - SMCLAS_ENTRY (TD), - SMCLAS_ENTRY (SV64), - SMCLAS_ENTRY (SV3264), - { 0, NULL } -#undef SMCLAS_ENTRY - }; - -/* Names for relocation type. */ -static const struct xlat_table rtype_xlat[] = - { -#define RTYPE_ENTRY(X) { R_##X, #X } - RTYPE_ENTRY (POS), - RTYPE_ENTRY (NEG), - RTYPE_ENTRY (REL), - RTYPE_ENTRY (TOC), - RTYPE_ENTRY (RTB), - RTYPE_ENTRY (GL), - RTYPE_ENTRY (TCL), - RTYPE_ENTRY (BA), - RTYPE_ENTRY (BR), - RTYPE_ENTRY (RL), - RTYPE_ENTRY (RLA), - RTYPE_ENTRY (REF), - RTYPE_ENTRY (TRL), - RTYPE_ENTRY (TRLA), - RTYPE_ENTRY (RRTBI), - RTYPE_ENTRY (RRTBA), - RTYPE_ENTRY (CAI), - RTYPE_ENTRY (CREL), - RTYPE_ENTRY (RBA), - RTYPE_ENTRY (RBAC), - RTYPE_ENTRY (RBR), - RTYPE_ENTRY (RBRC), - RTYPE_ENTRY (TLS), - RTYPE_ENTRY (TLS_IE), - RTYPE_ENTRY (TLS_LD), - RTYPE_ENTRY (TLS_LE), - RTYPE_ENTRY (TLSM), - RTYPE_ENTRY (TLSML), - RTYPE_ENTRY (TOCU), - RTYPE_ENTRY (TOCL), - { 0, NULL } - }; - -/* Simplified section header. */ -struct xcoff32_section -{ - /* NUL terminated name. */ - char name[9]; - - /* Section flags. */ - unsigned int flags; - - /* Offsets in file. */ - ufile_ptr scnptr; - ufile_ptr relptr; - ufile_ptr lnnoptr; - - /* Number of relocs and line numbers. */ - unsigned int nreloc; - unsigned int nlnno; -}; - -/* Simplified symbol. */ - -union xcoff32_symbol -{ - union external_auxent aux; - - struct sym - { - /* Pointer the the NUL-terminated name. */ - char *name; - - /* XCOFF symbol fields. */ - unsigned int val; - unsigned short scnum; - unsigned short ntype; - unsigned char sclass; - unsigned char numaux; - - /* Buffer in case the name is local. */ - union - { - char name[9]; - unsigned int off; - } raw; - } sym; -}; - -/* Important fields to dump the file. */ - -struct xcoff_dump -{ - /* From file header. */ - unsigned short nscns; - unsigned int symptr; - unsigned int nsyms; - unsigned short opthdr; - - /* Sections. */ - struct xcoff32_section *sects; - - /* Symbols. */ - union xcoff32_symbol *syms; - char *strings; - unsigned int strings_size; -}; - -/* Print a symbol (if possible). */ - -static void -xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx) -{ - if (data->syms != NULL - && symndx < data->nsyms - && data->syms[symndx].sym.name != NULL) - printf ("%s", data->syms[symndx].sym.name); - else - printf ("%u", symndx); -} - -/* Dump the file header. */ - -static void -dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr, - struct xcoff_dump *data) -{ - unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat); - unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags); - - printf (_(" nbr sections: %d\n"), data->nscns); - printf (_(" time and date: 0x%08x - "), timdat); - if (timdat == 0) - printf (_("not set\n")); - else - { - /* Not correct on all platforms, but works on unix. */ - time_t t = timdat; - fputs (ctime (&t), stdout); - } - printf (_(" symbols off: 0x%08x\n"), data->symptr); - printf (_(" nbr symbols: %d\n"), data->nsyms); - printf (_(" opt hdr sz: %d\n"), data->opthdr); - printf (_(" flags: 0x%04x "), flags); - dump_flags (f_flag_xlat, flags); - putchar ('\n'); -} - -/* Dump the a.out header. */ - -static void -dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data) -{ - AOUTHDR auxhdr; - unsigned short magic; - unsigned int sz = data->opthdr; - - printf (_("Auxiliary header:\n")); - if (data->opthdr == 0) - { - printf (_(" No aux header\n")); - return; - } - if (data->opthdr > sizeof (auxhdr)) - { - printf (_("warning: optionnal header size too large (> %d)\n"), - (int)sizeof (auxhdr)); - sz = sizeof (auxhdr); - } - if (bfd_bread (&auxhdr, sz, abfd) != sz) - { - non_fatal (_("cannot read auxhdr")); - return; - } - - magic = bfd_h_get_16 (abfd, auxhdr.magic); - printf (_(" o_mflag (magic): 0x%04x 0%04o\n"), magic, magic); - printf (_(" o_vstamp: 0x%04x\n"), - (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp)); - printf (_(" o_tsize: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize)); - printf (_(" o_dsize: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize)); - printf (_(" o_entry: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry)); - printf (_(" o_text_start: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start)); - printf (_(" o_data_start: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start)); - if (sz == offsetof (AOUTHDR, o_toc)) - return; - printf (_(" o_toc: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc)); - printf (_(" o_snentry: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry)); - printf (_(" o_sntext: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext)); - printf (_(" o_sndata: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata)); - printf (_(" o_sntoc: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc)); - printf (_(" o_snloader: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader)); - printf (_(" o_snbss: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss)); - printf (_(" o_algntext: %u\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext)); - printf (_(" o_algndata: %u\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata)); - printf (_(" o_modtype: 0x%04x"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype)); - if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1])) - printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]); - putchar ('\n'); - printf (_(" o_cputype: 0x%04x\n"), - (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype)); - printf (_(" o_maxstack: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack)); - printf (_(" o_maxdata: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata)); -#if 0 - printf (_(" o_debugger: 0x%08x\n"), - (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger)); -#endif -} - -/* Dump the sections header. */ - -static void -dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - unsigned int off; - - off = sizeof (struct external_filehdr) + data->opthdr; - printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"), - (unsigned int)sizeof (struct external_filehdr), data->opthdr, off, - off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns); - if (data->nscns == 0) - { - printf (_(" No section header\n")); - return; - } - if (bfd_seek (abfd, off, SEEK_SET) != 0) - { - non_fatal (_("cannot read section header")); - return; - } - printf (_(" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n")); - for (i = 0; i < data->nscns; i++) - { - struct external_scnhdr scn; - unsigned int flags; - - if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn)) - { - non_fatal (_("cannot read section header")); - return; - } - flags = bfd_h_get_32 (abfd, scn.s_flags); - printf (_("%2d %-8.8s %08x %08x %08x %08x %08x %08x " - "%-5d %-5d\n"), - i + 1, scn.s_name, - (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr), - (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr), - (unsigned int)bfd_h_get_32 (abfd, scn.s_size), - (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr), - (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr), - (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr), - (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc), - (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno)); - printf (_(" Flags: %08x "), flags); - - if (~flags == 0) - { - /* Stripped executable ? */ - putchar ('\n'); - } - else if (flags & STYP_OVRFLO) - printf (_("overflow - nreloc: %u, nlnno: %u\n"), - (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr), - (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr)); - else - { - dump_flags (s_flag_xlat, flags); - putchar ('\n'); - } - } -} - -/* Read section table. */ - -static void -xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data) -{ - int i; - - if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr, - SEEK_SET) != 0) - { - non_fatal (_("cannot read section headers")); - return; - } - - data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section)); - for (i = 0; i < data->nscns; i++) - { - struct external_scnhdr scn; - struct xcoff32_section *s = &data->sects[i]; - - if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn)) - { - non_fatal (_("cannot read section header")); - free (data->sects); - data->sects = NULL; - return; - } - memcpy (s->name, scn.s_name, 8); - s->name[8] = 0; - s->flags = bfd_h_get_32 (abfd, scn.s_flags); - - s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr); - s->relptr = bfd_h_get_32 (abfd, scn.s_relptr); - s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr); - - s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc); - s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno); - - if (s->flags == STYP_OVRFLO) - { - if (s->nreloc > 0 && s->nreloc <= data->nscns) - data->sects[s->nreloc - 1].nreloc = - bfd_h_get_32 (abfd, scn.s_paddr); - if (s->nlnno > 0 && s->nlnno <= data->nscns) - data->sects[s->nlnno - 1].nlnno = - bfd_h_get_32 (abfd, scn.s_vaddr); - } - } -} - -/* Read symbols. */ - -static void -xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - char stsz_arr[4]; - unsigned int stptr; - - if (data->nsyms == 0) - return; - - stptr = data->symptr - + data->nsyms * (unsigned)sizeof (struct external_syment); - - /* Read string table. */ - if (bfd_seek (abfd, stptr, SEEK_SET) != 0 - || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr)) - { - non_fatal (_("cannot read strings table length")); - data->strings_size = 0; - } - else - { - data->strings_size = bfd_h_get_32 (abfd, stsz_arr); - if (data->strings_size > sizeof (stsz_arr)) - { - unsigned int remsz = data->strings_size - sizeof (stsz_arr); - - data->strings = xmalloc (data->strings_size); - - memcpy (data->strings, stsz_arr, sizeof (stsz_arr)); - if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd) - != remsz) - { - non_fatal (_("cannot read strings table")); - goto clean; - } - } - } - - if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0) - { - non_fatal (_("cannot read symbol table")); - goto clean; - } - - data->syms = (union xcoff32_symbol *) - xmalloc (data->nsyms * sizeof (union xcoff32_symbol)); - - for (i = 0; i < data->nsyms; i++) - { - struct external_syment sym; - int j; - union xcoff32_symbol *s = &data->syms[i]; - - if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym)) - { - non_fatal (_("cannot read symbol entry")); - goto clean; - } - - s->sym.val = bfd_h_get_32 (abfd, sym.e_value); - s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum); - s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type); - s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass); - s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux); - - if (sym.e.e_name[0]) - { - memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name)); - s->sym.raw.name[8] = 0; - s->sym.name = s->sym.raw.name; - } - else - { - unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset); - - if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size) - s->sym.name = data->strings + soff; - else - { - s->sym.name = NULL; - s->sym.raw.off = soff; - } - } - - for (j = 0; j < s->sym.numaux; j++, i++) - { - if (bfd_bread (&s[j + 1].aux, - sizeof (union external_auxent), abfd) - != sizeof (union external_auxent)) - { - non_fatal (_("cannot read symbol aux entry")); - goto clean; - } - } - } - return; - clean: - free (data->syms); - data->syms = NULL; - free (data->strings); - data->strings = NULL; -} - -/* Dump xcoff symbols. */ - -static void -dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - asection *debugsec; - char *debug = NULL; - - printf (_("Symbols table (strtable at 0x%08x)"), - data->symptr - + data->nsyms * (unsigned)sizeof (struct external_syment)); - if (data->nsyms == 0 || data->syms == NULL) - { - printf (_(":\n No symbols\n")); - return; - } - - /* Read string table. */ - if (data->strings_size == 0) - printf (_(" (no strings):\n")); - else - printf (_(" (strings size: %08x):\n"), data->strings_size); - - /* Read debug section. */ - debugsec = bfd_get_section_by_name (abfd, ".debug"); - if (debugsec != NULL) - { - bfd_size_type size; - - size = bfd_get_section_size (debugsec); - debug = (char *) xmalloc (size); - bfd_get_section_contents (abfd, debugsec, debug, 0, size); - } - - printf (_(" # sc value section type aux name/off\n")); - for (i = 0; i < data->nsyms; i++) - { - union xcoff32_symbol *s = &data->syms[i]; - int j; - - printf ("%3u ", i); - dump_value (sc_xlat, s->sym.sclass, 10); - printf (" %08x ", s->sym.val); - if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns) - { - if (data->sects != NULL) - printf ("%-8s", data->sects[s->sym.scnum - 1].name); - else - printf ("%-8u", s->sym.scnum); - } - else - switch ((signed short)s->sym.scnum) - { - case N_DEBUG: - printf ("N_DEBUG "); - break; - case N_ABS: - printf ("N_ABS "); - break; - case N_UNDEF: - printf ("N_UNDEF "); - break; - default: - printf ("(%04x) ", s->sym.scnum); - } - printf (" %04x %3u ", s->sym.ntype, s->sym.numaux); - if (s->sym.name != NULL) - printf ("%s", s->sym.name); - else - { - if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL) - printf ("%s", debug + s->sym.raw.off); - else - printf ("%08x", s->sym.raw.off); - } - putchar ('\n'); - - for (j = 0; j < s->sym.numaux; j++, i++) - { - union external_auxent *aux = &s[j + 1].aux; - - printf (" %3u ", i + 1); - switch (s->sym.sclass) - { - case C_STAT: - printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-6u\n"), - (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen), - (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc), - (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno)); - break; - case C_DWARF: - printf (_(" scnlen: %08x nreloc: %-6u\n"), - (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen), - (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc)); - break; - case C_EXT: - case C_WEAKEXT: - case C_HIDEXT: - if (j == 0 && s->sym.numaux > 1) - { - /* Function aux entry. */ - printf (_(" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n"), - (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx), - (unsigned)bfd_h_get_32 - (abfd, aux->x_sym.x_misc.x_fsize), - (unsigned)bfd_h_get_32 - (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr), - (unsigned)bfd_h_get_32 - (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx)); - } - else if (j == 1 || (j == 0 && s->sym.numaux == 1)) - { - /* csect aux entry. */ - unsigned char smtyp; - unsigned int scnlen; - - smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp); - scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen); - - if (smtyp == XTY_LD) - printf (_(" scnsym: %-8u"), scnlen); - else - printf (_(" scnlen: %08x"), scnlen); - printf (_(" h: parm=%08x sn=%04x al: 2**%u"), - (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash), - (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash), - SMTYP_ALIGN (smtyp)); - printf (_(" typ: ")); - dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2); - printf (_(" cl: ")); - dump_value - (smclas_xlat, - (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6); - putchar ('\n'); - } - else - printf ("aux\n"); - break; - case C_FILE: - { - unsigned int off; - - printf (_(" ftype: %02x "), - (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype)); - if (aux->x_file.x_n.x_fname[0] != 0) - printf (_("fname: %.14s"), aux->x_file.x_n.x_fname); - else - { - off = (unsigned)bfd_h_get_32 - (abfd, aux->x_file.x_n.x_n.x_offset); - if (data->strings != NULL && off < data->strings_size) - printf (_(" %s"), data->strings + off); - else - printf (_("offset: %08x"), off); - } - putchar ('\n'); - } - break; - case C_BLOCK: - case C_FCN: - printf (_(" lnno: %u\n"), - (unsigned)bfd_h_get_16 - (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno)); - break; - default: - printf ("aux\n"); - break; - } - } - - } - free (debug); -} - -/* Dump xcoff relocation entries. */ - -static void -dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - - if (data->sects == NULL) - { - non_fatal (_("cannot read section headers")); - return; - } - - for (i = 0; i < data->nscns; i++) - { - struct xcoff32_section *sect = &data->sects[i]; - unsigned int nrel = sect->nreloc; - unsigned int j; - - if (nrel == 0) - continue; - printf (_("Relocations for %s (%u)\n"), sect->name, nrel); - if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0) - { - non_fatal (_("cannot read relocations")); - continue; - } - printf (_("vaddr sgn mod sz type symndx symbol\n")); - for (j = 0; j < nrel; j++) - { - struct external_reloc rel; - unsigned char rsize; - unsigned int symndx; - - if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel)) - { - non_fatal (_("cannot read relocation entry")); - return; - } - rsize = bfd_h_get_8 (abfd, rel.r_size); - printf (_("%08x %c %c %-2u "), - (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr), - rsize & 0x80 ? 'S' : 'U', - rsize & 0x40 ? 'm' : ' ', - (rsize & 0x3f) + 1); - dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6); - symndx = bfd_h_get_32 (abfd, rel.r_symndx); - printf ("%-6u ", symndx); - xcoff32_print_symbol (data, symndx); - putchar ('\n'); - } - putchar ('\n'); - } -} - -/* Dump xcoff line number entries. */ - -static void -dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - - if (data->sects == NULL) - { - non_fatal (_("cannot read section headers")); - return; - } - - for (i = 0; i < data->nscns; i++) - { - struct xcoff32_section *sect = &data->sects[i]; - unsigned int nlnno = sect->nlnno; - unsigned int j; - - if (nlnno == 0) - continue; - printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno); - if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0) - { - non_fatal (_("cannot read line numbers")); - continue; - } - printf (_("lineno symndx/paddr\n")); - for (j = 0; j < nlnno; j++) - { - struct external_lineno ln; - unsigned int no; - - if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln)) - { - non_fatal (_("cannot read line number entry")); - return; - } - no = bfd_h_get_16 (abfd, ln.l_lnno); - printf (_(" %-6u "), no); - if (no == 0) - { - unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx); - xcoff32_print_symbol (data, symndx); - } - else - printf ("0x%08x", - (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr)); - putchar ('\n'); - } - } -} - -/* Dump xcoff loader section. */ - -static void -dump_xcoff32_loader (bfd *abfd) -{ - asection *loader; - bfd_size_type size = 0; - struct external_ldhdr *lhdr; - struct external_ldsym *ldsym; - struct external_ldrel *ldrel; - bfd_byte *ldr_data; - unsigned int version; - unsigned int ndsyms; - unsigned int ndrel; - unsigned int stlen; - unsigned int stoff; - unsigned int impoff; - unsigned int nimpid; - unsigned int i; - const char *p; - - loader = bfd_get_section_by_name (abfd, ".loader"); - - if (loader == NULL) - { - printf (_("no .loader section in file\n")); - return; - } - size = bfd_get_section_size (loader); - if (size < sizeof (*lhdr)) - { - printf (_("section .loader is too short\n")); - return; - } - - ldr_data = (bfd_byte *) xmalloc (size); - bfd_get_section_contents (abfd, loader, ldr_data, 0, size); - lhdr = (struct external_ldhdr *)ldr_data; - printf (_("Loader header:\n")); - version = bfd_h_get_32 (abfd, lhdr->l_version); - printf (_(" version: %u\n"), version); - if (version != 1) - { - printf (_(" Unhandled version\n")); - free (ldr_data); - return; - } - ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms); - printf (_(" nbr symbols: %u\n"), ndsyms); - ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc); - printf (_(" nbr relocs: %u\n"), ndrel); - printf (_(" import strtab len: %u\n"), - (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen)); - nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid); - printf (_(" nbr import files: %u\n"), nimpid); - impoff = bfd_h_get_32 (abfd, lhdr->l_impoff); - printf (_(" import file off: %u\n"), impoff); - stlen = bfd_h_get_32 (abfd, lhdr->l_stlen); - printf (_(" string table len: %u\n"), stlen); - stoff = bfd_h_get_32 (abfd, lhdr->l_stoff); - printf (_(" string table off: %u\n"), stoff); - - ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr)); - printf (_("Dynamic symbols:\n")); - printf (_(" # value sc IFEW ty class file pa name\n")); - for (i = 0; i < ndsyms; i++, ldsym++) - { - unsigned char smtype; - - printf (_(" %4u %08x %3u "), i, - (unsigned)bfd_h_get_32 (abfd, ldsym->l_value), - (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum)); - smtype = bfd_h_get_8 (abfd, ldsym->l_smtype); - putchar (smtype & 0x40 ? 'I' : ' '); - putchar (smtype & 0x20 ? 'F' : ' '); - putchar (smtype & 0x10 ? 'E' : ' '); - putchar (smtype & 0x08 ? 'W' : ' '); - putchar (' '); - dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2); - putchar (' '); - dump_value - (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6); - printf (_(" %3u %3u "), - (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile), - (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm)); - if (ldsym->_l._l_name[0] != 0) - printf ("%-.8s", ldsym->_l._l_name); - else - { - unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset); - if (off > stlen) - printf (_("(bad offset: %u)"), off); - else - printf ("%s", ldr_data + stoff + off); - } - putchar ('\n'); - } - - printf (_("Dynamic relocs:\n")); - printf (_(" vaddr sec sz typ sym\n")); - ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr) - + ndsyms * sizeof (*ldsym)); - for (i = 0; i < ndrel; i++, ldrel++) - { - unsigned int rsize; - unsigned int rtype; - unsigned int symndx; - - rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0); - rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1); - - printf (_(" %08x %3u %c%c %2u "), - (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr), - (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm), - rsize & 0x80 ? 'S' : 'U', - rsize & 0x40 ? 'm' : ' ', - (rsize & 0x3f) + 1); - dump_value (rtype_xlat, rtype, 6); - symndx = bfd_h_get_32 (abfd, ldrel->l_symndx); - switch (symndx) - { - case 0: - printf (_(".text")); - break; - case 1: - printf (_(".data")); - break; - case 2: - printf (_(".bss")); - break; - default: - printf (_("%u"), symndx - 3); - break; - } - putchar ('\n'); - } - - printf (_("Import files:\n")); - p = (char *)ldr_data + impoff; - for (i = 0; i < nimpid; i++) - { - int n1, n2, n3; - - n1 = strlen (p); - n2 = strlen (p + n1 + 1); - n3 = strlen (p + n1 + 1 + n2+ 1); - printf (" %2u: %s,%s,%s\n", i, - p, p + n1 + 1, p + n1 + n2 + 2); - p += n1 + n2 + n3 + 3; - } - - free (ldr_data); -} - -/* Dump xcoff exception section. */ - -static void -dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data) -{ - asection *sec; - bfd_size_type size = 0; - bfd_byte *excp_data; - struct external_exceptab *exceptab; - unsigned int i; - - sec = bfd_get_section_by_name (abfd, ".except"); - - if (sec == NULL) - { - printf (_("no .except section in file\n")); - return; - } - size = bfd_get_section_size (sec); - excp_data = (bfd_byte *) xmalloc (size); - bfd_get_section_contents (abfd, sec, excp_data, 0, size); - exceptab = (struct external_exceptab *)excp_data; - - printf (_("Exception table:\n")); - printf (_("lang reason sym/addr\n")); - for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++) - { - unsigned int reason; - unsigned int addr; - - addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr); - reason = bfd_get_8 (abfd, exceptab->e_reason); - printf (_(" %02x %02x "), - (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason); - if (reason == 0) - xcoff32_print_symbol (data, addr); - else - printf (_("@%08x"), addr); - putchar ('\n'); - } - free (excp_data); -} - -/* Dump xcoff type-check section. */ - -static void -dump_xcoff32_typchk (bfd *abfd) -{ - asection *sec; - bfd_size_type size = 0; - bfd_byte *data; - unsigned int i; - - sec = bfd_get_section_by_name (abfd, ".typchk"); - - if (sec == NULL) - { - printf (_("no .typchk section in file\n")); - return; - } - size = bfd_get_section_size (sec); - data = (bfd_byte *) xmalloc (size); - bfd_get_section_contents (abfd, sec, data, 0, size); - - printf (_("Type-check section:\n")); - printf (_("offset len lang-id general-hash language-hash\n")); - for (i = 0; i < size;) - { - unsigned int len; - - len = bfd_get_16 (abfd, data + i); - printf ("%08x: %-4u ", i, len); - i += 2; - - if (len == 10) - { - /* Expected format. */ - printf ("%04x %08x %08x\n", - (unsigned) bfd_get_16 (abfd, data + i), - (unsigned) bfd_get_32 (abfd, data + i + 2), - (unsigned) bfd_get_32 (abfd, data + i + 2 + 4)); - } - else - { - unsigned int j; - - for (j = 0; j < len; j++) - { - if (j % 16 == 0) - printf ("\n "); - printf (" %02x", (unsigned char)data[i + j]); - } - putchar ('\n'); - } - i += len; - } - free (data); -} - -/* Dump xcoff traceback tags section. */ - -static void -dump_xcoff32_tbtags (bfd *abfd, - const char *text, bfd_size_type text_size, - unsigned int text_start, unsigned int func_start) -{ - unsigned int i; - - if (func_start - text_start > text_size) - { - printf (_(" address beyond section size\n")); - return; - } - for (i = func_start - text_start; i < text_size; i+= 4) - if (bfd_get_32 (abfd, text + i) == 0) - { - unsigned int tb1; - unsigned int tb2; - unsigned int off; - - printf (_(" tags at %08x\n"), i + 4); - if (i + 8 >= text_size) - goto truncated; - - tb1 = bfd_get_32 (abfd, text + i + 4); - tb2 = bfd_get_32 (abfd, text + i + 8); - off = i + 12; - printf (_(" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n"), - (tb1 >> 24) & 0xff, - (tb1 >> 16) & 0xff, - (tb1 >> 15) & 1, - (tb1 >> 14) & 1, - (tb1 >> 13) & 1, - (tb1 >> 12) & 1); - printf (_(" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n"), - (tb1 >> 11) & 1, - (tb1 >> 10) & 1, - (tb1 >> 9) & 1, - (tb1 >> 8) & 1, - (tb1 >> 7) & 1); - printf (_(" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n"), - (tb1 >> 6) & 1, - (tb1 >> 5) & 1, - (tb1 >> 2) & 7, - (tb1 >> 1) & 1, - (tb1 >> 0) & 1); - printf (_(" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n"), - (tb2 >> 31) & 1, - (tb2 >> 30) & 1, - (tb2 >> 24) & 63, - (tb2 >> 22) & 3, - (tb2 >> 16) & 63); - printf (_(" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n"), - (tb2 >> 8) & 0xff, - (tb2 >> 1) & 0x7f, - (tb2 >> 0) & 1); - - if (((tb2 >> 1) & 0x7fff) != 0) - { - unsigned int parminfo; - - if (off >= text_size) - goto truncated; - parminfo = bfd_get_32 (abfd, text + off); - off += 4; - printf (_(" parminfo: 0x%08x\n"), parminfo); - } - - if ((tb1 >> 13) & 1) - { - unsigned int tboff; - - if (off >= text_size) - goto truncated; - tboff = bfd_get_32 (abfd, text + off); - off += 4; - printf (_(" tb_offset: 0x%08x (start=0x%08x)\n"), - tboff, text_start + i - tboff); - } - if ((tb1 >> 7) & 1) - { - unsigned int hand_mask; - - if (off >= text_size) - goto truncated; - hand_mask = bfd_get_32 (abfd, text + off); - off += 4; - printf (_(" hand_mask_offset: 0x%08x\n"), hand_mask); - } - if ((tb1 >> 11) & 1) - { - unsigned int ctl_info; - unsigned int j; - - if (off >= text_size) - goto truncated; - ctl_info = bfd_get_32 (abfd, text + off); - off += 4; - printf (_(" number of CTL anchors: %u\n"), ctl_info); - for (j = 0; j < ctl_info; j++) - { - if (off >= text_size) - goto truncated; - printf (_(" CTL[%u]: %08x\n"), - j, (unsigned)bfd_get_32 (abfd, text + off)); - off += 4; - } - } - if ((tb1 >> 6) & 1) - { - unsigned int name_len; - unsigned int j; - - if (off >= text_size) - goto truncated; - name_len = bfd_get_16 (abfd, text + off); - off += 2; - printf (_(" Name (len: %u): "), name_len); - if (off + name_len >= text_size) - { - printf (_("[truncated]\n")); - goto truncated; - } - for (j = 0; j < name_len; j++) - if (ISPRINT (text[off + j])) - putchar (text[off + j]); - else - printf ("[%02x]", (unsigned char)text[off + j]); - putchar ('\n'); - off += name_len; - } - if ((tb1 >> 5) & 1) - { - if (off >= text_size) - goto truncated; - printf (_(" alloca reg: %u\n"), - (unsigned) bfd_get_8 (abfd, text + off)); - off++; - } - printf (_(" (end of tags at %08x)\n"), text_start + off); - return; - } - printf (_(" no tags found\n")); - return; - - truncated: - printf (_(" Truncated .text section\n")); - return; -} - -static void -dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - unsigned int scnum_text = -1; - unsigned int text_vma; - asection *text_sec; - bfd_size_type text_size; - char *text; - - if (data->syms == NULL || data->sects == NULL) - return; - - /* Read text section. */ - text_sec = bfd_get_section_by_name (abfd, ".text"); - if (text_sec == NULL) - return; - text_vma = bfd_get_section_vma (abfd, text_sec); - - text_size = bfd_get_section_size (text_sec); - text = (char *) xmalloc (text_size); - bfd_get_section_contents (abfd, text_sec, text, 0, text_size); - - for (i = 0; i < data->nscns; i++) - if (data->sects[i].flags == STYP_TEXT) - { - scnum_text = i + 1; - break; - } - if (scnum_text == (unsigned int)-1) - return; - - for (i = 0; i < data->nsyms; i++) - { - union xcoff32_symbol *s = &data->syms[i]; - - switch (s->sym.sclass) - { - case C_EXT: - case C_HIDEXT: - case C_WEAKEXT: - if (s->sym.scnum == scnum_text - && s->sym.numaux > 0) - { - union external_auxent *aux = &s[s->sym.numaux].aux; - - unsigned int smtyp; - unsigned int smclas; - - smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp); - smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas); - if (SMTYP_SMTYP (smtyp) == XTY_LD - && (smclas == XMC_PR - || smclas == XMC_GL - || smclas == XMC_XO)) - { - printf ("%08x: ", s->sym.val); - xcoff32_print_symbol (data, i); - putchar ('\n'); - dump_xcoff32_tbtags (abfd, text, text_size, - text_vma, s->sym.val); - } - } - break; - default: - break; - } - i += s->sym.numaux; - } - free (text); -} - -/* Dump the TOC symbols. */ - -static void -dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data) -{ - unsigned int i; - unsigned int nbr_ent; - unsigned int size; - - printf (_("TOC:\n")); - - if (data->syms == NULL) - return; - - nbr_ent = 0; - size = 0; - - for (i = 0; i < data->nsyms; i++) - { - union xcoff32_symbol *s = &data->syms[i]; - - switch (s->sym.sclass) - { - case C_EXT: - case C_HIDEXT: - case C_WEAKEXT: - if (s->sym.numaux > 0) - { - union external_auxent *aux = &s[s->sym.numaux].aux; - unsigned int smclas; - unsigned int ent_sz; - - smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas); - if (smclas == XMC_TC - || smclas == XMC_TD - || smclas == XMC_TC0) - { - ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen); - printf ("%08x %08x ", - s->sym.val, ent_sz); - xcoff32_print_symbol (data, i); - putchar ('\n'); - nbr_ent++; - size += ent_sz; - } - } - break; - default: - break; - } - i += s->sym.numaux; - } - printf (_("Nbr entries: %-8u Size: %08x (%u)\n"), - nbr_ent, size, size); -} - -/* Handle an rs6000 xcoff file. */ - -static void -dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr) -{ - struct xcoff_dump data; - - data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns); - data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr); - data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms); - data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr); - data.sects = NULL; - data.syms = NULL; - data.strings = NULL; - data.strings_size = 0; - - if (options[OPT_FILE_HEADER].selected) - dump_xcoff32_file_header (abfd, fhdr, &data); - - if (options[OPT_AOUT].selected) - dump_xcoff32_aout_header (abfd, &data); - - if (options[OPT_SYMS].selected - || options[OPT_RELOCS].selected - || options[OPT_LINENO].selected - || options[OPT_TRACEBACK].selected) - xcoff32_read_sections (abfd, &data); - - if (options[OPT_SECTIONS].selected) - dump_xcoff32_sections_header (abfd, &data); - - if (options[OPT_SYMS].selected - || options[OPT_RELOCS].selected - || options[OPT_LINENO].selected - || options[OPT_EXCEPT].selected - || options[OPT_TRACEBACK].selected - || options[OPT_TOC].selected) - xcoff32_read_symbols (abfd, &data); - - if (options[OPT_SYMS].selected) - dump_xcoff32_symbols (abfd, &data); - - if (options[OPT_RELOCS].selected) - dump_xcoff32_relocs (abfd, &data); - - if (options[OPT_LINENO].selected) - dump_xcoff32_lineno (abfd, &data); - - if (options[OPT_LOADER].selected) - dump_xcoff32_loader (abfd); - - if (options[OPT_EXCEPT].selected) - dump_xcoff32_except (abfd, &data); - - if (options[OPT_TYPCHK].selected) - dump_xcoff32_typchk (abfd); - - if (options[OPT_TRACEBACK].selected) - dump_xcoff32_traceback (abfd, &data); - - if (options[OPT_TOC].selected) - dump_xcoff32_toc (abfd, &data); - - free (data.sects); - free (data.strings); - free (data.syms); -} - -/* Dump ABFD (according to the options[] array). */ - -static void -xcoff_dump (bfd *abfd) -{ - struct external_filehdr fhdr; - unsigned short magic; - - /* Read file header. */ - if (bfd_seek (abfd, 0, SEEK_SET) != 0 - || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr)) - { - non_fatal (_("cannot read header")); - return; - } - - /* Decoding. We don't use the bfd/coff function to get all the fields. */ - magic = bfd_h_get_16 (abfd, fhdr.f_magic); - if (options[OPT_FILE_HEADER].selected) - { - printf (_("File header:\n")); - printf (_(" magic: 0x%04x (0%04o) "), magic, magic); - switch (magic) - { - case U802WRMAGIC: - printf (_("(WRMAGIC: writable text segments)")); - break; - case U802ROMAGIC: - printf (_("(ROMAGIC: readonly sharablee text segments)")); - break; - case U802TOCMAGIC: - printf (_("(TOCMAGIC: readonly text segments and TOC)")); - break; - default: - printf (_("unknown magic")); - } - putchar ('\n'); - } - if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC) - dump_xcoff32 (abfd, &fhdr); - else - printf (_(" Unhandled magic\n")); -} - -/* Vector for xcoff. */ - -const struct objdump_private_desc objdump_private_desc_xcoff = - { - xcoff_help, - xcoff_filter, - xcoff_dump, - options - }; diff --git a/contrib/binutils-2.22/binutils/prdbg.c b/contrib/binutils-2.22/binutils/prdbg.c deleted file mode 100644 index 091cefeada..0000000000 --- a/contrib/binutils-2.22/binutils/prdbg.c +++ /dev/null @@ -1,2838 +0,0 @@ -/* prdbg.c -- Print out generic debugging information. - Copyright 1995, 1996, 1999, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009, 2011 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - Tags style generation written by Salvador E. Tropea . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This file prints out the generic debugging information, by - supplying a set of routines to debug_write. */ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "libiberty.h" -#include "demangle.h" -#include "debug.h" -#include "budbg.h" - -/* This is the structure we use as a handle for these routines. */ - -struct pr_handle -{ - /* File to print information to. */ - FILE *f; - /* Current indentation level. */ - unsigned int indent; - /* Type stack. */ - struct pr_stack *stack; - /* Parameter number we are about to output. */ - int parameter; - /* The following are used only by the tags code (tg_). */ - /* Name of the file we are using. */ - char *filename; - /* The BFD. */ - bfd *abfd; - /* The symbols table for this BFD. */ - asymbol **syms; - /* Pointer to a function to demangle symbols. */ - char *(*demangler) (bfd *, const char *, int); -}; - -/* The type stack. */ - -struct pr_stack -{ - /* Next element on the stack. */ - struct pr_stack *next; - /* This element. */ - char *type; - /* Current visibility of fields if this is a class. */ - enum debug_visibility visibility; - /* Name of the current method we are handling. */ - const char *method; - /* The following are used only by the tags code (tg_). */ - /* Type for the container (struct, union, class, union class). */ - const char *flavor; - /* A comma separated list of parent classes. */ - char *parents; - /* How many parents contains parents. */ - int num_parents; -}; - -static void indent (struct pr_handle *); -static bfd_boolean push_type (struct pr_handle *, const char *); -static bfd_boolean prepend_type (struct pr_handle *, const char *); -static bfd_boolean append_type (struct pr_handle *, const char *); -static bfd_boolean substitute_type (struct pr_handle *, const char *); -static bfd_boolean indent_type (struct pr_handle *); -static char *pop_type (struct pr_handle *); -static void print_vma (bfd_vma, char *, bfd_boolean, bfd_boolean); -static bfd_boolean pr_fix_visibility - (struct pr_handle *, enum debug_visibility); -static bfd_boolean pr_start_compilation_unit (void *, const char *); -static bfd_boolean pr_start_source (void *, const char *); -static bfd_boolean pr_empty_type (void *); -static bfd_boolean pr_void_type (void *); -static bfd_boolean pr_int_type (void *, unsigned int, bfd_boolean); -static bfd_boolean pr_float_type (void *, unsigned int); -static bfd_boolean pr_complex_type (void *, unsigned int); -static bfd_boolean pr_bool_type (void *, unsigned int); -static bfd_boolean pr_enum_type - (void *, const char *, const char **, bfd_signed_vma *); -static bfd_boolean pr_pointer_type (void *); -static bfd_boolean pr_function_type (void *, int, bfd_boolean); -static bfd_boolean pr_reference_type (void *); -static bfd_boolean pr_range_type (void *, bfd_signed_vma, bfd_signed_vma); -static bfd_boolean pr_array_type - (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); -static bfd_boolean pr_set_type (void *, bfd_boolean); -static bfd_boolean pr_offset_type (void *); -static bfd_boolean pr_method_type (void *, bfd_boolean, int, bfd_boolean); -static bfd_boolean pr_const_type (void *); -static bfd_boolean pr_volatile_type (void *); -static bfd_boolean pr_start_struct_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int); -static bfd_boolean pr_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean pr_end_struct_type (void *); -static bfd_boolean pr_start_class_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int, - bfd_boolean, bfd_boolean); -static bfd_boolean pr_class_static_member - (void *, const char *, const char *, enum debug_visibility); -static bfd_boolean pr_class_baseclass - (void *, bfd_vma, bfd_boolean, enum debug_visibility); -static bfd_boolean pr_class_start_method (void *, const char *); -static bfd_boolean pr_class_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, - bfd_vma, bfd_boolean); -static bfd_boolean pr_class_static_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); -static bfd_boolean pr_class_end_method (void *); -static bfd_boolean pr_end_class_type (void *); -static bfd_boolean pr_typedef_type (void *, const char *); -static bfd_boolean pr_tag_type - (void *, const char *, unsigned int, enum debug_type_kind); -static bfd_boolean pr_typdef (void *, const char *); -static bfd_boolean pr_tag (void *, const char *); -static bfd_boolean pr_int_constant (void *, const char *, bfd_vma); -static bfd_boolean pr_float_constant (void *, const char *, double); -static bfd_boolean pr_typed_constant (void *, const char *, bfd_vma); -static bfd_boolean pr_variable - (void *, const char *, enum debug_var_kind, bfd_vma); -static bfd_boolean pr_start_function (void *, const char *, bfd_boolean); -static bfd_boolean pr_function_parameter - (void *, const char *, enum debug_parm_kind, bfd_vma); -static bfd_boolean pr_start_block (void *, bfd_vma); -static bfd_boolean pr_end_block (void *, bfd_vma); -static bfd_boolean pr_end_function (void *); -static bfd_boolean pr_lineno (void *, const char *, unsigned long, bfd_vma); -static bfd_boolean append_parent (struct pr_handle *, const char *); -/* Only used by tg_ code. */ -static bfd_boolean tg_fix_visibility - (struct pr_handle *, enum debug_visibility); -static void find_address_in_section (bfd *, asection *, void *); -static void translate_addresses (bfd *, char *, FILE *, asymbol **); -static const char *visibility_name (enum debug_visibility); -/* Tags style replacements. */ -static bfd_boolean tg_start_compilation_unit (void *, const char *); -static bfd_boolean tg_start_source (void *, const char *); -static bfd_boolean tg_enum_type - (void *, const char *, const char **, bfd_signed_vma *); -static bfd_boolean tg_start_struct_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int); -static bfd_boolean pr_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean tg_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean tg_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean tg_end_struct_type (void *); -static bfd_boolean tg_start_class_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, bfd_boolean); -static bfd_boolean tg_class_static_member - (void *, const char *, const char *, enum debug_visibility); -static bfd_boolean tg_class_baseclass - (void *, bfd_vma, bfd_boolean, enum debug_visibility); -static bfd_boolean tg_class_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean); -static bfd_boolean tg_class_static_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); -static bfd_boolean tg_end_class_type (void *); -static bfd_boolean tg_tag_type - (void *, const char *, unsigned int, enum debug_type_kind); -static bfd_boolean tg_typdef (void *, const char *); -static bfd_boolean tg_tag (void *, const char *); -static bfd_boolean tg_int_constant (void *, const char *, bfd_vma); -static bfd_boolean tg_float_constant (void *, const char *, double); -static bfd_boolean tg_typed_constant (void *, const char *, bfd_vma); -static bfd_boolean tg_variable - (void *, const char *, enum debug_var_kind, bfd_vma); -static bfd_boolean tg_start_function (void *, const char *, bfd_boolean); -static bfd_boolean tg_function_parameter - (void *, const char *, enum debug_parm_kind, bfd_vma); -static bfd_boolean tg_start_block (void *, bfd_vma); -static bfd_boolean tg_end_block (void *, bfd_vma); -static bfd_boolean tg_lineno (void *, const char *, unsigned long, bfd_vma); - -static const struct debug_write_fns pr_fns = -{ - pr_start_compilation_unit, - pr_start_source, - pr_empty_type, - pr_void_type, - pr_int_type, - pr_float_type, - pr_complex_type, - pr_bool_type, - pr_enum_type, - pr_pointer_type, - pr_function_type, - pr_reference_type, - pr_range_type, - pr_array_type, - pr_set_type, - pr_offset_type, - pr_method_type, - pr_const_type, - pr_volatile_type, - pr_start_struct_type, - pr_struct_field, - pr_end_struct_type, - pr_start_class_type, - pr_class_static_member, - pr_class_baseclass, - pr_class_start_method, - pr_class_method_variant, - pr_class_static_method_variant, - pr_class_end_method, - pr_end_class_type, - pr_typedef_type, - pr_tag_type, - pr_typdef, - pr_tag, - pr_int_constant, - pr_float_constant, - pr_typed_constant, - pr_variable, - pr_start_function, - pr_function_parameter, - pr_start_block, - pr_end_block, - pr_end_function, - pr_lineno -}; - -static const struct debug_write_fns tg_fns = -{ - tg_start_compilation_unit, - tg_start_source, - pr_empty_type, /* Same, push_type. */ - pr_void_type, /* Same, push_type. */ - pr_int_type, /* Same, push_type. */ - pr_float_type, /* Same, push_type. */ - pr_complex_type, /* Same, push_type. */ - pr_bool_type, /* Same, push_type. */ - tg_enum_type, - pr_pointer_type, /* Same, changes to pointer. */ - pr_function_type, /* Same, push_type. */ - pr_reference_type, /* Same, changes to reference. */ - pr_range_type, /* FIXME: What's that?. */ - pr_array_type, /* Same, push_type. */ - pr_set_type, /* FIXME: What's that?. */ - pr_offset_type, /* FIXME: What's that?. */ - pr_method_type, /* Same. */ - pr_const_type, /* Same, changes to const. */ - pr_volatile_type, /* Same, changes to volatile. */ - tg_start_struct_type, - tg_struct_field, - tg_end_struct_type, - tg_start_class_type, - tg_class_static_member, - tg_class_baseclass, - pr_class_start_method, /* Same, remembers that's a method. */ - tg_class_method_variant, - tg_class_static_method_variant, - pr_class_end_method, /* Same, forgets that's a method. */ - tg_end_class_type, - pr_typedef_type, /* Same, just push type. */ - tg_tag_type, - tg_typdef, - tg_tag, - tg_int_constant, /* Untested. */ - tg_float_constant, /* Untested. */ - tg_typed_constant, /* Untested. */ - tg_variable, - tg_start_function, - tg_function_parameter, - tg_start_block, - tg_end_block, - pr_end_function, /* Same, does nothing. */ - tg_lineno -}; - -/* Print out the generic debugging information recorded in dhandle. */ - -bfd_boolean -print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms, - void *demangler, bfd_boolean as_tags) -{ - struct pr_handle info; - - info.f = f; - info.indent = 0; - info.stack = NULL; - info.parameter = 0; - info.filename = NULL; - info.abfd = abfd; - info.syms = syms; - info.demangler = (char * (*)(struct bfd *, const char *, int)) demangler; - - if (as_tags) - { - fputs ("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f); - fputs ("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted/\n", f); - fputs ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t//\n", f); - fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f); - } - - return as_tags ? debug_write (dhandle, &tg_fns, (void *) & info) - : debug_write (dhandle, &pr_fns, (void *) & info); -} - -/* Indent to the current indentation level. */ - -static void -indent (struct pr_handle *info) -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - putc (' ', info->f); -} - -/* Push a type on the type stack. */ - -static bfd_boolean -push_type (struct pr_handle *info, const char *type) -{ - struct pr_stack *n; - - if (type == NULL) - return FALSE; - - n = (struct pr_stack *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = xstrdup (type); - n->visibility = DEBUG_VISIBILITY_IGNORE; - n->method = NULL; - n->next = info->stack; - info->stack = n; - - return TRUE; -} - -/* Prepend a string onto the type on the top of the type stack. */ - -static bfd_boolean -prepend_type (struct pr_handle *info, const char *s) -{ - char *n; - - assert (info->stack != NULL); - - n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1); - sprintf (n, "%s%s", s, info->stack->type); - free (info->stack->type); - info->stack->type = n; - - return TRUE; -} - -/* Append a string to the type on the top of the type stack. */ - -static bfd_boolean -append_type (struct pr_handle *info, const char *s) -{ - unsigned int len; - - if (s == NULL) - return FALSE; - - assert (info->stack != NULL); - - len = strlen (info->stack->type); - info->stack->type = (char *) xrealloc (info->stack->type, - len + strlen (s) + 1); - strcpy (info->stack->type + len, s); - - return TRUE; -} - -/* Append a string to the parents on the top of the type stack. */ - -static bfd_boolean -append_parent (struct pr_handle *info, const char *s) -{ - unsigned int len; - - if (s == NULL) - return FALSE; - - assert (info->stack != NULL); - - len = info->stack->parents ? strlen (info->stack->parents) : 0; - info->stack->parents = (char *) xrealloc (info->stack->parents, - len + strlen (s) + 1); - strcpy (info->stack->parents + len, s); - - return TRUE; -} - -/* We use an underscore to indicate where the name should go in a type - string. This function substitutes a string for the underscore. If - there is no underscore, the name follows the type. */ - -static bfd_boolean -substitute_type (struct pr_handle *info, const char *s) -{ - char *u; - - assert (info->stack != NULL); - - u = strchr (info->stack->type, '|'); - if (u != NULL) - { - char *n; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (s)); - - memcpy (n, info->stack->type, u - info->stack->type); - strcpy (n + (u - info->stack->type), s); - strcat (n, u + 1); - - free (info->stack->type); - info->stack->type = n; - - return TRUE; - } - - if (strchr (s, '|') != NULL - && (strchr (info->stack->type, '{') != NULL - || strchr (info->stack->type, '(') != NULL)) - { - if (! prepend_type (info, "(") - || ! append_type (info, ")")) - return FALSE; - } - - if (*s == '\0') - return TRUE; - - return (append_type (info, " ") - && append_type (info, s)); -} - -/* Indent the type at the top of the stack by appending spaces. */ - -static bfd_boolean -indent_type (struct pr_handle *info) -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - { - if (! append_type (info, " ")) - return FALSE; - } - - return TRUE; -} - -/* Pop a type from the type stack. */ - -static char * -pop_type (struct pr_handle *info) -{ - struct pr_stack *o; - char *ret; - - assert (info->stack != NULL); - - o = info->stack; - info->stack = o->next; - ret = o->type; - free (o); - - return ret; -} - -/* Print a VMA value into a string. */ - -static void -print_vma (bfd_vma vma, char *buf, bfd_boolean unsignedp, bfd_boolean hexp) -{ - if (sizeof (vma) <= sizeof (unsigned long)) - { - if (hexp) - sprintf (buf, "0x%lx", (unsigned long) vma); - else if (unsignedp) - sprintf (buf, "%lu", (unsigned long) vma); - else - sprintf (buf, "%ld", (long) vma); - } -#if BFD_HOST_64BIT_LONG_LONG - else if (sizeof (vma) <= sizeof (unsigned long long)) - { -#ifndef __MSVCRT__ - if (hexp) - sprintf (buf, "0x%llx", (unsigned long long) vma); - else if (unsignedp) - sprintf (buf, "%llu", (unsigned long long) vma); - else - sprintf (buf, "%lld", (long long) vma); -#else - if (hexp) - sprintf (buf, "0x%I64x", (unsigned long long) vma); - else if (unsignedp) - sprintf (buf, "%I64u", (unsigned long long) vma); - else - sprintf (buf, "%I64d", (long long) vma); -#endif - } -#endif - else - { - buf[0] = '0'; - buf[1] = 'x'; - sprintf_vma (buf + 2, vma); - } -} - -/* Start a new compilation unit. */ - -static bfd_boolean -pr_start_compilation_unit (void *p, const char *filename) -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); - - fprintf (info->f, "%s:\n", filename); - - return TRUE; -} - -/* Start a source file within a compilation unit. */ - -static bfd_boolean -pr_start_source (void *p, const char *filename) -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); - - fprintf (info->f, " %s:\n", filename); - - return TRUE; -} - -/* Push an empty type onto the type stack. */ - -static bfd_boolean -pr_empty_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, ""); -} - -/* Push a void type onto the type stack. */ - -static bfd_boolean -pr_void_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, "void"); -} - -/* Push an integer type onto the type stack. */ - -static bfd_boolean -pr_int_type (void *p, unsigned int size, bfd_boolean unsignedp) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8); - return push_type (info, ab); -} - -/* Push a floating type onto the type stack. */ - -static bfd_boolean -pr_float_type (void *p, unsigned int size) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - if (size == 4) - return push_type (info, "float"); - else if (size == 8) - return push_type (info, "double"); - - sprintf (ab, "float%d", size * 8); - return push_type (info, ab); -} - -/* Push a complex type onto the type stack. */ - -static bfd_boolean -pr_complex_type (void *p, unsigned int size) -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! pr_float_type (p, size)) - return FALSE; - - return prepend_type (info, "complex "); -} - -/* Push a bfd_boolean type onto the type stack. */ - -static bfd_boolean -pr_bool_type (void *p, unsigned int size) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "bool%d", size * 8); - - return push_type (info, ab); -} - -/* Push an enum type onto the type stack. */ - -static bfd_boolean -pr_enum_type (void *p, const char *tag, const char **names, - bfd_signed_vma *values) -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int i; - bfd_signed_vma val; - - if (! push_type (info, "enum ")) - return FALSE; - if (tag != NULL) - { - if (! append_type (info, tag) - || ! append_type (info, " ")) - return FALSE; - } - if (! append_type (info, "{ ")) - return FALSE; - - if (names == NULL) - { - if (! append_type (info, "/* undefined */")) - return FALSE; - } - else - { - val = 0; - for (i = 0; names[i] != NULL; i++) - { - if (i > 0) - { - if (! append_type (info, ", ")) - return FALSE; - } - - if (! append_type (info, names[i])) - return FALSE; - - if (values[i] != val) - { - char ab[20]; - - print_vma (values[i], ab, FALSE, FALSE); - if (! append_type (info, " = ") - || ! append_type (info, ab)) - return FALSE; - val = values[i]; - } - - ++val; - } - } - - return append_type (info, " }"); -} - -/* Turn the top type on the stack into a pointer. */ - -static bfd_boolean -pr_pointer_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - - s = strchr (info->stack->type, '|'); - if (s != NULL && s[1] == '[') - return substitute_type (info, "(*|)"); - return substitute_type (info, "*|"); -} - -/* Turn the top type on the stack into a function returning that type. */ - -static bfd_boolean -pr_function_type (void *p, int argcount, bfd_boolean varargs) -{ - struct pr_handle *info = (struct pr_handle *) p; - char **arg_types; - unsigned int len; - char *s; - - assert (info->stack != NULL); - - len = 10; - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - { - free (arg_types); - return FALSE; - } - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - { - free (arg_types); - return FALSE; - } - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - LITSTRCPY (s, "(|) ("); - - if (argcount < 0) - strcat (s, "/* unknown */"); - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return FALSE; - - free (s); - - return TRUE; -} - -/* Turn the top type on the stack into a reference to that type. */ - -static bfd_boolean -pr_reference_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - - return substitute_type (info, "&|"); -} - -/* Make a range type. */ - -static bfd_boolean -pr_range_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper) -{ - struct pr_handle *info = (struct pr_handle *) p; - char abl[20], abu[20]; - - assert (info->stack != NULL); - - if (! substitute_type (info, "")) - return FALSE; - - print_vma (lower, abl, FALSE, FALSE); - print_vma (upper, abu, FALSE, FALSE); - - return (prepend_type (info, "range (") - && append_type (info, "):") - && append_type (info, abl) - && append_type (info, ":") - && append_type (info, abu)); -} - -/* Make an array type. */ - -static bfd_boolean -pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper, - bfd_boolean stringp) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *range_type; - char abl[20], abu[20], ab[50]; - - range_type = pop_type (info); - if (range_type == NULL) - return FALSE; - - if (lower == 0) - { - if (upper == -1) - sprintf (ab, "|[]"); - else - { - print_vma (upper + 1, abu, FALSE, FALSE); - sprintf (ab, "|[%s]", abu); - } - } - else - { - print_vma (lower, abl, FALSE, FALSE); - print_vma (upper, abu, FALSE, FALSE); - sprintf (ab, "|[%s:%s]", abl, abu); - } - - if (! substitute_type (info, ab)) - return FALSE; - - if (strcmp (range_type, "int") != 0) - { - if (! append_type (info, ":") - || ! append_type (info, range_type)) - return FALSE; - } - - if (stringp) - { - if (! append_type (info, " /* string */")) - return FALSE; - } - - return TRUE; -} - -/* Make a set type. */ - -static bfd_boolean -pr_set_type (void *p, bfd_boolean bitstringp) -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! substitute_type (info, "")) - return FALSE; - - if (! prepend_type (info, "set { ") - || ! append_type (info, " }")) - return FALSE; - - if (bitstringp) - { - if (! append_type (info, "/* bitstring */")) - return FALSE; - } - - return TRUE; -} - -/* Make an offset type. */ - -static bfd_boolean -pr_offset_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, "")) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - return (substitute_type (info, "") - && prepend_type (info, " ") - && prepend_type (info, t) - && append_type (info, "::|")); -} - -/* Make a method type. */ - -static bfd_boolean -pr_method_type (void *p, bfd_boolean domain, int argcount, bfd_boolean varargs) -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int len; - char *domain_type; - char **arg_types; - char *s; - - len = 10; - - if (! domain) - domain_type = NULL; - else - { - if (! substitute_type (info, "")) - return FALSE; - domain_type = pop_type (info); - if (domain_type == NULL) - return FALSE; - if (CONST_STRNEQ (domain_type, "class ") - && strchr (domain_type + sizeof "class " - 1, ' ') == NULL) - domain_type += sizeof "class " - 1; - else if (CONST_STRNEQ (domain_type, "union class ") - && (strchr (domain_type + sizeof "union class " - 1, ' ') - == NULL)) - domain_type += sizeof "union class " - 1; - len += strlen (domain_type); - } - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - { - free (arg_types); - return FALSE; - } - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - { - free (arg_types); - return FALSE; - } - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - if (! domain) - *s = '\0'; - else - strcpy (s, domain_type); - strcat (s, "::| ("); - - if (argcount < 0) - strcat (s, "/* unknown */"); - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return FALSE; - - free (s); - - return TRUE; -} - -/* Make a const qualified type. */ - -static bfd_boolean -pr_const_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "const |"); -} - -/* Make a volatile qualified type. */ - -static bfd_boolean -pr_volatile_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "volatile |"); -} - -/* Start accumulating a struct type. */ - -static bfd_boolean -pr_start_struct_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size) -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->indent += 2; - - if (! push_type (info, structp ? "struct " : "union ")) - return FALSE; - if (tag != NULL) - { - if (! append_type (info, tag)) - return FALSE; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return FALSE; - } - - if (! append_type (info, " {")) - return FALSE; - if (size != 0 || tag != NULL) - { - char ab[30]; - - if (! append_type (info, " /*")) - return FALSE; - - if (size != 0) - { - sprintf (ab, " size %u", size); - if (! append_type (info, ab)) - return FALSE; - } - if (tag != NULL) - { - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return FALSE; - } - if (! append_type (info, " */")) - return FALSE; - } - if (! append_type (info, "\n")) - return FALSE; - - info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; - - return indent_type (info); -} - -/* Output the visibility of a field in a struct. */ - -static bfd_boolean -pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility) -{ - const char *s = NULL; - char *t; - unsigned int len; - - assert (info->stack != NULL); - - if (info->stack->visibility == visibility) - return TRUE; - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - s = "public"; - break; - case DEBUG_VISIBILITY_PRIVATE: - s = "private"; - break; - case DEBUG_VISIBILITY_PROTECTED: - s = "protected"; - break; - case DEBUG_VISIBILITY_IGNORE: - s = "/* ignore */"; - break; - default: - abort (); - return FALSE; - } - - /* Trim off a trailing space in the struct string, to make the - output look a bit better, then stick on the visibility string. */ - - t = info->stack->type; - len = strlen (t); - assert (t[len - 1] == ' '); - t[len - 1] = '\0'; - - if (! append_type (info, s) - || ! append_type (info, ":\n") - || ! indent_type (info)) - return FALSE; - - info->stack->visibility = visibility; - - return TRUE; -} - -/* Add a field to a struct type. */ - -static bfd_boolean -pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize, - enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - char *t; - - if (! substitute_type (info, name)) - return FALSE; - - if (! append_type (info, "; /* ")) - return FALSE; - - if (bitsize != 0) - { - print_vma (bitsize, ab, TRUE, FALSE); - if (! append_type (info, "bitsize ") - || ! append_type (info, ab) - || ! append_type (info, ", ")) - return FALSE; - } - - print_vma (bitpos, ab, TRUE, FALSE); - if (! append_type (info, "bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (! pr_fix_visibility (info, visibility)) - return FALSE; - - return append_type (info, t); -} - -/* Finish a struct type. */ - -static bfd_boolean -pr_end_struct_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - assert (info->indent >= 2); - - info->indent -= 2; - - /* Change the trailing indentation to have a close brace. */ - s = info->stack->type + strlen (info->stack->type) - 2; - assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); - - *s++ = '}'; - *s = '\0'; - - return TRUE; -} - -/* Start a class type. */ - -static bfd_boolean -pr_start_class_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size, - bfd_boolean vptr, bfd_boolean ownvptr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *tv = NULL; - - info->indent += 2; - - if (vptr && ! ownvptr) - { - tv = pop_type (info); - if (tv == NULL) - return FALSE; - } - - if (! push_type (info, structp ? "class " : "union class ")) - return FALSE; - if (tag != NULL) - { - if (! append_type (info, tag)) - return FALSE; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return FALSE; - } - - if (! append_type (info, " {")) - return FALSE; - if (size != 0 || vptr || ownvptr || tag != NULL) - { - if (! append_type (info, " /*")) - return FALSE; - - if (size != 0) - { - char ab[20]; - - sprintf (ab, "%u", size); - if (! append_type (info, " size ") - || ! append_type (info, ab)) - return FALSE; - } - - if (vptr) - { - if (! append_type (info, " vtable ")) - return FALSE; - if (ownvptr) - { - if (! append_type (info, "self ")) - return FALSE; - } - else - { - if (! append_type (info, tv) - || ! append_type (info, " ")) - return FALSE; - } - } - - if (tag != NULL) - { - char ab[30]; - - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return FALSE; - } - - if (! append_type (info, " */")) - return FALSE; - } - - info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; - - return (append_type (info, "\n") - && indent_type (info)); -} - -/* Add a static member to a class. */ - -static bfd_boolean -pr_class_static_member (void *p, const char *name, const char *physname, - enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return FALSE; - - if (! prepend_type (info, "static ") - || ! append_type (info, "; /* ") - || ! append_type (info, physname) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (! pr_fix_visibility (info, visibility)) - return FALSE; - - return append_type (info, t); -} - -/* Add a base class to a class. */ - -static bfd_boolean -pr_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean is_virtual, - enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - const char *prefix; - char ab[20]; - char *s, *l, *n; - - assert (info->stack != NULL && info->stack->next != NULL); - - if (! substitute_type (info, "")) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (CONST_STRNEQ (t, "class ")) - t += sizeof "class " - 1; - - /* Push it back on to take advantage of the prepend_type and - append_type routines. */ - if (! push_type (info, t)) - return FALSE; - - if (is_virtual) - { - if (! prepend_type (info, "virtual ")) - return FALSE; - } - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - prefix = "public "; - break; - case DEBUG_VISIBILITY_PROTECTED: - prefix = "protected "; - break; - case DEBUG_VISIBILITY_PRIVATE: - prefix = "private "; - break; - default: - prefix = "/* unknown visibility */ "; - break; - } - - if (! prepend_type (info, prefix)) - return FALSE; - - if (bitpos != 0) - { - print_vma (bitpos, ab, TRUE, FALSE); - if (! append_type (info, " /* bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */")) - return FALSE; - } - - /* Now the top of the stack is something like "public A / * bitpos - 10 * /". The next element on the stack is something like "class - xx { / * size 8 * /\n...". We want to substitute the top of the - stack in before the {. */ - s = strchr (info->stack->next->type, '{'); - assert (s != NULL); - --s; - - /* If there is already a ':', then we already have a baseclass, and - we must append this one after a comma. */ - for (l = info->stack->next->type; l != s; l++) - if (*l == ':') - break; - if (! prepend_type (info, l == s ? " : " : ", ")) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1); - memcpy (n, info->stack->type, s - info->stack->type); - strcpy (n + (s - info->stack->type), t); - strcat (n, s); - - free (info->stack->type); - info->stack->type = n; - - free (t); - - return TRUE; -} - -/* Start adding a method to a class. */ - -static bfd_boolean -pr_class_start_method (void *p, const char *name) -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - info->stack->method = name; - return TRUE; -} - -/* Add a variant to a method. */ - -static bfd_boolean -pr_class_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep, - bfd_vma voffset, bfd_boolean context) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - char *context_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return FALSE; - } - if (constp) - { - if (! append_type (info, " const")) - return FALSE; - } - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, - (context - ? info->stack->next->next->method - : info->stack->next->method))) - return FALSE; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return FALSE; - - /* Pull off the context type if there is one. */ - if (! context) - context_type = NULL; - else - { - context_type = pop_type (info); - if (context_type == NULL) - return FALSE; - } - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return FALSE; - - if (! append_type (info, method_type) - || ! append_type (info, " /* ") - || ! append_type (info, physname) - || ! append_type (info, " ")) - return FALSE; - if (context || voffset != 0) - { - char ab[20]; - - if (context) - { - if (! append_type (info, "context ") - || ! append_type (info, context_type) - || ! append_type (info, " ")) - return FALSE; - } - print_vma (voffset, ab, TRUE, FALSE); - if (! append_type (info, "voffset ") - || ! append_type (info, ab)) - return FALSE; - } - - return (append_type (info, " */;\n") - && indent_type (info)); -} - -/* Add a static variant to a method. */ - -static bfd_boolean -pr_class_static_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - assert (info->stack->next->method != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return FALSE; - } - if (constp) - { - if (! append_type (info, " const")) - return FALSE; - } - - /* Mark it as static. */ - if (! prepend_type (info, "static ")) - return FALSE; - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, info->stack->next->method)) - return FALSE; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return FALSE; - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return FALSE; - - return (append_type (info, method_type) - && append_type (info, " /* ") - && append_type (info, physname) - && append_type (info, " */;\n") - && indent_type (info)); -} - -/* Finish up a method. */ - -static bfd_boolean -pr_class_end_method (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->stack->method = NULL; - return TRUE; -} - -/* Finish up a class. */ - -static bfd_boolean -pr_end_class_type (void *p) -{ - return pr_end_struct_type (p); -} - -/* Push a type on the stack using a typedef name. */ - -static bfd_boolean -pr_typedef_type (void *p, const char *name) -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, name); -} - -/* Push a type on the stack using a tag name. */ - -static bfd_boolean -pr_tag_type (void *p, const char *name, unsigned int id, - enum debug_type_kind kind) -{ - struct pr_handle *info = (struct pr_handle *) p; - const char *t, *tag; - char idbuf[20]; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - t = "struct "; - break; - case DEBUG_KIND_UNION: - t = "union "; - break; - case DEBUG_KIND_ENUM: - t = "enum "; - break; - case DEBUG_KIND_CLASS: - t = "class "; - break; - case DEBUG_KIND_UNION_CLASS: - t = "union class "; - break; - default: - abort (); - return FALSE; - } - - if (! push_type (info, t)) - return FALSE; - if (name != NULL) - tag = name; - else - { - sprintf (idbuf, "%%anon%u", id); - tag = idbuf; - } - - if (! append_type (info, tag)) - return FALSE; - if (name != NULL && kind != DEBUG_KIND_ENUM) - { - sprintf (idbuf, " /* id %u */", id); - if (! append_type (info, idbuf)) - return FALSE; - } - - return TRUE; -} - -/* Output a typedef. */ - -static bfd_boolean -pr_typdef (void *p, const char *name) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - if (! substitute_type (info, name)) - return FALSE; - - s = pop_type (info); - if (s == NULL) - return FALSE; - - indent (info); - fprintf (info->f, "typedef %s;\n", s); - - free (s); - - return TRUE; -} - -/* Output a tag. The tag should already be in the string on the - stack, so all we have to do here is print it out. */ - -static bfd_boolean -pr_tag (void *p, const char *name ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - indent (info); - fprintf (info->f, "%s;\n", t); - - free (t); - - return TRUE; -} - -/* Output an integer constant. */ - -static bfd_boolean -pr_int_constant (void *p, const char *name, bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - - indent (info); - print_vma (val, ab, FALSE, FALSE); - fprintf (info->f, "const int %s = %s;\n", name, ab); - return TRUE; -} - -/* Output a floating point constant. */ - -static bfd_boolean -pr_float_constant (void *p, const char *name, double val) -{ - struct pr_handle *info = (struct pr_handle *) p; - - indent (info); - fprintf (info->f, "const double %s = %g;\n", name, val); - return TRUE; -} - -/* Output a typed constant. */ - -static bfd_boolean -pr_typed_constant (void *p, const char *name, bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - indent (info); - print_vma (val, ab, FALSE, FALSE); - fprintf (info->f, "const %s %s = %s;\n", t, name, ab); - - free (t); - - return TRUE; -} - -/* Output a variable. */ - -static bfd_boolean -pr_variable (void *p, const char *name, enum debug_var_kind kind, - bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - - if (! substitute_type (info, name)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - indent (info); - switch (kind) - { - case DEBUG_STATIC: - case DEBUG_LOCAL_STATIC: - fprintf (info->f, "static "); - break; - case DEBUG_REGISTER: - fprintf (info->f, "register "); - break; - default: - break; - } - print_vma (val, ab, TRUE, TRUE); - fprintf (info->f, "%s /* %s */;\n", t, ab); - - free (t); - - return TRUE; -} - -/* Start outputting a function. */ - -static bfd_boolean -pr_start_function (void *p, const char *name, bfd_boolean global) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - indent (info); - if (! global) - fprintf (info->f, "static "); - fprintf (info->f, "%s (", t); - - info->parameter = 1; - - return TRUE; -} - -/* Output a function parameter. */ - -static bfd_boolean -pr_function_parameter (void *p, const char *name, - enum debug_parm_kind kind, bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - - if (kind == DEBUG_PARM_REFERENCE - || kind == DEBUG_PARM_REF_REG) - { - if (! pr_reference_type (p)) - return FALSE; - } - - if (! substitute_type (info, name)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (info->parameter != 1) - fprintf (info->f, ", "); - - if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) - fprintf (info->f, "register "); - - print_vma (val, ab, TRUE, TRUE); - fprintf (info->f, "%s /* %s */", t, ab); - - free (t); - - ++info->parameter; - - return TRUE; -} - -/* Start writing out a block. */ - -static bfd_boolean -pr_start_block (void *p, bfd_vma addr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - - if (info->parameter > 0) - { - fprintf (info->f, ")\n"); - info->parameter = 0; - } - - indent (info); - print_vma (addr, ab, TRUE, TRUE); - fprintf (info->f, "{ /* %s */\n", ab); - - info->indent += 2; - - return TRUE; -} - -/* Write out line number information. */ - -static bfd_boolean -pr_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - - indent (info); - print_vma (addr, ab, TRUE, TRUE); - fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab); - - return TRUE; -} - -/* Finish writing out a block. */ - -static bfd_boolean -pr_end_block (void *p, bfd_vma addr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - - info->indent -= 2; - - indent (info); - print_vma (addr, ab, TRUE, TRUE); - fprintf (info->f, "} /* %s */\n", ab); - - return TRUE; -} - -/* Finish writing out a function. */ - -static bfd_boolean -pr_end_function (void *p ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Tags style generation functions start here. */ - -/* Variables for address to line translation. */ -static bfd_vma pc; -static const char *filename; -static const char *functionname; -static unsigned int line; -static bfd_boolean found; - -/* Look for an address in a section. This is called via - bfd_map_over_sections. */ - -static void -find_address_in_section (bfd *abfd, asection *section, void *data) -{ - bfd_vma vma; - bfd_size_type size; - asymbol **syms = (asymbol **) data; - - if (found) - return; - - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) - return; - - vma = bfd_get_section_vma (abfd, section); - if (pc < vma) - return; - - size = bfd_get_section_size (section); - if (pc >= vma + size) - return; - - found = bfd_find_nearest_line (abfd, section, syms, pc - vma, - &filename, &functionname, &line); -} - -static void -translate_addresses (bfd *abfd, char *addr_hex, FILE *f, asymbol **syms) -{ - pc = bfd_scan_vma (addr_hex, NULL, 16); - found = FALSE; - bfd_map_over_sections (abfd, find_address_in_section, syms); - - if (! found) - fprintf (f, "??"); - else - fprintf (f, "%u", line); -} - -/* Start a new compilation unit. */ - -static bfd_boolean -tg_start_compilation_unit (void * p, const char *fname ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - - free (info->filename); - /* Should it be relative? best way to do it here?. */ - info->filename = strdup (fname); - - return TRUE; -} - -/* Start a source file within a compilation unit. */ - -static bfd_boolean -tg_start_source (void *p, const char *fname) -{ - struct pr_handle *info = (struct pr_handle *) p; - - free (info->filename); - /* Should it be relative? best way to do it here?. */ - info->filename = strdup (fname); - - return TRUE; -} - -/* Push an enum type onto the type stack. */ - -static bfd_boolean -tg_enum_type (void *p, const char *tag, const char **names, - bfd_signed_vma *values) -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int i; - const char *name; - char ab[20]; - - if (! pr_enum_type (p, tag, names, values)) - return FALSE; - - name = tag ? tag : "unknown"; - /* Generate an entry for the enum. */ - if (tag) - fprintf (info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag, - info->filename, info->stack->type); - - /* Generate entries for the values. */ - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - print_vma (values[i], ab, FALSE, FALSE); - fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n", - names[i], info->filename, name, ab); - } - } - - return TRUE; -} - -/* Start accumulating a struct type. */ - -static bfd_boolean -tg_start_struct_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, - unsigned int size ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - const char *name; - char idbuf[20]; - - if (tag != NULL) - name = tag; - else - { - name = idbuf; - sprintf (idbuf, "%%anon%u", id); - } - - if (! push_type (info, name)) - return FALSE; - - info->stack->flavor = structp ? "struct" : "union"; - - fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename, - info->stack->flavor[0]); - - info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; - - return indent_type (info); -} - -/* Output the visibility of a field in a struct. */ - -static bfd_boolean -tg_fix_visibility (struct pr_handle *info, enum debug_visibility visibility) -{ - assert (info->stack != NULL); - - if (info->stack->visibility == visibility) - return TRUE; - - assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE); - - info->stack->visibility = visibility; - - return TRUE; -} - -/* Add a field to a struct type. */ - -static bfd_boolean -tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED, - bfd_vma bitsize ATTRIBUTE_UNUSED, - enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (! tg_fix_visibility (info, visibility)) - return FALSE; - - /* It happens, a bug? */ - if (! name[0]) - return TRUE; - - fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n", - name, info->filename, t, info->stack->flavor, info->stack->type, - visibility_name (visibility)); - - return TRUE; -} - -/* Finish a struct type. */ - -static bfd_boolean -tg_end_struct_type (void *p ATTRIBUTE_UNUSED) -{ - assert (((struct pr_handle *) p)->stack != NULL); - - return TRUE; -} - -/* Start a class type. */ - -static bfd_boolean -tg_start_class_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size, - bfd_boolean vptr, bfd_boolean ownvptr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *tv = NULL; - const char *name; - - info->indent += 2; - - if (vptr && ! ownvptr) - { - tv = pop_type (info); - if (tv == NULL) - return FALSE; - } - - if (tag != NULL) - name = tag; - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - name = idbuf; - } - - if (! push_type (info, name)) - return FALSE; - - info->stack->flavor = structp ? "class" : "union class"; - info->stack->parents = NULL; - info->stack->num_parents = 0; - - if (size != 0 || vptr || ownvptr || tag != NULL) - { - if (vptr) - { - if (! append_type (info, " vtable ")) - return FALSE; - if (ownvptr) - { - if (! append_type (info, "self ")) - return FALSE; - } - else - { - if (! append_type (info, tv) - || ! append_type (info, " ")) - return FALSE; - } - } - } - - info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; - - return TRUE; -} - -/* Add a static member to a class. */ - -static bfd_boolean -tg_class_static_member (void *p, const char *name, - const char *physname ATTRIBUTE_UNUSED, - enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - int len_var, len_class; - char *full_name; - - len_var = strlen (name); - len_class = strlen (info->stack->next->type); - full_name = (char *) xmalloc (len_var + len_class + 3); - if (! full_name) - return FALSE; - sprintf (full_name, "%s::%s", info->stack->next->type, name); - - if (! substitute_type (info, full_name)) - { - free (full_name); - return FALSE; - } - - if (! prepend_type (info, "static ")) - { - free (full_name); - return FALSE; - } - - t = pop_type (info); - if (t == NULL) - { - free (full_name); - return FALSE; - } - - if (! tg_fix_visibility (info, visibility)) - { - free (t); - free (full_name); - return FALSE; - } - - fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n", - name, info->filename, t, info->stack->type, - visibility_name (visibility)); - free (t); - free (full_name); - - return TRUE; -} - -/* Add a base class to a class. */ - -static bfd_boolean -tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED, - bfd_boolean is_virtual, enum debug_visibility visibility) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - const char *prefix; - - assert (info->stack != NULL && info->stack->next != NULL); - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (CONST_STRNEQ (t, "class ")) - t += sizeof "class " - 1; - - /* Push it back on to take advantage of the prepend_type and - append_type routines. */ - if (! push_type (info, t)) - return FALSE; - - if (is_virtual) - { - if (! prepend_type (info, "virtual ")) - return FALSE; - } - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - prefix = "public "; - break; - case DEBUG_VISIBILITY_PROTECTED: - prefix = "protected "; - break; - case DEBUG_VISIBILITY_PRIVATE: - prefix = "private "; - break; - default: - prefix = "/* unknown visibility */ "; - break; - } - - if (! prepend_type (info, prefix)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (info->stack->num_parents && ! append_parent (info, ", ")) - return FALSE; - - if (! append_parent (info, t)) - return FALSE; - info->stack->num_parents++; - - free (t); - - return TRUE; -} - -/* Add a variant to a method. */ - -static bfd_boolean -tg_class_method_variant (void *p, const char *physname ATTRIBUTE_UNUSED, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep, - bfd_vma voffset ATTRIBUTE_UNUSED, - bfd_boolean context) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - char *context_type; - char *method_name; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return FALSE; - } - if (constp) - { - if (! append_type (info, " const")) - return FALSE; - } - - method_name = strdup (context ? info->stack->next->next->method - : info->stack->next->method); - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, method_name)) - { - free (method_name); - return FALSE; - } - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - { - free (method_name); - return FALSE; - } - - /* Pull off the context type if there is one. */ - if (! context) - context_type = NULL; - else - { - context_type = pop_type (info); - if (context_type == NULL) - { - free (method_type); - free (method_name); - return FALSE; - } - } - - /* Now the top of the stack is the class. */ - if (! tg_fix_visibility (info, visibility)) - { - free (method_type); - free (method_name); - free (context_type); - return FALSE; - } - - fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n", - method_name, info->filename, method_type, info->stack->type); - free (method_type); - free (method_name); - free (context_type); - - return TRUE; -} - -/* Add a static variant to a method. */ - -static bfd_boolean -tg_class_static_method_variant (void *p, - const char *physname ATTRIBUTE_UNUSED, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - char *method_name; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - assert (info->stack->next->method != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return FALSE; - } - if (constp) - { - if (! append_type (info, " const")) - return FALSE; - } - - /* Mark it as static. */ - if (! prepend_type (info, "static ")) - return FALSE; - - method_name = strdup (info->stack->next->method); - /* Stick the name of the method into its type. */ - if (! substitute_type (info, info->stack->next->method)) - { - free (method_name); - return FALSE; - } - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - { - free (method_name); - return FALSE; - } - - /* Now the top of the stack is the class. */ - if (! tg_fix_visibility (info, visibility)) - { - free (method_type); - free (method_name); - return FALSE; - } - - fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n", - method_name, info->filename, method_type, info->stack->type, - visibility_name (visibility)); - free (method_type); - free (method_name); - - return TRUE; -} - -/* Finish up a class. */ - -static bfd_boolean -tg_end_class_type (void *p) -{ - struct pr_handle *info = (struct pr_handle *) p; - - fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type, - info->filename, info->stack->flavor); - if (info->stack->num_parents) - { - fprintf (info->f, "\tinherits:%s", info->stack->parents); - free (info->stack->parents); - } - fputc ('\n', info->f); - - return tg_end_struct_type (p); -} - -/* Push a type on the stack using a tag name. */ - -static bfd_boolean -tg_tag_type (void *p, const char *name, unsigned int id, - enum debug_type_kind kind) -{ - struct pr_handle *info = (struct pr_handle *) p; - const char *t, *tag; - char idbuf[20]; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - t = "struct "; - break; - case DEBUG_KIND_UNION: - t = "union "; - break; - case DEBUG_KIND_ENUM: - t = "enum "; - break; - case DEBUG_KIND_CLASS: - t = "class "; - break; - case DEBUG_KIND_UNION_CLASS: - t = "union class "; - break; - default: - abort (); - return FALSE; - } - - if (! push_type (info, t)) - return FALSE; - if (name != NULL) - tag = name; - else - { - sprintf (idbuf, "%%anon%u", id); - tag = idbuf; - } - - if (! append_type (info, tag)) - return FALSE; - - return TRUE; -} - -/* Output a typedef. */ - -static bfd_boolean -tg_typdef (void *p, const char *name) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - s = pop_type (info); - if (s == NULL) - return FALSE; - - fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name, - info->filename, s); - - free (s); - - return TRUE; -} - -/* Output a tag. The tag should already be in the string on the - stack, so all we have to do here is print it out. */ - -static bfd_boolean -tg_tag (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return FALSE; - free (t); - - return TRUE; -} - -/* Output an integer constant. */ - -static bfd_boolean -tg_int_constant (void *p, const char *name, bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - - indent (info); - print_vma (val, ab, FALSE, FALSE); - fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n", - name, info->filename, ab); - return TRUE; -} - -/* Output a floating point constant. */ - -static bfd_boolean -tg_float_constant (void *p, const char *name, double val) -{ - struct pr_handle *info = (struct pr_handle *) p; - - indent (info); - fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n", - name, info->filename, val); - return TRUE; -} - -/* Output a typed constant. */ - -static bfd_boolean -tg_typed_constant (void *p, const char *name, bfd_vma val) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - indent (info); - print_vma (val, ab, FALSE, FALSE); - fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n", - name, info->filename, t, ab); - - free (t); - - return TRUE; -} - -/* Output a variable. */ - -static bfd_boolean -tg_variable (void *p, const char *name, enum debug_var_kind kind, - bfd_vma val ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t, *dname, *from_class; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - dname = NULL; - if (info->demangler) - dname = info->demangler (info->abfd, name, DMGL_ANSI | DMGL_PARAMS); - - from_class = NULL; - if (dname != NULL) - { - char *sep; - sep = strstr (dname, "::"); - if (sep) - { - *sep = 0; - name = sep + 2; - from_class = dname; - } - else - /* Obscure types as vts and type_info nodes. */ - name = dname; - } - - fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename, t); - - switch (kind) - { - case DEBUG_STATIC: - case DEBUG_LOCAL_STATIC: - fprintf (info->f, "\tfile:"); - break; - case DEBUG_REGISTER: - fprintf (info->f, "\tregister:"); - break; - default: - break; - } - - if (from_class) - fprintf (info->f, "\tclass:%s", from_class); - - if (dname) - free (dname); - - fprintf (info->f, "\n"); - - free (t); - - return TRUE; -} - -/* Start outputting a function. */ - -static bfd_boolean -tg_start_function (void *p, const char *name, bfd_boolean global) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *dname; - - if (! global) - info->stack->flavor = "static"; - else - info->stack->flavor = NULL; - - dname = NULL; - if (info->demangler) - dname = info->demangler (info->abfd, name, DMGL_ANSI | DMGL_PARAMS); - - if (! substitute_type (info, dname ? dname : name)) - return FALSE; - - info->stack->method = NULL; - if (dname != NULL) - { - char *sep; - sep = strstr (dname, "::"); - if (sep) - { - info->stack->method = dname; - *sep = 0; - name = sep + 2; - } - else - { - info->stack->method = ""; - name = dname; - } - sep = strchr (name, '('); - if (sep) - *sep = 0; - /* Obscure functions as type_info function. */ - } - - info->stack->parents = strdup (name); - - if (! info->stack->method && ! append_type (info, "(")) - return FALSE; - - info->parameter = 1; - - return TRUE; -} - -/* Output a function parameter. */ - -static bfd_boolean -tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind, - bfd_vma val ATTRIBUTE_UNUSED) -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (kind == DEBUG_PARM_REFERENCE - || kind == DEBUG_PARM_REF_REG) - { - if (! pr_reference_type (p)) - return FALSE; - } - - if (! substitute_type (info, name)) - return FALSE; - - t = pop_type (info); - if (t == NULL) - return FALSE; - - if (! info->stack->method) - { - if (info->parameter != 1 && ! append_type (info, ", ")) - return FALSE; - - if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) - if (! append_type (info, "register ")) - return FALSE; - - if (! append_type (info, t)) - return FALSE; - } - - free (t); - - ++info->parameter; - - return TRUE; -} - -/* Start writing out a block. */ - -static bfd_boolean -tg_start_block (void *p, bfd_vma addr) -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20], kind, *partof; - char *t; - bfd_boolean local; - - if (info->parameter > 0) - { - info->parameter = 0; - - /* Delayed name. */ - fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename); - free (info->stack->parents); - - print_vma (addr, ab, TRUE, TRUE); - translate_addresses (info->abfd, ab, info->f, info->syms); - local = info->stack->flavor != NULL; - if (info->stack->method && *info->stack->method) - { - kind = 'm'; - partof = (char *) info->stack->method; - } - else - { - kind = 'f'; - partof = NULL; - if (! info->stack->method && ! append_type (info, ")")) - return FALSE; - } - t = pop_type (info); - if (t == NULL) - return FALSE; - fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t); - if (local) - fputs ("\tfile:", info->f); - if (partof) - { - fprintf (info->f, "\tclass:%s", partof); - free (partof); - } - fputc ('\n', info->f); - } - - return TRUE; -} - -/* Write out line number information. */ - -static bfd_boolean -tg_lineno (void *p ATTRIBUTE_UNUSED, const char *fname ATTRIBUTE_UNUSED, - unsigned long lineno ATTRIBUTE_UNUSED, - bfd_vma addr ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Finish writing out a block. */ - -static bfd_boolean -tg_end_block (void *p ATTRIBUTE_UNUSED, bfd_vma addr ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Convert the visibility value into a human readable name. */ - -static const char * -visibility_name (enum debug_visibility visibility) -{ - const char *s; - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - s = "public"; - break; - case DEBUG_VISIBILITY_PRIVATE: - s = "private"; - break; - case DEBUG_VISIBILITY_PROTECTED: - s = "protected"; - break; - case DEBUG_VISIBILITY_IGNORE: - s = "/* ignore */"; - break; - default: - abort (); - return FALSE; - } - return s; -} diff --git a/contrib/binutils-2.22/binutils/rdcoff.c b/contrib/binutils-2.22/binutils/rdcoff.c deleted file mode 100644 index 473305e231..0000000000 --- a/contrib/binutils-2.22/binutils/rdcoff.c +++ /dev/null @@ -1,876 +0,0 @@ -/* stabs.c -- Parse COFF debugging information - Copyright 1996, 1999, 2000, 2002, 2003, 2005, 2007 - Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This file contains code which parses COFF debugging information. */ - -#include "sysdep.h" -#include "bfd.h" -#include "coff/internal.h" -#include "libiberty.h" -#include "bucomm.h" -#include "debug.h" -#include "budbg.h" - -/* FIXME: We should not need this BFD internal file. We need it for - the N_BTMASK, etc., values. */ -#include "libcoff.h" - -/* These macros extract the right mask and shifts for this BFD. They - assume that there is a local variable named ABFD. This is so that - macros like ISFCN and DECREF, from coff/internal.h, will work - without modification. */ -#define N_BTMASK (coff_data (abfd)->local_n_btmask) -#define N_BTSHFT (coff_data (abfd)->local_n_btshft) -#define N_TMASK (coff_data (abfd)->local_n_tmask) -#define N_TSHIFT (coff_data (abfd)->local_n_tshift) - -/* This structure is used to hold the symbols, as well as the current - location within the symbols. */ - -struct coff_symbols -{ - /* The symbols. */ - asymbol **syms; - /* The number of symbols. */ - long symcount; - /* The index of the current symbol. */ - long symno; - /* The index of the current symbol in the COFF symbol table (where - each auxent counts as a symbol). */ - long coff_symno; -}; - -/* The largest basic type we are prepared to handle. */ - -#define T_MAX (T_LNGDBL) - -/* This structure is used to hold slots. */ - -struct coff_slots -{ - /* Next set of slots. */ - struct coff_slots *next; - /* Slots. */ -#define COFF_SLOTS (16) - debug_type slots[COFF_SLOTS]; -}; - -/* This structure is used to map symbol indices to types. */ - -struct coff_types -{ - /* Slots. */ - struct coff_slots *slots; - /* Basic types. */ - debug_type basic[T_MAX + 1]; -}; - -static debug_type *coff_get_slot (struct coff_types *, int); -static debug_type parse_coff_type - (bfd *, struct coff_symbols *, struct coff_types *, long, int, - union internal_auxent *, bfd_boolean, void *); -static debug_type parse_coff_base_type - (bfd *, struct coff_symbols *, struct coff_types *, long, int, - union internal_auxent *, void *); -static debug_type parse_coff_struct_type - (bfd *, struct coff_symbols *, struct coff_types *, int, - union internal_auxent *, void *); -static debug_type parse_coff_enum_type - (bfd *, struct coff_symbols *, struct coff_types *, - union internal_auxent *, void *); -static bfd_boolean parse_coff_symbol - (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *, - void *, debug_type, bfd_boolean); -static bfd_boolean external_coff_symbol_p (int sym_class); - -/* Return the slot for a type. */ - -static debug_type * -coff_get_slot (struct coff_types *types, int indx) -{ - struct coff_slots **pps; - - pps = &types->slots; - - while (indx >= COFF_SLOTS) - { - if (*pps == NULL) - { - *pps = (struct coff_slots *) xmalloc (sizeof **pps); - memset (*pps, 0, sizeof **pps); - } - pps = &(*pps)->next; - indx -= COFF_SLOTS; - } - - if (*pps == NULL) - { - *pps = (struct coff_slots *) xmalloc (sizeof **pps); - memset (*pps, 0, sizeof **pps); - } - - return (*pps)->slots + indx; -} - -/* Parse a COFF type code in NTYPE. */ - -static debug_type -parse_coff_type (bfd *abfd, struct coff_symbols *symbols, - struct coff_types *types, long coff_symno, int ntype, - union internal_auxent *pauxent, bfd_boolean useaux, - void *dhandle) -{ - debug_type type; - - if ((ntype & ~N_BTMASK) != 0) - { - int newtype; - - newtype = DECREF (ntype); - - if (ISPTR (ntype)) - { - type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, - pauxent, useaux, dhandle); - type = debug_make_pointer_type (dhandle, type); - } - else if (ISFCN (ntype)) - { - type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, - pauxent, useaux, dhandle); - type = debug_make_function_type (dhandle, type, (debug_type *) NULL, - FALSE); - } - else if (ISARY (ntype)) - { - int n; - - if (pauxent == NULL) - n = 0; - else - { - unsigned short *dim; - int i; - - /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets - the c_naux field of the syment to 0. */ - - /* Move the dimensions down, so that the next array - picks up the next one. */ - dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen; - n = dim[0]; - for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++) - *dim = *(dim + 1); - *dim = 0; - } - - type = parse_coff_type (abfd, symbols, types, coff_symno, newtype, - pauxent, FALSE, dhandle); - type = debug_make_array_type (dhandle, type, - parse_coff_base_type (abfd, symbols, - types, - coff_symno, - T_INT, - NULL, dhandle), - 0, n - 1, FALSE); - } - else - { - non_fatal (_("parse_coff_type: Bad type code 0x%x"), ntype); - return DEBUG_TYPE_NULL; - } - - return type; - } - - if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0) - { - debug_type *slot; - - /* This is a reference to an existing type. FIXME: gdb checks - that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */ - slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l); - if (*slot != DEBUG_TYPE_NULL) - return *slot; - else - return debug_make_indirect_type (dhandle, slot, (const char *) NULL); - } - - /* If the aux entry has already been used for something, useaux will - have been set to false, indicating that parse_coff_base_type - should not use it. We need to do it this way, rather than simply - passing pauxent as NULL, because we need to be able handle - multiple array dimensions while still discarding pauxent after - having handled all of them. */ - if (! useaux) - pauxent = NULL; - - return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype, - pauxent, dhandle); -} - -/* Parse a basic COFF type in NTYPE. */ - -static debug_type -parse_coff_base_type (bfd *abfd, struct coff_symbols *symbols, - struct coff_types *types, long coff_symno, int ntype, - union internal_auxent *pauxent, void *dhandle) -{ - debug_type ret; - bfd_boolean set_basic; - const char *name; - debug_type *slot; - - if (ntype >= 0 - && ntype <= T_MAX - && types->basic[ntype] != DEBUG_TYPE_NULL) - return types->basic[ntype]; - - set_basic = TRUE; - name = NULL; - - switch (ntype) - { - default: - ret = debug_make_void_type (dhandle); - break; - - case T_NULL: - case T_VOID: - ret = debug_make_void_type (dhandle); - name = "void"; - break; - - case T_CHAR: - ret = debug_make_int_type (dhandle, 1, FALSE); - name = "char"; - break; - - case T_SHORT: - ret = debug_make_int_type (dhandle, 2, FALSE); - name = "short"; - break; - - case T_INT: - /* FIXME: Perhaps the size should depend upon the architecture. */ - ret = debug_make_int_type (dhandle, 4, FALSE); - name = "int"; - break; - - case T_LONG: - ret = debug_make_int_type (dhandle, 4, FALSE); - name = "long"; - break; - - case T_FLOAT: - ret = debug_make_float_type (dhandle, 4); - name = "float"; - break; - - case T_DOUBLE: - ret = debug_make_float_type (dhandle, 8); - name = "double"; - break; - - case T_LNGDBL: - ret = debug_make_float_type (dhandle, 12); - name = "long double"; - break; - - case T_UCHAR: - ret = debug_make_int_type (dhandle, 1, TRUE); - name = "unsigned char"; - break; - - case T_USHORT: - ret = debug_make_int_type (dhandle, 2, TRUE); - name = "unsigned short"; - break; - - case T_UINT: - ret = debug_make_int_type (dhandle, 4, TRUE); - name = "unsigned int"; - break; - - case T_ULONG: - ret = debug_make_int_type (dhandle, 4, TRUE); - name = "unsigned long"; - break; - - case T_STRUCT: - if (pauxent == NULL) - ret = debug_make_struct_type (dhandle, TRUE, 0, - (debug_field *) NULL); - else - ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, - dhandle); - - slot = coff_get_slot (types, coff_symno); - *slot = ret; - - set_basic = FALSE; - break; - - case T_UNION: - if (pauxent == NULL) - ret = debug_make_struct_type (dhandle, FALSE, 0, (debug_field *) NULL); - else - ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, - dhandle); - - slot = coff_get_slot (types, coff_symno); - *slot = ret; - - set_basic = FALSE; - break; - - case T_ENUM: - if (pauxent == NULL) - ret = debug_make_enum_type (dhandle, (const char **) NULL, - (bfd_signed_vma *) NULL); - else - ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle); - - slot = coff_get_slot (types, coff_symno); - *slot = ret; - - set_basic = FALSE; - break; - } - - if (name != NULL) - ret = debug_name_type (dhandle, name, ret); - - if (set_basic - && ntype >= 0 - && ntype <= T_MAX) - types->basic[ntype] = ret; - - return ret; -} - -/* Parse a struct type. */ - -static debug_type -parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols, - struct coff_types *types, int ntype, - union internal_auxent *pauxent, void *dhandle) -{ - long symend; - int alloc; - debug_field *fields; - int count; - bfd_boolean done; - - symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - count = 0; - - done = FALSE; - while (! done - && symbols->coff_symno < symend - && symbols->symno < symbols->symcount) - { - asymbol *sym; - long this_coff_symno; - struct internal_syment syment; - union internal_auxent auxent; - union internal_auxent *psubaux; - bfd_vma bitpos = 0, bitsize = 0; - - sym = symbols->syms[symbols->symno]; - - if (! bfd_coff_get_syment (abfd, sym, &syment)) - { - non_fatal (_("bfd_coff_get_syment failed: %s"), - bfd_errmsg (bfd_get_error ())); - return DEBUG_TYPE_NULL; - } - - this_coff_symno = symbols->coff_symno; - - ++symbols->symno; - symbols->coff_symno += 1 + syment.n_numaux; - - if (syment.n_numaux == 0) - psubaux = NULL; - else - { - if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent)) - { - non_fatal (_("bfd_coff_get_auxent failed: %s"), - bfd_errmsg (bfd_get_error ())); - return DEBUG_TYPE_NULL; - } - psubaux = &auxent; - } - - switch (syment.n_sclass) - { - case C_MOS: - case C_MOU: - bitpos = 8 * bfd_asymbol_value (sym); - bitsize = 0; - break; - - case C_FIELD: - bitpos = bfd_asymbol_value (sym); - bitsize = auxent.x_sym.x_misc.x_lnsz.x_size; - break; - - case C_EOS: - done = TRUE; - break; - } - - if (! done) - { - debug_type ftype; - debug_field f; - - ftype = parse_coff_type (abfd, symbols, types, this_coff_symno, - syment.n_type, psubaux, TRUE, dhandle); - f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype, - bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC); - if (f == DEBUG_FIELD_NULL) - return DEBUG_TYPE_NULL; - - if (count + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[count] = f; - ++count; - } - } - - fields[count] = DEBUG_FIELD_NULL; - - return debug_make_struct_type (dhandle, ntype == T_STRUCT, - pauxent->x_sym.x_misc.x_lnsz.x_size, - fields); -} - -/* Parse an enum type. */ - -static debug_type -parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols, - struct coff_types *types ATTRIBUTE_UNUSED, - union internal_auxent *pauxent, void *dhandle) -{ - long symend; - int alloc; - const char **names; - bfd_signed_vma *vals; - int count; - bfd_boolean done; - - symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l; - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals); - count = 0; - - done = FALSE; - while (! done - && symbols->coff_symno < symend - && symbols->symno < symbols->symcount) - { - asymbol *sym; - struct internal_syment syment; - - sym = symbols->syms[symbols->symno]; - - if (! bfd_coff_get_syment (abfd, sym, &syment)) - { - non_fatal (_("bfd_coff_get_syment failed: %s"), - bfd_errmsg (bfd_get_error ())); - return DEBUG_TYPE_NULL; - } - - ++symbols->symno; - symbols->coff_symno += 1 + syment.n_numaux; - - switch (syment.n_sclass) - { - case C_MOE: - if (count + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - vals = ((bfd_signed_vma *) - xrealloc (vals, alloc * sizeof *vals)); - } - - names[count] = bfd_asymbol_name (sym); - vals[count] = bfd_asymbol_value (sym); - ++count; - break; - - case C_EOS: - done = TRUE; - break; - } - } - - names[count] = NULL; - - return debug_make_enum_type (dhandle, names, vals); -} - -/* Handle a single COFF symbol. */ - -static bfd_boolean -parse_coff_symbol (bfd *abfd ATTRIBUTE_UNUSED, struct coff_types *types, - asymbol *sym, long coff_symno, - struct internal_syment *psyment, void *dhandle, - debug_type type, bfd_boolean within_function) -{ - switch (psyment->n_sclass) - { - case C_NULL: - break; - - case C_AUTO: - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, - DEBUG_LOCAL, bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_WEAKEXT: - case C_EXT: - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, - DEBUG_GLOBAL, bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_STAT: - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, - (within_function - ? DEBUG_LOCAL_STATIC - : DEBUG_STATIC), - bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_REG: - /* FIXME: We may need to convert the register number. */ - if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, - DEBUG_REGISTER, bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_LABEL: - break; - - case C_ARG: - if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, - DEBUG_PARM_STACK, bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_REGPARM: - /* FIXME: We may need to convert the register number. */ - if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, - DEBUG_PARM_REG, bfd_asymbol_value (sym))) - return FALSE; - break; - - case C_TPDEF: - type = debug_name_type (dhandle, bfd_asymbol_name (sym), type); - if (type == DEBUG_TYPE_NULL) - return FALSE; - break; - - case C_STRTAG: - case C_UNTAG: - case C_ENTAG: - { - debug_type *slot; - - type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type); - if (type == DEBUG_TYPE_NULL) - return FALSE; - - /* Store the named type into the slot, so that references get - the name. */ - slot = coff_get_slot (types, coff_symno); - *slot = type; - } - break; - - default: - break; - } - - return TRUE; -} - -/* Determine if a symbol has external visibility. */ - -static bfd_boolean -external_coff_symbol_p (int sym_class) -{ - switch (sym_class) - { - case C_EXT: - case C_WEAKEXT: - return TRUE; - default: - break; - } - return FALSE; -} - -/* This is the main routine. It looks through all the symbols and - handles them. */ - -bfd_boolean -parse_coff (bfd *abfd, asymbol **syms, long symcount, void *dhandle) -{ - struct coff_symbols symbols; - struct coff_types types; - int i; - long next_c_file; - const char *fnname; - int fnclass; - int fntype; - bfd_vma fnend; - alent *linenos; - bfd_boolean within_function; - long this_coff_symno; - - symbols.syms = syms; - symbols.symcount = symcount; - symbols.symno = 0; - symbols.coff_symno = 0; - - types.slots = NULL; - for (i = 0; i <= T_MAX; i++) - types.basic[i] = DEBUG_TYPE_NULL; - - next_c_file = -1; - fnname = NULL; - fnclass = 0; - fntype = 0; - fnend = 0; - linenos = NULL; - within_function = FALSE; - - while (symbols.symno < symcount) - { - asymbol *sym; - const char *name; - struct internal_syment syment; - union internal_auxent auxent; - union internal_auxent *paux; - debug_type type; - - sym = syms[symbols.symno]; - - if (! bfd_coff_get_syment (abfd, sym, &syment)) - { - non_fatal (_("bfd_coff_get_syment failed: %s"), - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - name = bfd_asymbol_name (sym); - - this_coff_symno = symbols.coff_symno; - - ++symbols.symno; - symbols.coff_symno += 1 + syment.n_numaux; - - /* We only worry about the first auxent, because that is the - only one which is relevant for debugging information. */ - if (syment.n_numaux == 0) - paux = NULL; - else - { - if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent)) - { - non_fatal (_("bfd_coff_get_auxent failed: %s"), - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - paux = &auxent; - } - - if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE) - { - /* The last C_FILE symbol points to the first external - symbol. */ - if (! debug_set_filename (dhandle, "*globals*")) - return FALSE; - } - - switch (syment.n_sclass) - { - case C_EFCN: - case C_EXTDEF: - case C_ULABEL: - case C_USTATIC: - case C_LINE: - case C_ALIAS: - case C_HIDDEN: - /* Just ignore these classes. */ - break; - - case C_FILE: - next_c_file = syment.n_value; - if (! debug_set_filename (dhandle, name)) - return FALSE; - break; - - case C_STAT: - /* Ignore static symbols with a type of T_NULL. These - represent section entries. */ - if (syment.n_type == T_NULL) - break; - /* Fall through. */ - case C_WEAKEXT: - case C_EXT: - if (ISFCN (syment.n_type)) - { - fnname = name; - fnclass = syment.n_sclass; - fntype = syment.n_type; - if (syment.n_numaux > 0) - fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize; - else - fnend = 0; - linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym)); - break; - } - type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, - syment.n_type, paux, TRUE, dhandle); - if (type == DEBUG_TYPE_NULL) - return FALSE; - if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment, - dhandle, type, within_function)) - return FALSE; - break; - - case C_FCN: - if (strcmp (name, ".bf") == 0) - { - if (fnname == NULL) - { - non_fatal (_("%ld: .bf without preceding function"), - this_coff_symno); - return FALSE; - } - - type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, - DECREF (fntype), paux, FALSE, dhandle); - if (type == DEBUG_TYPE_NULL) - return FALSE; - - if (! debug_record_function (dhandle, fnname, type, - external_coff_symbol_p (fnclass), - bfd_asymbol_value (sym))) - return FALSE; - - if (linenos != NULL) - { - int base; - bfd_vma addr; - - if (syment.n_numaux == 0) - base = 0; - else - base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1; - - addr = bfd_get_section_vma (abfd, bfd_get_section (sym)); - - ++linenos; - - while (linenos->line_number != 0) - { - if (! debug_record_line (dhandle, - linenos->line_number + base, - linenos->u.offset + addr)) - return FALSE; - ++linenos; - } - } - - fnname = NULL; - linenos = NULL; - fnclass = 0; - fntype = 0; - - within_function = TRUE; - } - else if (strcmp (name, ".ef") == 0) - { - if (! within_function) - { - non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno); - return FALSE; - } - - if (bfd_asymbol_value (sym) > fnend) - fnend = bfd_asymbol_value (sym); - if (! debug_end_function (dhandle, fnend)) - return FALSE; - - fnend = 0; - within_function = FALSE; - } - break; - - case C_BLOCK: - if (strcmp (name, ".bb") == 0) - { - if (! debug_start_block (dhandle, bfd_asymbol_value (sym))) - return FALSE; - } - else if (strcmp (name, ".eb") == 0) - { - if (! debug_end_block (dhandle, bfd_asymbol_value (sym))) - return FALSE; - } - break; - - default: - type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, - syment.n_type, paux, TRUE, dhandle); - if (type == DEBUG_TYPE_NULL) - return FALSE; - if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment, - dhandle, type, within_function)) - return FALSE; - break; - } - } - - return TRUE; -} diff --git a/contrib/binutils-2.22/binutils/rddbg.c b/contrib/binutils-2.22/binutils/rddbg.c deleted file mode 100644 index 27abd66a48..0000000000 --- a/contrib/binutils-2.22/binutils/rddbg.c +++ /dev/null @@ -1,450 +0,0 @@ -/* rddbg.c -- Read debugging information into a generic form. - Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2005, 2007, 2008, - 2010 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - - -/* This file reads debugging information into a generic form. This - file knows how to dig the debugging information out of an object - file. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "bucomm.h" -#include "debug.h" -#include "budbg.h" - -static bfd_boolean read_section_stabs_debugging_info - (bfd *, asymbol **, long, void *, bfd_boolean *); -static bfd_boolean read_symbol_stabs_debugging_info - (bfd *, asymbol **, long, void *, bfd_boolean *); -static bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *); -static void save_stab (int, int, bfd_vma, const char *); -static void stab_context (void); -static void free_saved_stabs (void); - -/* Read debugging information from a BFD. Returns a generic debugging - pointer. */ - -void * -read_debugging_info (bfd *abfd, asymbol **syms, long symcount, bfd_boolean no_messages) -{ - void *dhandle; - bfd_boolean found; - - dhandle = debug_init (); - if (dhandle == NULL) - return NULL; - - if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - - if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) - { - if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - } - - if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) - { - if (! read_ieee_debugging_info (abfd, dhandle, &found)) - return NULL; - } - - /* Try reading the COFF symbols if we didn't find any stabs in COFF - sections. */ - if (! found - && bfd_get_flavour (abfd) == bfd_target_coff_flavour - && symcount > 0) - { - if (! parse_coff (abfd, syms, symcount, dhandle)) - return NULL; - found = TRUE; - } - - if (! found) - { - if (! no_messages) - non_fatal (_("%s: no recognized debugging information"), - bfd_get_filename (abfd)); - return NULL; - } - - return dhandle; -} - -/* Read stabs in sections debugging information from a BFD. */ - -static bfd_boolean -read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, - void *dhandle, bfd_boolean *pfound) -{ - static struct - { - const char *secname; - const char *strsecname; - } - names[] = - { - { ".stab", ".stabstr" }, - { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" }, - { "$GDB_SYMBOLS$", "$GDB_STRINGS$" } - }; - unsigned int i; - void *shandle; - - *pfound = FALSE; - shandle = NULL; - - for (i = 0; i < sizeof names / sizeof names[0]; i++) - { - asection *sec, *strsec; - - sec = bfd_get_section_by_name (abfd, names[i].secname); - strsec = bfd_get_section_by_name (abfd, names[i].strsecname); - if (sec != NULL && strsec != NULL) - { - bfd_size_type stabsize, strsize; - bfd_byte *stabs, *strings; - bfd_byte *stab; - bfd_size_type stroff, next_stroff; - - stabsize = bfd_section_size (abfd, sec); - stabs = (bfd_byte *) xmalloc (stabsize); - if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].secname, - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - strsize = bfd_section_size (abfd, strsec); - strings = (bfd_byte *) xmalloc (strsize); - if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].strsecname, - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, TRUE, syms, symcount); - if (shandle == NULL) - return FALSE; - } - - *pfound = TRUE; - - stroff = 0; - next_stroff = 0; - for (stab = stabs; stab < stabs + stabsize; stab += 12) - { - unsigned int strx; - int type; - int other ATTRIBUTE_UNUSED; - int desc; - bfd_vma value; - - /* This code presumes 32 bit values. */ - - strx = bfd_get_32 (abfd, stab); - type = bfd_get_8 (abfd, stab + 4); - other = bfd_get_8 (abfd, stab + 5); - desc = bfd_get_16 (abfd, stab + 6); - value = bfd_get_32 (abfd, stab + 8); - - if (type == 0) - { - /* Special type 0 stabs indicate the offset to the - next string table. */ - stroff = next_stroff; - next_stroff += value; - } - else - { - char *f, *s; - - f = NULL; - - if (stroff + strx > strsize) - { - fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n", - bfd_get_filename (abfd), names[i].secname, - (long) (stab - stabs) / 12, strx, type); - continue; - } - - s = (char *) strings + stroff + strx; - - while (s[strlen (s) - 1] == '\\' - && stab + 12 < stabs + stabsize) - { - char *p; - - stab += 12; - p = s + strlen (s) - 1; - *p = '\0'; - s = concat (s, - ((char *) strings - + stroff - + bfd_get_32 (abfd, stab)), - (const char *) NULL); - - /* We have to restore the backslash, because, if - the linker is hashing stabs strings, we may - see the same string more than once. */ - *p = '\\'; - - if (f != NULL) - free (f); - f = s; - } - - save_stab (type, desc, value, s); - - if (! parse_stab (dhandle, shandle, type, desc, value, s)) - { - stab_context (); - free_saved_stabs (); - return FALSE; - } - - /* Don't free f, since I think the stabs code - expects strings to hang around. This should be - straightened out. FIXME. */ - } - } - - free_saved_stabs (); - free (stabs); - - /* Don't free strings, since I think the stabs code expects - the strings to hang around. This should be straightened - out. FIXME. */ - } - } - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return FALSE; - } - - return TRUE; -} - -/* Read stabs in the symbol table. */ - -static bfd_boolean -read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, - void *dhandle, bfd_boolean *pfound) -{ - void *shandle; - asymbol **ps, **symend; - - shandle = NULL; - symend = syms + symcount; - for (ps = syms; ps < symend; ps++) - { - symbol_info i; - - bfd_get_symbol_info (abfd, *ps, &i); - - if (i.type == '-') - { - const char *s; - char *f; - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, FALSE, syms, symcount); - if (shandle == NULL) - return FALSE; - } - - *pfound = TRUE; - - s = i.name; - f = NULL; - while (s[strlen (s) - 1] == '\\' - && ps + 1 < symend) - { - char *sc, *n; - - ++ps; - sc = xstrdup (s); - sc[strlen (sc) - 1] = '\0'; - n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); - free (sc); - if (f != NULL) - free (f); - f = n; - s = n; - } - - save_stab (i.stab_type, i.stab_desc, i.value, s); - - if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, - i.value, s)) - { - stab_context (); - free_saved_stabs (); - return FALSE; - } - - /* Don't free f, since I think the stabs code expects - strings to hang around. This should be straightened out. - FIXME. */ - } - } - - free_saved_stabs (); - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return FALSE; - } - - return TRUE; -} - -/* Read IEEE debugging information. */ - -static bfd_boolean -read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound) -{ - asection *dsec; - bfd_size_type size; - bfd_byte *contents; - - /* The BFD backend puts the debugging information into a section - named .debug. */ - - dsec = bfd_get_section_by_name (abfd, ".debug"); - if (dsec == NULL) - return TRUE; - - size = bfd_section_size (abfd, dsec); - contents = (bfd_byte *) xmalloc (size); - if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) - return FALSE; - - if (! parse_ieee (dhandle, abfd, contents, size)) - return FALSE; - - free (contents); - - *pfound = TRUE; - - return TRUE; -} - -/* Record stabs strings, so that we can give some context for errors. */ - -#define SAVE_STABS_COUNT (16) - -struct saved_stab -{ - int type; - int desc; - bfd_vma value; - char *string; -}; - -static struct saved_stab saved_stabs[SAVE_STABS_COUNT]; -static int saved_stabs_index; - -/* Save a stabs string. */ - -static void -save_stab (int type, int desc, bfd_vma value, const char *string) -{ - if (saved_stabs[saved_stabs_index].string != NULL) - free (saved_stabs[saved_stabs_index].string); - saved_stabs[saved_stabs_index].type = type; - saved_stabs[saved_stabs_index].desc = desc; - saved_stabs[saved_stabs_index].value = value; - saved_stabs[saved_stabs_index].string = xstrdup (string); - saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; -} - -/* Provide context for an error. */ - -static void -stab_context (void) -{ - int i; - - fprintf (stderr, _("Last stabs entries before error:\n")); - fprintf (stderr, "n_type n_desc n_value string\n"); - - i = saved_stabs_index; - do - { - struct saved_stab *stabp; - - stabp = saved_stabs + i; - if (stabp->string != NULL) - { - const char *s; - - s = bfd_get_stab_name (stabp->type); - if (s != NULL) - fprintf (stderr, "%-6s", s); - else if (stabp->type == 0) - fprintf (stderr, "HdrSym"); - else - fprintf (stderr, "%-6d", stabp->type); - fprintf (stderr, " %-6d ", stabp->desc); - fprintf_vma (stderr, stabp->value); - if (stabp->type != 0) - fprintf (stderr, " %s", stabp->string); - fprintf (stderr, "\n"); - } - i = (i + 1) % SAVE_STABS_COUNT; - } - while (i != saved_stabs_index); -} - -/* Free the saved stab strings. */ - -static void -free_saved_stabs (void) -{ - int i; - - for (i = 0; i < SAVE_STABS_COUNT; i++) - { - if (saved_stabs[i].string != NULL) - { - free (saved_stabs[i].string); - saved_stabs[i].string = NULL; - } - } - - saved_stabs_index = 0; -} diff --git a/contrib/binutils-2.22/binutils/readelf.c b/contrib/binutils-2.22/binutils/readelf.c deleted file mode 100644 index 9e13190b4e..0000000000 --- a/contrib/binutils-2.22/binutils/readelf.c +++ /dev/null @@ -1,13604 +0,0 @@ -/* readelf.c -- display contents of an ELF format file - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - Originally developed by Eric Youngdale - Modifications by Nick Clifton - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* The difference between readelf and objdump: - - Both programs are capable of displaying the contents of ELF format files, - so why does the binutils project have two file dumpers ? - - The reason is that objdump sees an ELF file through a BFD filter of the - world; if BFD has a bug where, say, it disagrees about a machine constant - in e_flags, then the odds are good that it will remain internally - consistent. The linker sees it the BFD way, objdump sees it the BFD way, - GAS sees it the BFD way. There was need for a tool to go find out what - the file actually says. - - This is why the readelf program does not link against the BFD library - it - exists as an independent program to help verify the correct working of BFD. - - There is also the case that readelf can provide more information about an - ELF file than is provided by objdump. In particular it can display DWARF - debugging information which (at the moment) objdump cannot. */ - -#include "config.h" -#include "sysdep.h" -#include -#include -#include -#ifdef HAVE_ZLIB_H -#include -#endif - -#if __GNUC__ >= 2 -/* Define BFD64 here, even if our default architecture is 32 bit ELF - as this will allow us to read in and parse 64bit and 32bit ELF files. - Only do this if we believe that the compiler can support a 64 bit - data type. For now we only rely on GCC being able to do this. */ -#define BFD64 -#endif - -#include "bfd.h" -#include "bucomm.h" -#include "elfcomm.h" -#include "dwarf.h" - -#include "elf/common.h" -#include "elf/external.h" -#include "elf/internal.h" - - -/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that - we can obtain the H8 reloc numbers. We need these for the - get_reloc_size() function. We include h8.h again after defining - RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */ - -#include "elf/h8.h" -#undef _ELF_H8_H - -/* Undo the effects of #including reloc-macros.h. */ - -#undef START_RELOC_NUMBERS -#undef RELOC_NUMBER -#undef FAKE_RELOC -#undef EMPTY_RELOC -#undef END_RELOC_NUMBERS -#undef _RELOC_MACROS_H - -/* The following headers use the elf/reloc-macros.h file to - automatically generate relocation recognition functions - such as elf_mips_reloc_type() */ - -#define RELOC_MACROS_GEN_FUNC - -#include "elf/alpha.h" -#include "elf/arc.h" -#include "elf/arm.h" -#include "elf/avr.h" -#include "elf/bfin.h" -#include "elf/cr16.h" -#include "elf/cris.h" -#include "elf/crx.h" -#include "elf/d10v.h" -#include "elf/d30v.h" -#include "elf/dlx.h" -#include "elf/fr30.h" -#include "elf/frv.h" -#include "elf/h8.h" -#include "elf/hppa.h" -#include "elf/i386.h" -#include "elf/i370.h" -#include "elf/i860.h" -#include "elf/i960.h" -#include "elf/ia64.h" -#include "elf/ip2k.h" -#include "elf/lm32.h" -#include "elf/iq2000.h" -#include "elf/m32c.h" -#include "elf/m32r.h" -#include "elf/m68k.h" -#include "elf/m68hc11.h" -#include "elf/mcore.h" -#include "elf/mep.h" -#include "elf/microblaze.h" -#include "elf/mips.h" -#include "elf/mmix.h" -#include "elf/mn10200.h" -#include "elf/mn10300.h" -#include "elf/moxie.h" -#include "elf/mt.h" -#include "elf/msp430.h" -#include "elf/or32.h" -#include "elf/pj.h" -#include "elf/ppc.h" -#include "elf/ppc64.h" -#include "elf/rx.h" -#include "elf/s390.h" -#include "elf/score.h" -#include "elf/sh.h" -#include "elf/sparc.h" -#include "elf/spu.h" -#include "elf/tic6x.h" -#include "elf/tilegx.h" -#include "elf/tilepro.h" -#include "elf/v850.h" -#include "elf/vax.h" -#include "elf/x86-64.h" -#include "elf/xc16x.h" -#include "elf/xstormy16.h" -#include "elf/xtensa.h" - -#include "getopt.h" -#include "libiberty.h" -#include "safe-ctype.h" -#include "filenames.h" - -char * program_name = "readelf"; -static long archive_file_offset; -static unsigned long archive_file_size; -static unsigned long dynamic_addr; -static bfd_size_type dynamic_size; -static unsigned int dynamic_nent; -static char * dynamic_strings; -static unsigned long dynamic_strings_length; -static char * string_table; -static unsigned long string_table_length; -static unsigned long num_dynamic_syms; -static Elf_Internal_Sym * dynamic_symbols; -static Elf_Internal_Syminfo * dynamic_syminfo; -static unsigned long dynamic_syminfo_offset; -static unsigned int dynamic_syminfo_nent; -static char program_interpreter[PATH_MAX]; -static bfd_vma dynamic_info[DT_ENCODING]; -static bfd_vma dynamic_info_DT_GNU_HASH; -static bfd_vma version_info[16]; -static Elf_Internal_Ehdr elf_header; -static Elf_Internal_Shdr * section_headers; -static Elf_Internal_Phdr * program_headers; -static Elf_Internal_Dyn * dynamic_section; -static Elf_Internal_Shdr * symtab_shndx_hdr; -static int show_name; -static int do_dynamic; -static int do_syms; -static int do_dyn_syms; -static int do_reloc; -static int do_sections; -static int do_section_groups; -static int do_section_details; -static int do_segments; -static int do_unwind; -static int do_using_dynamic; -static int do_header; -static int do_dump; -static int do_version; -static int do_histogram; -static int do_debugging; -static int do_arch; -static int do_notes; -static int do_archive_index; -static int is_32bit_elf; - -struct group_list -{ - struct group_list * next; - unsigned int section_index; -}; - -struct group -{ - struct group_list * root; - unsigned int group_index; -}; - -static size_t group_count; -static struct group * section_groups; -static struct group ** section_headers_groups; - - -/* Flag bits indicating particular types of dump. */ -#define HEX_DUMP (1 << 0) /* The -x command line switch. */ -#define DISASS_DUMP (1 << 1) /* The -i command line switch. */ -#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */ -#define STRING_DUMP (1 << 3) /* The -p command line switch. */ -#define RELOC_DUMP (1 << 4) /* The -R command line switch. */ - -typedef unsigned char dump_type; - -/* A linked list of the section names for which dumps were requested. */ -struct dump_list_entry -{ - char * name; - dump_type type; - struct dump_list_entry * next; -}; -static struct dump_list_entry * dump_sects_byname; - -/* A dynamic array of flags indicating for which sections a dump - has been requested via command line switches. */ -static dump_type * cmdline_dump_sects = NULL; -static unsigned int num_cmdline_dump_sects = 0; - -/* A dynamic array of flags indicating for which sections a dump of - some kind has been requested. It is reset on a per-object file - basis and then initialised from the cmdline_dump_sects array, - the results of interpreting the -w switch, and the - dump_sects_byname list. */ -static dump_type * dump_sects = NULL; -static unsigned int num_dump_sects = 0; - - -/* How to print a vma value. */ -typedef enum print_mode -{ - HEX, - DEC, - DEC_5, - UNSIGNED, - PREFIX_HEX, - FULL_HEX, - LONG_HEX -} -print_mode; - -#define UNKNOWN -1 - -#define SECTION_NAME(X) \ - ((X) == NULL ? _("") \ - : string_table == NULL ? _("") \ - : ((X)->sh_name >= string_table_length ? _("") \ - : string_table + (X)->sh_name)) - -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ - -#define GET_ELF_SYMBOLS(file, section) \ - (is_32bit_elf ? get_32bit_elf_symbols (file, section) \ - : get_64bit_elf_symbols (file, section)) - -#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length)) -/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has - already been called and verified that the string exists. */ -#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset) - -#define REMOVE_ARCH_BITS(ADDR) \ - do \ - { \ - if (elf_header.e_machine == EM_ARM) \ - (ADDR) &= ~1; \ - } \ - while (0) - -/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET. - Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer - using malloc and fill that. In either case return the pointer to the start of - the retrieved data or NULL if something went wrong. If something does go wrong - emit an error message using REASON as part of the context. */ - -static void * -get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb, - const char * reason) -{ - void * mvar; - - if (size == 0 || nmemb == 0) - return NULL; - - if (fseek (file, archive_file_offset + offset, SEEK_SET)) - { - error (_("Unable to seek to 0x%lx for %s\n"), - (unsigned long) archive_file_offset + offset, reason); - return NULL; - } - - mvar = var; - if (mvar == NULL) - { - /* Check for overflow. */ - if (nmemb < (~(size_t) 0 - 1) / size) - /* + 1 so that we can '\0' terminate invalid string table sections. */ - mvar = malloc (size * nmemb + 1); - - if (mvar == NULL) - { - error (_("Out of memory allocating 0x%lx bytes for %s\n"), - (unsigned long)(size * nmemb), reason); - return NULL; - } - - ((char *) mvar)[size * nmemb] = '\0'; - } - - if (fread (mvar, size, nmemb, file) != nmemb) - { - error (_("Unable to read in 0x%lx bytes of %s\n"), - (unsigned long)(size * nmemb), reason); - if (mvar != var) - free (mvar); - return NULL; - } - - return mvar; -} - -/* Print a VMA value. */ - -static int -print_vma (bfd_vma vma, print_mode mode) -{ - int nc = 0; - - switch (mode) - { - case FULL_HEX: - nc = printf ("0x"); - /* Drop through. */ - - case LONG_HEX: -#ifdef BFD64 - if (is_32bit_elf) - return nc + printf ("%8.8" BFD_VMA_FMT "x", vma); -#endif - printf_vma (vma); - return nc + 16; - - case DEC_5: - if (vma <= 99999) - return printf ("%5" BFD_VMA_FMT "d", vma); - /* Drop through. */ - - case PREFIX_HEX: - nc = printf ("0x"); - /* Drop through. */ - - case HEX: - return nc + printf ("%" BFD_VMA_FMT "x", vma); - - case DEC: - return printf ("%" BFD_VMA_FMT "d", vma); - - case UNSIGNED: - return printf ("%" BFD_VMA_FMT "u", vma); - } - return 0; -} - -/* Display a symbol on stdout. Handles the display of non-printing characters. - - If DO_WIDE is not true then format the symbol to be at most WIDTH characters, - truncating as necessary. If WIDTH is negative then format the string to be - exactly - WIDTH characters, truncating or padding as necessary. - - Returns the number of emitted characters. */ - -static unsigned int -print_symbol (int width, const char *symbol) -{ - const char *c; - bfd_boolean extra_padding = FALSE; - unsigned int num_printed = 0; - - if (do_wide) - { - /* Set the width to a very large value. This simplifies the - code below. */ - width = INT_MAX; - } - else if (width < 0) - { - /* Keep the width positive. This also helps. */ - width = - width; - extra_padding = TRUE; - } - - while (width) - { - int len; - - c = symbol; - - /* Look for non-printing symbols inside the symbol's name. - This test is triggered in particular by the names generated - by the assembler for local labels. */ - while (ISPRINT (*c)) - c++; - - len = c - symbol; - - if (len) - { - if (len > width) - len = width; - - printf ("%.*s", len, symbol); - - width -= len; - num_printed += len; - } - - if (*c == 0 || width == 0) - break; - - /* Now display the non-printing character, if - there is room left in which to dipslay it. */ - if ((unsigned char) *c < 32) - { - if (width < 2) - break; - - printf ("^%c", *c + 0x40); - - width -= 2; - num_printed += 2; - } - else - { - if (width < 6) - break; - - printf ("<0x%.2x>", (unsigned char) *c); - - width -= 6; - num_printed += 6; - } - - symbol = c + 1; - } - - if (extra_padding && width > 0) - { - /* Fill in the remaining spaces. */ - printf ("%-*s", width, " "); - num_printed += 2; - } - - return num_printed; -} - -/* Return a pointer to section NAME, or NULL if no such section exists. */ - -static Elf_Internal_Shdr * -find_section (const char * name) -{ - unsigned int i; - - for (i = 0; i < elf_header.e_shnum; i++) - if (streq (SECTION_NAME (section_headers + i), name)) - return section_headers + i; - - return NULL; -} - -/* Return a pointer to a section containing ADDR, or NULL if no such - section exists. */ - -static Elf_Internal_Shdr * -find_section_by_address (bfd_vma addr) -{ - unsigned int i; - - for (i = 0; i < elf_header.e_shnum; i++) - { - Elf_Internal_Shdr *sec = section_headers + i; - if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size) - return sec; - } - - return NULL; -} - -/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of - bytes read. */ - -static unsigned long -read_uleb128 (unsigned char *data, unsigned int *length_return) -{ - return read_leb128 (data, length_return, 0); -} - -/* Return true if the current file is for IA-64 machine and OpenVMS ABI. - This OS has so many departures from the ELF standard that we test it at - many places. */ - -static inline int -is_ia64_vms (void) -{ - return elf_header.e_machine == EM_IA_64 - && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS; -} - -/* Guess the relocation size commonly used by the specific machines. */ - -static int -guess_is_rela (unsigned int e_machine) -{ - switch (e_machine) - { - /* Targets that use REL relocations. */ - case EM_386: - case EM_486: - case EM_960: - case EM_ARM: - case EM_D10V: - case EM_CYGNUS_D10V: - case EM_DLX: - case EM_MIPS: - case EM_MIPS_RS3_LE: - case EM_CYGNUS_M32R: - case EM_OPENRISC: - case EM_OR32: - case EM_SCORE: - return FALSE; - - /* Targets that use RELA relocations. */ - case EM_68K: - case EM_860: - case EM_ALPHA: - case EM_ALTERA_NIOS2: - case EM_AVR: - case EM_AVR_OLD: - case EM_BLACKFIN: - case EM_CR16: - case EM_CR16_OLD: - case EM_CRIS: - case EM_CRX: - case EM_D30V: - case EM_CYGNUS_D30V: - case EM_FR30: - case EM_CYGNUS_FR30: - case EM_CYGNUS_FRV: - case EM_H8S: - case EM_H8_300: - case EM_H8_300H: - case EM_IA_64: - case EM_IP2K: - case EM_IP2K_OLD: - case EM_IQ2000: - case EM_LATTICEMICO32: - case EM_M32C_OLD: - case EM_M32C: - case EM_M32R: - case EM_MCORE: - case EM_CYGNUS_MEP: - case EM_MMIX: - case EM_MN10200: - case EM_CYGNUS_MN10200: - case EM_MN10300: - case EM_CYGNUS_MN10300: - case EM_MOXIE: - case EM_MSP430: - case EM_MSP430_OLD: - case EM_MT: - case EM_NIOS32: - case EM_PPC64: - case EM_PPC: - case EM_RX: - case EM_S390: - case EM_S390_OLD: - case EM_SH: - case EM_SPARC: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPU: - case EM_TI_C6000: - case EM_TILEGX: - case EM_TILEPRO: - case EM_V850: - case EM_CYGNUS_V850: - case EM_VAX: - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - case EM_XSTORMY16: - case EM_XTENSA: - case EM_XTENSA_OLD: - case EM_MICROBLAZE: - case EM_MICROBLAZE_OLD: - return TRUE; - - case EM_68HC05: - case EM_68HC08: - case EM_68HC11: - case EM_68HC16: - case EM_FX66: - case EM_ME16: - case EM_MMA: - case EM_NCPU: - case EM_NDR1: - case EM_PCP: - case EM_ST100: - case EM_ST19: - case EM_ST7: - case EM_ST9PLUS: - case EM_STARCORE: - case EM_SVX: - case EM_TINYJ: - default: - warn (_("Don't know about relocations on this machine architecture\n")); - return FALSE; - } -} - -static int -slurp_rela_relocs (FILE * file, - unsigned long rel_offset, - unsigned long rel_size, - Elf_Internal_Rela ** relasp, - unsigned long * nrelasp) -{ - Elf_Internal_Rela * relas; - unsigned long nrelas; - unsigned int i; - - if (is_32bit_elf) - { - Elf32_External_Rela * erelas; - - erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); - if (!erelas) - return 0; - - nrelas = rel_size / sizeof (Elf32_External_Rela); - - relas = (Elf_Internal_Rela *) cmalloc (nrelas, - sizeof (Elf_Internal_Rela)); - - if (relas == NULL) - { - free (erelas); - error (_("out of memory parsing relocs\n")); - return 0; - } - - for (i = 0; i < nrelas; i++) - { - relas[i].r_offset = BYTE_GET (erelas[i].r_offset); - relas[i].r_info = BYTE_GET (erelas[i].r_info); - relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend); - } - - free (erelas); - } - else - { - Elf64_External_Rela * erelas; - - erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); - if (!erelas) - return 0; - - nrelas = rel_size / sizeof (Elf64_External_Rela); - - relas = (Elf_Internal_Rela *) cmalloc (nrelas, - sizeof (Elf_Internal_Rela)); - - if (relas == NULL) - { - free (erelas); - error (_("out of memory parsing relocs\n")); - return 0; - } - - for (i = 0; i < nrelas; i++) - { - relas[i].r_offset = BYTE_GET (erelas[i].r_offset); - relas[i].r_info = BYTE_GET (erelas[i].r_info); - relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend); - - /* The #ifdef BFD64 below is to prevent a compile time - warning. We know that if we do not have a 64 bit data - type that we will never execute this code anyway. */ -#ifdef BFD64 - if (elf_header.e_machine == EM_MIPS - && elf_header.e_ident[EI_DATA] != ELFDATA2MSB) - { - /* In little-endian objects, r_info isn't really a - 64-bit little-endian value: it has a 32-bit - little-endian symbol index followed by four - individual byte fields. Reorder INFO - accordingly. */ - bfd_vma inf = relas[i].r_info; - inf = (((inf & 0xffffffff) << 32) - | ((inf >> 56) & 0xff) - | ((inf >> 40) & 0xff00) - | ((inf >> 24) & 0xff0000) - | ((inf >> 8) & 0xff000000)); - relas[i].r_info = inf; - } -#endif /* BFD64 */ - } - - free (erelas); - } - *relasp = relas; - *nrelasp = nrelas; - return 1; -} - -static int -slurp_rel_relocs (FILE * file, - unsigned long rel_offset, - unsigned long rel_size, - Elf_Internal_Rela ** relsp, - unsigned long * nrelsp) -{ - Elf_Internal_Rela * rels; - unsigned long nrels; - unsigned int i; - - if (is_32bit_elf) - { - Elf32_External_Rel * erels; - - erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); - if (!erels) - return 0; - - nrels = rel_size / sizeof (Elf32_External_Rel); - - rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela)); - - if (rels == NULL) - { - free (erels); - error (_("out of memory parsing relocs\n")); - return 0; - } - - for (i = 0; i < nrels; i++) - { - rels[i].r_offset = BYTE_GET (erels[i].r_offset); - rels[i].r_info = BYTE_GET (erels[i].r_info); - rels[i].r_addend = 0; - } - - free (erels); - } - else - { - Elf64_External_Rel * erels; - - erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1, - rel_size, _("relocs")); - if (!erels) - return 0; - - nrels = rel_size / sizeof (Elf64_External_Rel); - - rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela)); - - if (rels == NULL) - { - free (erels); - error (_("out of memory parsing relocs\n")); - return 0; - } - - for (i = 0; i < nrels; i++) - { - rels[i].r_offset = BYTE_GET (erels[i].r_offset); - rels[i].r_info = BYTE_GET (erels[i].r_info); - rels[i].r_addend = 0; - - /* The #ifdef BFD64 below is to prevent a compile time - warning. We know that if we do not have a 64 bit data - type that we will never execute this code anyway. */ -#ifdef BFD64 - if (elf_header.e_machine == EM_MIPS - && elf_header.e_ident[EI_DATA] != ELFDATA2MSB) - { - /* In little-endian objects, r_info isn't really a - 64-bit little-endian value: it has a 32-bit - little-endian symbol index followed by four - individual byte fields. Reorder INFO - accordingly. */ - bfd_vma inf = rels[i].r_info; - inf = (((inf & 0xffffffff) << 32) - | ((inf >> 56) & 0xff) - | ((inf >> 40) & 0xff00) - | ((inf >> 24) & 0xff0000) - | ((inf >> 8) & 0xff000000)); - rels[i].r_info = inf; - } -#endif /* BFD64 */ - } - - free (erels); - } - *relsp = rels; - *nrelsp = nrels; - return 1; -} - -/* Returns the reloc type extracted from the reloc info field. */ - -static unsigned int -get_reloc_type (bfd_vma reloc_info) -{ - if (is_32bit_elf) - return ELF32_R_TYPE (reloc_info); - - switch (elf_header.e_machine) - { - case EM_MIPS: - /* Note: We assume that reloc_info has already been adjusted for us. */ - return ELF64_MIPS_R_TYPE (reloc_info); - - case EM_SPARCV9: - return ELF64_R_TYPE_ID (reloc_info); - - default: - return ELF64_R_TYPE (reloc_info); - } -} - -/* Return the symbol index extracted from the reloc info field. */ - -static bfd_vma -get_reloc_symindex (bfd_vma reloc_info) -{ - return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info); -} - -/* Display the contents of the relocation data found at the specified - offset. */ - -static void -dump_relocations (FILE * file, - unsigned long rel_offset, - unsigned long rel_size, - Elf_Internal_Sym * symtab, - unsigned long nsyms, - char * strtab, - unsigned long strtablen, - int is_rela) -{ - unsigned int i; - Elf_Internal_Rela * rels; - - if (is_rela == UNKNOWN) - is_rela = guess_is_rela (elf_header.e_machine); - - if (is_rela) - { - if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size)) - return; - } - else - { - if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size)) - return; - } - - if (is_32bit_elf) - { - if (is_rela) - { - if (do_wide) - printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n")); - else - printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n")); - } - else - { - if (do_wide) - printf (_(" Offset Info Type Sym. Value Symbol's Name\n")); - else - printf (_(" Offset Info Type Sym.Value Sym. Name\n")); - } - } - else - { - if (is_rela) - { - if (do_wide) - printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n")); - else - printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n")); - } - else - { - if (do_wide) - printf (_(" Offset Info Type Symbol's Value Symbol's Name\n")); - else - printf (_(" Offset Info Type Sym. Value Sym. Name\n")); - } - } - - for (i = 0; i < rel_size; i++) - { - const char * rtype; - bfd_vma offset; - bfd_vma inf; - bfd_vma symtab_index; - bfd_vma type; - - offset = rels[i].r_offset; - inf = rels[i].r_info; - - type = get_reloc_type (inf); - symtab_index = get_reloc_symindex (inf); - - if (is_32bit_elf) - { - printf ("%8.8lx %8.8lx ", - (unsigned long) offset & 0xffffffff, - (unsigned long) inf & 0xffffffff); - } - else - { -#if BFD_HOST_64BIT_LONG - printf (do_wide - ? "%16.16lx %16.16lx " - : "%12.12lx %12.12lx ", - offset, inf); -#elif BFD_HOST_64BIT_LONG_LONG -#ifndef __MSVCRT__ - printf (do_wide - ? "%16.16llx %16.16llx " - : "%12.12llx %12.12llx ", - offset, inf); -#else - printf (do_wide - ? "%16.16I64x %16.16I64x " - : "%12.12I64x %12.12I64x ", - offset, inf); -#endif -#else - printf (do_wide - ? "%8.8lx%8.8lx %8.8lx%8.8lx " - : "%4.4lx%8.8lx %4.4lx%8.8lx ", - _bfd_int64_high (offset), - _bfd_int64_low (offset), - _bfd_int64_high (inf), - _bfd_int64_low (inf)); -#endif - } - - switch (elf_header.e_machine) - { - default: - rtype = NULL; - break; - - case EM_M32R: - case EM_CYGNUS_M32R: - rtype = elf_m32r_reloc_type (type); - break; - - case EM_386: - case EM_486: - rtype = elf_i386_reloc_type (type); - break; - - case EM_68HC11: - case EM_68HC12: - rtype = elf_m68hc11_reloc_type (type); - break; - - case EM_68K: - rtype = elf_m68k_reloc_type (type); - break; - - case EM_960: - rtype = elf_i960_reloc_type (type); - break; - - case EM_AVR: - case EM_AVR_OLD: - rtype = elf_avr_reloc_type (type); - break; - - case EM_OLD_SPARCV9: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - rtype = elf_sparc_reloc_type (type); - break; - - case EM_SPU: - rtype = elf_spu_reloc_type (type); - break; - - case EM_V850: - case EM_CYGNUS_V850: - rtype = v850_reloc_type (type); - break; - - case EM_D10V: - case EM_CYGNUS_D10V: - rtype = elf_d10v_reloc_type (type); - break; - - case EM_D30V: - case EM_CYGNUS_D30V: - rtype = elf_d30v_reloc_type (type); - break; - - case EM_DLX: - rtype = elf_dlx_reloc_type (type); - break; - - case EM_SH: - rtype = elf_sh_reloc_type (type); - break; - - case EM_MN10300: - case EM_CYGNUS_MN10300: - rtype = elf_mn10300_reloc_type (type); - break; - - case EM_MN10200: - case EM_CYGNUS_MN10200: - rtype = elf_mn10200_reloc_type (type); - break; - - case EM_FR30: - case EM_CYGNUS_FR30: - rtype = elf_fr30_reloc_type (type); - break; - - case EM_CYGNUS_FRV: - rtype = elf_frv_reloc_type (type); - break; - - case EM_MCORE: - rtype = elf_mcore_reloc_type (type); - break; - - case EM_MMIX: - rtype = elf_mmix_reloc_type (type); - break; - - case EM_MOXIE: - rtype = elf_moxie_reloc_type (type); - break; - - case EM_MSP430: - case EM_MSP430_OLD: - rtype = elf_msp430_reloc_type (type); - break; - - case EM_PPC: - rtype = elf_ppc_reloc_type (type); - break; - - case EM_PPC64: - rtype = elf_ppc64_reloc_type (type); - break; - - case EM_MIPS: - case EM_MIPS_RS3_LE: - rtype = elf_mips_reloc_type (type); - break; - - case EM_ALPHA: - rtype = elf_alpha_reloc_type (type); - break; - - case EM_ARM: - rtype = elf_arm_reloc_type (type); - break; - - case EM_ARC: - rtype = elf_arc_reloc_type (type); - break; - - case EM_PARISC: - rtype = elf_hppa_reloc_type (type); - break; - - case EM_H8_300: - case EM_H8_300H: - case EM_H8S: - rtype = elf_h8_reloc_type (type); - break; - - case EM_OPENRISC: - case EM_OR32: - rtype = elf_or32_reloc_type (type); - break; - - case EM_PJ: - case EM_PJ_OLD: - rtype = elf_pj_reloc_type (type); - break; - case EM_IA_64: - rtype = elf_ia64_reloc_type (type); - break; - - case EM_CRIS: - rtype = elf_cris_reloc_type (type); - break; - - case EM_860: - rtype = elf_i860_reloc_type (type); - break; - - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - rtype = elf_x86_64_reloc_type (type); - break; - - case EM_S370: - rtype = i370_reloc_type (type); - break; - - case EM_S390_OLD: - case EM_S390: - rtype = elf_s390_reloc_type (type); - break; - - case EM_SCORE: - rtype = elf_score_reloc_type (type); - break; - - case EM_XSTORMY16: - rtype = elf_xstormy16_reloc_type (type); - break; - - case EM_CRX: - rtype = elf_crx_reloc_type (type); - break; - - case EM_VAX: - rtype = elf_vax_reloc_type (type); - break; - - case EM_IP2K: - case EM_IP2K_OLD: - rtype = elf_ip2k_reloc_type (type); - break; - - case EM_IQ2000: - rtype = elf_iq2000_reloc_type (type); - break; - - case EM_XTENSA_OLD: - case EM_XTENSA: - rtype = elf_xtensa_reloc_type (type); - break; - - case EM_LATTICEMICO32: - rtype = elf_lm32_reloc_type (type); - break; - - case EM_M32C_OLD: - case EM_M32C: - rtype = elf_m32c_reloc_type (type); - break; - - case EM_MT: - rtype = elf_mt_reloc_type (type); - break; - - case EM_BLACKFIN: - rtype = elf_bfin_reloc_type (type); - break; - - case EM_CYGNUS_MEP: - rtype = elf_mep_reloc_type (type); - break; - - case EM_CR16: - case EM_CR16_OLD: - rtype = elf_cr16_reloc_type (type); - break; - - case EM_MICROBLAZE: - case EM_MICROBLAZE_OLD: - rtype = elf_microblaze_reloc_type (type); - break; - - case EM_RX: - rtype = elf_rx_reloc_type (type); - break; - - case EM_XC16X: - case EM_C166: - rtype = elf_xc16x_reloc_type (type); - break; - - case EM_TI_C6000: - rtype = elf_tic6x_reloc_type (type); - break; - - case EM_TILEGX: - rtype = elf_tilegx_reloc_type (type); - break; - - case EM_TILEPRO: - rtype = elf_tilepro_reloc_type (type); - break; - } - - if (rtype == NULL) - printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff); - else - printf (do_wide ? "%-22.22s" : "%-17.17s", rtype); - - if (elf_header.e_machine == EM_ALPHA - && rtype != NULL - && streq (rtype, "R_ALPHA_LITUSE") - && is_rela) - { - switch (rels[i].r_addend) - { - case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break; - case LITUSE_ALPHA_BASE: rtype = "BASE"; break; - case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break; - case LITUSE_ALPHA_JSR: rtype = "JSR"; break; - case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break; - case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break; - case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break; - default: rtype = NULL; - } - if (rtype) - printf (" (%s)", rtype); - else - { - putchar (' '); - printf (_(""), - (unsigned long) rels[i].r_addend); - } - } - else if (symtab_index) - { - if (symtab == NULL || symtab_index >= nsyms) - printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index); - else - { - Elf_Internal_Sym * psym; - - psym = symtab + symtab_index; - - printf (" "); - - if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC) - { - const char * name; - unsigned int len; - unsigned int width = is_32bit_elf ? 8 : 14; - - /* Relocations against GNU_IFUNC symbols do not use the value - of the symbol as the address to relocate against. Instead - they invoke the function named by the symbol and use its - result as the address for relocation. - - To indicate this to the user, do not display the value of - the symbol in the "Symbols's Value" field. Instead show - its name followed by () as a hint that the symbol is - invoked. */ - - if (strtab == NULL - || psym->st_name == 0 - || psym->st_name >= strtablen) - name = "??"; - else - name = strtab + psym->st_name; - - len = print_symbol (width, name); - printf ("()%-*s", len <= width ? (width + 1) - len : 1, " "); - } - else - { - print_vma (psym->st_value, LONG_HEX); - - printf (is_32bit_elf ? " " : " "); - } - - if (psym->st_name == 0) - { - const char * sec_name = ""; - char name_buf[40]; - - if (ELF_ST_TYPE (psym->st_info) == STT_SECTION) - { - if (psym->st_shndx < elf_header.e_shnum) - sec_name - = SECTION_NAME (section_headers + psym->st_shndx); - else if (psym->st_shndx == SHN_ABS) - sec_name = "ABS"; - else if (psym->st_shndx == SHN_COMMON) - sec_name = "COMMON"; - else if ((elf_header.e_machine == EM_MIPS - && psym->st_shndx == SHN_MIPS_SCOMMON) - || (elf_header.e_machine == EM_TI_C6000 - && psym->st_shndx == SHN_TIC6X_SCOMMON)) - sec_name = "SCOMMON"; - else if (elf_header.e_machine == EM_MIPS - && psym->st_shndx == SHN_MIPS_SUNDEFINED) - sec_name = "SUNDEF"; - else if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM - || elf_header.e_machine == EM_K1OM) - && psym->st_shndx == SHN_X86_64_LCOMMON) - sec_name = "LARGE_COMMON"; - else if (elf_header.e_machine == EM_IA_64 - && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX - && psym->st_shndx == SHN_IA_64_ANSI_COMMON) - sec_name = "ANSI_COM"; - else if (is_ia64_vms () - && psym->st_shndx == SHN_IA_64_VMS_SYMVEC) - sec_name = "VMS_SYMVEC"; - else - { - sprintf (name_buf, "
", - (unsigned int) psym->st_shndx); - sec_name = name_buf; - } - } - print_symbol (22, sec_name); - } - else if (strtab == NULL) - printf (_(""), psym->st_name); - else if (psym->st_name >= strtablen) - printf (_(""), psym->st_name); - else - print_symbol (22, strtab + psym->st_name); - - if (is_rela) - { - bfd_signed_vma off = rels[i].r_addend; - - if (off < 0) - printf (" - %" BFD_VMA_FMT "x", - off); - else - printf (" + %" BFD_VMA_FMT "x", off); - } - } - } - else if (is_rela) - { - printf ("%*c", is_32bit_elf ? - (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' '); - print_vma (rels[i].r_addend, LONG_HEX); - } - - if (elf_header.e_machine == EM_SPARCV9 - && rtype != NULL - && streq (rtype, "R_SPARC_OLO10")) - printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf)); - - putchar ('\n'); - -#ifdef BFD64 - if (! is_32bit_elf && elf_header.e_machine == EM_MIPS) - { - bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf); - bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf); - const char * rtype2 = elf_mips_reloc_type (type2); - const char * rtype3 = elf_mips_reloc_type (type3); - - printf (" Type2: "); - - if (rtype2 == NULL) - printf (_("unrecognized: %-7lx"), - (unsigned long) type2 & 0xffffffff); - else - printf ("%-17.17s", rtype2); - - printf ("\n Type3: "); - - if (rtype3 == NULL) - printf (_("unrecognized: %-7lx"), - (unsigned long) type3 & 0xffffffff); - else - printf ("%-17.17s", rtype3); - - putchar ('\n'); - } -#endif /* BFD64 */ - } - - free (rels); -} - -static const char * -get_mips_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION"; - case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP"; - case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM"; - case DT_MIPS_IVERSION: return "MIPS_IVERSION"; - case DT_MIPS_FLAGS: return "MIPS_FLAGS"; - case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS"; - case DT_MIPS_MSYM: return "MIPS_MSYM"; - case DT_MIPS_CONFLICT: return "MIPS_CONFLICT"; - case DT_MIPS_LIBLIST: return "MIPS_LIBLIST"; - case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO"; - case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO"; - case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO"; - case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO"; - case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO"; - case DT_MIPS_GOTSYM: return "MIPS_GOTSYM"; - case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO"; - case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP"; - case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS"; - case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO"; - case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE"; - case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO"; - case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC"; - case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO"; - case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM"; - case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO"; - case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM"; - case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO"; - case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS"; - case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT"; - case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; - case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX"; - case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX"; - case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX"; - case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX"; - case DT_MIPS_OPTIONS: return "MIPS_OPTIONS"; - case DT_MIPS_INTERFACE: return "MIPS_INTERFACE"; - case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN"; - case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE"; - case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR"; - case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX"; - case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE"; - case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE"; - case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC"; - case DT_MIPS_PLTGOT: return "MIPS_PLTGOT"; - case DT_MIPS_RWPLT: return "MIPS_RWPLT"; - default: - return NULL; - } -} - -static const char * -get_sparc64_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_SPARC_REGISTER: return "SPARC_REGISTER"; - default: - return NULL; - } -} - -static const char * -get_ppc_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_PPC_GOT: return "PPC_GOT"; - case DT_PPC_TLSOPT: return "PPC_TLSOPT"; - default: - return NULL; - } -} - -static const char * -get_ppc64_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_PPC64_GLINK: return "PPC64_GLINK"; - case DT_PPC64_OPD: return "PPC64_OPD"; - case DT_PPC64_OPDSZ: return "PPC64_OPDSZ"; - case DT_PPC64_TLSOPT: return "PPC64_TLSOPT"; - default: - return NULL; - } -} - -static const char * -get_parisc_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_HP_LOAD_MAP: return "HP_LOAD_MAP"; - case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS"; - case DT_HP_DLD_HOOK: return "HP_DLD_HOOK"; - case DT_HP_UX10_INIT: return "HP_UX10_INIT"; - case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ"; - case DT_HP_PREINIT: return "HP_PREINIT"; - case DT_HP_PREINITSZ: return "HP_PREINITSZ"; - case DT_HP_NEEDED: return "HP_NEEDED"; - case DT_HP_TIME_STAMP: return "HP_TIME_STAMP"; - case DT_HP_CHECKSUM: return "HP_CHECKSUM"; - case DT_HP_GST_SIZE: return "HP_GST_SIZE"; - case DT_HP_GST_VERSION: return "HP_GST_VERSION"; - case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL"; - case DT_HP_EPLTREL: return "HP_GST_EPLTREL"; - case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ"; - case DT_HP_FILTERED: return "HP_FILTERED"; - case DT_HP_FILTER_TLS: return "HP_FILTER_TLS"; - case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED"; - case DT_HP_LAZYLOAD: return "HP_LAZYLOAD"; - case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT"; - case DT_PLT: return "PLT"; - case DT_PLT_SIZE: return "PLT_SIZE"; - case DT_DLT: return "DLT"; - case DT_DLT_SIZE: return "DLT_SIZE"; - default: - return NULL; - } -} - -static const char * -get_ia64_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE"; - case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE"; - case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT"; - case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS"; - case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ"; - case DT_IA_64_VMS_IDENT: return "VMS_IDENT"; - case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT"; - case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT"; - case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT"; - case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT"; - case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED"; - case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT"; - case DT_IA_64_VMS_XLATED: return "VMS_XLATED"; - case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE"; - case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ"; - case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG"; - case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG"; - case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME"; - case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO"; - case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET"; - case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG"; - case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET"; - case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG"; - case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET"; - case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET"; - case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF"; - case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF"; - case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF"; - case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET"; - case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG"; - case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE"; - default: - return NULL; - } -} - -static const char * -get_alpha_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_ALPHA_PLTRO: return "ALPHA_PLTRO"; - default: - return NULL; - } -} - -static const char * -get_score_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS"; - case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO"; - case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO"; - case DT_SCORE_GOTSYM: return "SCORE_GOTSYM"; - case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO"; - case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO"; - default: - return NULL; - } -} - -static const char * -get_tic6x_dynamic_type (unsigned long type) -{ - switch (type) - { - case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET"; - case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET"; - case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE"; - case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE"; - case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP"; - case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX"; - default: - return NULL; - } -} - -static const char * -get_dynamic_type (unsigned long type) -{ - static char buff[64]; - - switch (type) - { - case DT_NULL: return "NULL"; - case DT_NEEDED: return "NEEDED"; - case DT_PLTRELSZ: return "PLTRELSZ"; - case DT_PLTGOT: return "PLTGOT"; - case DT_HASH: return "HASH"; - case DT_STRTAB: return "STRTAB"; - case DT_SYMTAB: return "SYMTAB"; - case DT_RELA: return "RELA"; - case DT_RELASZ: return "RELASZ"; - case DT_RELAENT: return "RELAENT"; - case DT_STRSZ: return "STRSZ"; - case DT_SYMENT: return "SYMENT"; - case DT_INIT: return "INIT"; - case DT_FINI: return "FINI"; - case DT_SONAME: return "SONAME"; - case DT_RPATH: return "RPATH"; - case DT_SYMBOLIC: return "SYMBOLIC"; - case DT_REL: return "REL"; - case DT_RELSZ: return "RELSZ"; - case DT_RELENT: return "RELENT"; - case DT_PLTREL: return "PLTREL"; - case DT_DEBUG: return "DEBUG"; - case DT_TEXTREL: return "TEXTREL"; - case DT_JMPREL: return "JMPREL"; - case DT_BIND_NOW: return "BIND_NOW"; - case DT_INIT_ARRAY: return "INIT_ARRAY"; - case DT_FINI_ARRAY: return "FINI_ARRAY"; - case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ"; - case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ"; - case DT_RUNPATH: return "RUNPATH"; - case DT_FLAGS: return "FLAGS"; - - case DT_PREINIT_ARRAY: return "PREINIT_ARRAY"; - case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ"; - - case DT_CHECKSUM: return "CHECKSUM"; - case DT_PLTPADSZ: return "PLTPADSZ"; - case DT_MOVEENT: return "MOVEENT"; - case DT_MOVESZ: return "MOVESZ"; - case DT_FEATURE: return "FEATURE"; - case DT_POSFLAG_1: return "POSFLAG_1"; - case DT_SYMINSZ: return "SYMINSZ"; - case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */ - - case DT_ADDRRNGLO: return "ADDRRNGLO"; - case DT_CONFIG: return "CONFIG"; - case DT_DEPAUDIT: return "DEPAUDIT"; - case DT_AUDIT: return "AUDIT"; - case DT_PLTPAD: return "PLTPAD"; - case DT_MOVETAB: return "MOVETAB"; - case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */ - - case DT_VERSYM: return "VERSYM"; - - case DT_TLSDESC_GOT: return "TLSDESC_GOT"; - case DT_TLSDESC_PLT: return "TLSDESC_PLT"; - case DT_RELACOUNT: return "RELACOUNT"; - case DT_RELCOUNT: return "RELCOUNT"; - case DT_FLAGS_1: return "FLAGS_1"; - case DT_VERDEF: return "VERDEF"; - case DT_VERDEFNUM: return "VERDEFNUM"; - case DT_VERNEED: return "VERNEED"; - case DT_VERNEEDNUM: return "VERNEEDNUM"; - - case DT_AUXILIARY: return "AUXILIARY"; - case DT_USED: return "USED"; - case DT_FILTER: return "FILTER"; - - case DT_GNU_PRELINKED: return "GNU_PRELINKED"; - case DT_GNU_CONFLICT: return "GNU_CONFLICT"; - case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ"; - case DT_GNU_LIBLIST: return "GNU_LIBLIST"; - case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ"; - case DT_GNU_HASH: return "GNU_HASH"; - - default: - if ((type >= DT_LOPROC) && (type <= DT_HIPROC)) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_MIPS: - case EM_MIPS_RS3_LE: - result = get_mips_dynamic_type (type); - break; - case EM_SPARCV9: - result = get_sparc64_dynamic_type (type); - break; - case EM_PPC: - result = get_ppc_dynamic_type (type); - break; - case EM_PPC64: - result = get_ppc64_dynamic_type (type); - break; - case EM_IA_64: - result = get_ia64_dynamic_type (type); - break; - case EM_ALPHA: - result = get_alpha_dynamic_type (type); - break; - case EM_SCORE: - result = get_score_dynamic_type (type); - break; - case EM_TI_C6000: - result = get_tic6x_dynamic_type (type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type); - } - else if (((type >= DT_LOOS) && (type <= DT_HIOS)) - || (elf_header.e_machine == EM_PARISC - && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS))) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_PARISC: - result = get_parisc_dynamic_type (type); - break; - case EM_IA_64: - result = get_ia64_dynamic_type (type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - snprintf (buff, sizeof (buff), _("Operating System specific: %lx"), - type); - } - else - snprintf (buff, sizeof (buff), _(": %lx"), type); - - return buff; - } -} - -static char * -get_file_type (unsigned e_type) -{ - static char buff[32]; - - switch (e_type) - { - case ET_NONE: return _("NONE (None)"); - case ET_REL: return _("REL (Relocatable file)"); - case ET_EXEC: return _("EXEC (Executable file)"); - case ET_DYN: return _("DYN (Shared object file)"); - case ET_CORE: return _("CORE (Core file)"); - - default: - if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC)) - snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type); - else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS)) - snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type); - else - snprintf (buff, sizeof (buff), _(": %x"), e_type); - return buff; - } -} - -static char * -get_machine_name (unsigned e_machine) -{ - static char buff[64]; /* XXX */ - - switch (e_machine) - { - case EM_NONE: return _("None"); - case EM_M32: return "WE32100"; - case EM_SPARC: return "Sparc"; - case EM_SPU: return "SPU"; - case EM_386: return "Intel 80386"; - case EM_68K: return "MC68000"; - case EM_88K: return "MC88000"; - case EM_486: return "Intel 80486"; - case EM_860: return "Intel 80860"; - case EM_MIPS: return "MIPS R3000"; - case EM_S370: return "IBM System/370"; - case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian"; - case EM_OLD_SPARCV9: return "Sparc v9 (old)"; - case EM_PARISC: return "HPPA"; - case EM_PPC_OLD: return "Power PC (old)"; - case EM_SPARC32PLUS: return "Sparc v8+" ; - case EM_960: return "Intel 90860"; - case EM_PPC: return "PowerPC"; - case EM_PPC64: return "PowerPC64"; - case EM_V800: return "NEC V800"; - case EM_FR20: return "Fujitsu FR20"; - case EM_RH32: return "TRW RH32"; - case EM_MCORE: return "MCORE"; - case EM_ARM: return "ARM"; - case EM_OLD_ALPHA: return "Digital Alpha (old)"; - case EM_SH: return "Renesas / SuperH SH"; - case EM_SPARCV9: return "Sparc v9"; - case EM_TRICORE: return "Siemens Tricore"; - case EM_ARC: return "ARC"; - case EM_H8_300: return "Renesas H8/300"; - case EM_H8_300H: return "Renesas H8/300H"; - case EM_H8S: return "Renesas H8S"; - case EM_H8_500: return "Renesas H8/500"; - case EM_IA_64: return "Intel IA-64"; - case EM_MIPS_X: return "Stanford MIPS-X"; - case EM_COLDFIRE: return "Motorola Coldfire"; - case EM_68HC12: return "Motorola M68HC12"; - case EM_ALPHA: return "Alpha"; - case EM_CYGNUS_D10V: - case EM_D10V: return "d10v"; - case EM_CYGNUS_D30V: - case EM_D30V: return "d30v"; - case EM_CYGNUS_M32R: - case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)"; - case EM_CYGNUS_V850: - case EM_V850: return "Renesas v850"; - case EM_CYGNUS_MN10300: - case EM_MN10300: return "mn10300"; - case EM_CYGNUS_MN10200: - case EM_MN10200: return "mn10200"; - case EM_MOXIE: return "Moxie"; - case EM_CYGNUS_FR30: - case EM_FR30: return "Fujitsu FR30"; - case EM_CYGNUS_FRV: return "Fujitsu FR-V"; - case EM_PJ_OLD: - case EM_PJ: return "picoJava"; - case EM_MMA: return "Fujitsu Multimedia Accelerator"; - case EM_PCP: return "Siemens PCP"; - case EM_NCPU: return "Sony nCPU embedded RISC processor"; - case EM_NDR1: return "Denso NDR1 microprocesspr"; - case EM_STARCORE: return "Motorola Star*Core processor"; - case EM_ME16: return "Toyota ME16 processor"; - case EM_ST100: return "STMicroelectronics ST100 processor"; - case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor"; - case EM_PDSP: return "Sony DSP processor"; - case EM_PDP10: return "Digital Equipment Corp. PDP-10"; - case EM_PDP11: return "Digital Equipment Corp. PDP-11"; - case EM_FX66: return "Siemens FX66 microcontroller"; - case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller"; - case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller"; - case EM_68HC16: return "Motorola MC68HC16 Microcontroller"; - case EM_68HC11: return "Motorola MC68HC11 Microcontroller"; - case EM_68HC08: return "Motorola MC68HC08 Microcontroller"; - case EM_68HC05: return "Motorola MC68HC05 Microcontroller"; - case EM_SVX: return "Silicon Graphics SVx"; - case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller"; - case EM_VAX: return "Digital VAX"; - case EM_AVR_OLD: - case EM_AVR: return "Atmel AVR 8-bit microcontroller"; - case EM_CRIS: return "Axis Communications 32-bit embedded processor"; - case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu"; - case EM_FIREPATH: return "Element 14 64-bit DSP processor"; - case EM_ZSP: return "LSI Logic's 16-bit DSP processor"; - case EM_MMIX: return "Donald Knuth's educational 64-bit processor"; - case EM_HUANY: return "Harvard Universitys's machine-independent object format"; - case EM_PRISM: return "Vitesse Prism"; - case EM_X86_64: return "Advanced Micro Devices X86-64"; - case EM_L1OM: return "Intel L1OM"; - case EM_K1OM: return "Intel K1OM"; - case EM_S390_OLD: - case EM_S390: return "IBM S/390"; - case EM_SCORE: return "SUNPLUS S+Core"; - case EM_XSTORMY16: return "Sanyo XStormy16 CPU core"; - case EM_OPENRISC: - case EM_OR32: return "OpenRISC"; - case EM_ARC_A5: return "ARC International ARCompact processor"; - case EM_CRX: return "National Semiconductor CRX microprocessor"; - case EM_DLX: return "OpenDLX"; - case EM_IP2K_OLD: - case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers"; - case EM_IQ2000: return "Vitesse IQ2000"; - case EM_XTENSA_OLD: - case EM_XTENSA: return "Tensilica Xtensa Processor"; - case EM_VIDEOCORE: return "Alphamosaic VideoCore processor"; - case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor"; - case EM_NS32K: return "National Semiconductor 32000 series"; - case EM_TPC: return "Tenor Network TPC processor"; - case EM_ST200: return "STMicroelectronics ST200 microcontroller"; - case EM_MAX: return "MAX Processor"; - case EM_CR: return "National Semiconductor CompactRISC"; - case EM_F2MC16: return "Fujitsu F2MC16"; - case EM_MSP430: return "Texas Instruments msp430 microcontroller"; - case EM_LATTICEMICO32: return "Lattice Mico32"; - case EM_M32C_OLD: - case EM_M32C: return "Renesas M32c"; - case EM_MT: return "Morpho Techologies MT processor"; - case EM_BLACKFIN: return "Analog Devices Blackfin"; - case EM_SE_C33: return "S1C33 Family of Seiko Epson processors"; - case EM_SEP: return "Sharp embedded microprocessor"; - case EM_ARCA: return "Arca RISC microprocessor"; - case EM_UNICORE: return "Unicore"; - case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU"; - case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor"; - case EM_NIOS32: return "Altera Nios"; - case EM_ALTERA_NIOS2: return "Altera Nios II"; - case EM_C166: - case EM_XC16X: return "Infineon Technologies xc16x"; - case EM_M16C: return "Renesas M16C series microprocessors"; - case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller"; - case EM_CE: return "Freescale Communication Engine RISC core"; - case EM_TSK3000: return "Altium TSK3000 core"; - case EM_RS08: return "Freescale RS08 embedded processor"; - case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor"; - case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor"; - case EM_VIDEOCORE3: return "Broadcom VideoCore III processor"; - case EM_SE_C17: return "Seiko Epson C17 family"; - case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family"; - case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family"; - case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family"; - case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor"; - case EM_CYPRESS_M8C: return "Cypress M8C microprocessor"; - case EM_R32C: return "Renesas R32C series microprocessors"; - case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family"; - case EM_QDSP6: return "QUALCOMM DSP6 Processor"; - case EM_8051: return "Intel 8051 and variants"; - case EM_STXP7X: return "STMicroelectronics STxP7x family"; - case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family"; - case EM_ECOG1X: return "Cyan Technology eCOG1X family"; - case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers"; - case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor"; - case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor"; - case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture"; - case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine"; - case EM_CR16: - case EM_CR16_OLD: return "National Semiconductor's CR16"; - case EM_MICROBLAZE: return "Xilinx MicroBlaze"; - case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze"; - case EM_RX: return "Renesas RX"; - case EM_METAG: return "Imagination Technologies META processor architecture"; - case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture"; - case EM_ECOG16: return "Cyan Technology eCOG16 family"; - case EM_ETPU: return "Freescale Extended Time Processing Unit"; - case EM_SLE9X: return "Infineon Technologies SLE9X core"; - case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family"; - case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller"; - case EM_TILE64: return "Tilera TILE64 multicore architecture family"; - case EM_TILEPRO: return "Tilera TILEPro multicore architecture family"; - case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family"; - case EM_CUDA: return "NVIDIA CUDA architecture"; - default: - snprintf (buff, sizeof (buff), _(": 0x%x"), e_machine); - return buff; - } -} - -static void -decode_ARM_machine_flags (unsigned e_flags, char buf[]) -{ - unsigned eabi; - int unknown = 0; - - eabi = EF_ARM_EABI_VERSION (e_flags); - e_flags &= ~ EF_ARM_EABIMASK; - - /* Handle "generic" ARM flags. */ - if (e_flags & EF_ARM_RELEXEC) - { - strcat (buf, ", relocatable executable"); - e_flags &= ~ EF_ARM_RELEXEC; - } - - if (e_flags & EF_ARM_HASENTRY) - { - strcat (buf, ", has entry point"); - e_flags &= ~ EF_ARM_HASENTRY; - } - - /* Now handle EABI specific flags. */ - switch (eabi) - { - default: - strcat (buf, ", "); - if (e_flags) - unknown = 1; - break; - - case EF_ARM_EABI_VER1: - strcat (buf, ", Version1 EABI"); - while (e_flags) - { - unsigned flag; - - /* Process flags one bit at a time. */ - flag = e_flags & - e_flags; - e_flags &= ~ flag; - - switch (flag) - { - case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */ - strcat (buf, ", sorted symbol tables"); - break; - - default: - unknown = 1; - break; - } - } - break; - - case EF_ARM_EABI_VER2: - strcat (buf, ", Version2 EABI"); - while (e_flags) - { - unsigned flag; - - /* Process flags one bit at a time. */ - flag = e_flags & - e_flags; - e_flags &= ~ flag; - - switch (flag) - { - case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */ - strcat (buf, ", sorted symbol tables"); - break; - - case EF_ARM_DYNSYMSUSESEGIDX: - strcat (buf, ", dynamic symbols use segment index"); - break; - - case EF_ARM_MAPSYMSFIRST: - strcat (buf, ", mapping symbols precede others"); - break; - - default: - unknown = 1; - break; - } - } - break; - - case EF_ARM_EABI_VER3: - strcat (buf, ", Version3 EABI"); - break; - - case EF_ARM_EABI_VER4: - strcat (buf, ", Version4 EABI"); - goto eabi; - - case EF_ARM_EABI_VER5: - strcat (buf, ", Version5 EABI"); - eabi: - while (e_flags) - { - unsigned flag; - - /* Process flags one bit at a time. */ - flag = e_flags & - e_flags; - e_flags &= ~ flag; - - switch (flag) - { - case EF_ARM_BE8: - strcat (buf, ", BE8"); - break; - - case EF_ARM_LE8: - strcat (buf, ", LE8"); - break; - - default: - unknown = 1; - break; - } - } - break; - - case EF_ARM_EABI_UNKNOWN: - strcat (buf, ", GNU EABI"); - while (e_flags) - { - unsigned flag; - - /* Process flags one bit at a time. */ - flag = e_flags & - e_flags; - e_flags &= ~ flag; - - switch (flag) - { - case EF_ARM_INTERWORK: - strcat (buf, ", interworking enabled"); - break; - - case EF_ARM_APCS_26: - strcat (buf, ", uses APCS/26"); - break; - - case EF_ARM_APCS_FLOAT: - strcat (buf, ", uses APCS/float"); - break; - - case EF_ARM_PIC: - strcat (buf, ", position independent"); - break; - - case EF_ARM_ALIGN8: - strcat (buf, ", 8 bit structure alignment"); - break; - - case EF_ARM_NEW_ABI: - strcat (buf, ", uses new ABI"); - break; - - case EF_ARM_OLD_ABI: - strcat (buf, ", uses old ABI"); - break; - - case EF_ARM_SOFT_FLOAT: - strcat (buf, ", software FP"); - break; - - case EF_ARM_VFP_FLOAT: - strcat (buf, ", VFP"); - break; - - case EF_ARM_MAVERICK_FLOAT: - strcat (buf, ", Maverick FP"); - break; - - default: - unknown = 1; - break; - } - } - } - - if (unknown) - strcat (buf,_(", ")); -} - -static char * -get_machine_flags (unsigned e_flags, unsigned e_machine) -{ - static char buf[1024]; - - buf[0] = '\0'; - - if (e_flags) - { - switch (e_machine) - { - default: - break; - - case EM_ARM: - decode_ARM_machine_flags (e_flags, buf); - break; - - case EM_BLACKFIN: - if (e_flags & EF_BFIN_PIC) - strcat (buf, ", PIC"); - - if (e_flags & EF_BFIN_FDPIC) - strcat (buf, ", FDPIC"); - - if (e_flags & EF_BFIN_CODE_IN_L1) - strcat (buf, ", code in L1"); - - if (e_flags & EF_BFIN_DATA_IN_L1) - strcat (buf, ", data in L1"); - - break; - - case EM_CYGNUS_FRV: - switch (e_flags & EF_FRV_CPU_MASK) - { - case EF_FRV_CPU_GENERIC: - break; - - default: - strcat (buf, ", fr???"); - break; - - case EF_FRV_CPU_FR300: - strcat (buf, ", fr300"); - break; - - case EF_FRV_CPU_FR400: - strcat (buf, ", fr400"); - break; - case EF_FRV_CPU_FR405: - strcat (buf, ", fr405"); - break; - - case EF_FRV_CPU_FR450: - strcat (buf, ", fr450"); - break; - - case EF_FRV_CPU_FR500: - strcat (buf, ", fr500"); - break; - case EF_FRV_CPU_FR550: - strcat (buf, ", fr550"); - break; - - case EF_FRV_CPU_SIMPLE: - strcat (buf, ", simple"); - break; - case EF_FRV_CPU_TOMCAT: - strcat (buf, ", tomcat"); - break; - } - break; - - case EM_68K: - if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000) - strcat (buf, ", m68000"); - else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32) - strcat (buf, ", cpu32"); - else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO) - strcat (buf, ", fido_a"); - else - { - char const * isa = _("unknown"); - char const * mac = _("unknown mac"); - char const * additional = NULL; - - switch (e_flags & EF_M68K_CF_ISA_MASK) - { - case EF_M68K_CF_ISA_A_NODIV: - isa = "A"; - additional = ", nodiv"; - break; - case EF_M68K_CF_ISA_A: - isa = "A"; - break; - case EF_M68K_CF_ISA_A_PLUS: - isa = "A+"; - break; - case EF_M68K_CF_ISA_B_NOUSP: - isa = "B"; - additional = ", nousp"; - break; - case EF_M68K_CF_ISA_B: - isa = "B"; - break; - case EF_M68K_CF_ISA_C: - isa = "C"; - break; - case EF_M68K_CF_ISA_C_NODIV: - isa = "C"; - additional = ", nodiv"; - break; - } - strcat (buf, ", cf, isa "); - strcat (buf, isa); - if (additional) - strcat (buf, additional); - if (e_flags & EF_M68K_CF_FLOAT) - strcat (buf, ", float"); - switch (e_flags & EF_M68K_CF_MAC_MASK) - { - case 0: - mac = NULL; - break; - case EF_M68K_CF_MAC: - mac = "mac"; - break; - case EF_M68K_CF_EMAC: - mac = "emac"; - break; - case EF_M68K_CF_EMAC_B: - mac = "emac_b"; - break; - } - if (mac) - { - strcat (buf, ", "); - strcat (buf, mac); - } - } - break; - - case EM_PPC: - if (e_flags & EF_PPC_EMB) - strcat (buf, ", emb"); - - if (e_flags & EF_PPC_RELOCATABLE) - strcat (buf, _(", relocatable")); - - if (e_flags & EF_PPC_RELOCATABLE_LIB) - strcat (buf, _(", relocatable-lib")); - break; - - case EM_V850: - case EM_CYGNUS_V850: - switch (e_flags & EF_V850_ARCH) - { - case E_V850E2V3_ARCH: - strcat (buf, ", v850e2v3"); - break; - case E_V850E2_ARCH: - strcat (buf, ", v850e2"); - break; - case E_V850E1_ARCH: - strcat (buf, ", v850e1"); - break; - case E_V850E_ARCH: - strcat (buf, ", v850e"); - break; - case E_V850_ARCH: - strcat (buf, ", v850"); - break; - default: - strcat (buf, _(", unknown v850 architecture variant")); - break; - } - break; - - case EM_M32R: - case EM_CYGNUS_M32R: - if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH) - strcat (buf, ", m32r"); - break; - - case EM_MIPS: - case EM_MIPS_RS3_LE: - if (e_flags & EF_MIPS_NOREORDER) - strcat (buf, ", noreorder"); - - if (e_flags & EF_MIPS_PIC) - strcat (buf, ", pic"); - - if (e_flags & EF_MIPS_CPIC) - strcat (buf, ", cpic"); - - if (e_flags & EF_MIPS_UCODE) - strcat (buf, ", ugen_reserved"); - - if (e_flags & EF_MIPS_ABI2) - strcat (buf, ", abi2"); - - if (e_flags & EF_MIPS_OPTIONS_FIRST) - strcat (buf, ", odk first"); - - if (e_flags & EF_MIPS_32BITMODE) - strcat (buf, ", 32bitmode"); - - switch ((e_flags & EF_MIPS_MACH)) - { - case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break; - case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break; - case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break; - case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break; - case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break; - case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break; - case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break; - case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break; - case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break; - case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break; - case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break; - case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break; - case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; - case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break; - case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break; - case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break; - case 0: - /* We simply ignore the field in this case to avoid confusion: - MIPS ELF does not specify EF_MIPS_MACH, it is a GNU - extension. */ - break; - default: strcat (buf, _(", unknown CPU")); break; - } - - switch ((e_flags & EF_MIPS_ABI)) - { - case E_MIPS_ABI_O32: strcat (buf, ", o32"); break; - case E_MIPS_ABI_O64: strcat (buf, ", o64"); break; - case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break; - case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break; - case 0: - /* We simply ignore the field in this case to avoid confusion: - MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension. - This means it is likely to be an o32 file, but not for - sure. */ - break; - default: strcat (buf, _(", unknown ABI")); break; - } - - if (e_flags & EF_MIPS_ARCH_ASE_MDMX) - strcat (buf, ", mdmx"); - - if (e_flags & EF_MIPS_ARCH_ASE_M16) - strcat (buf, ", mips16"); - - if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) - strcat (buf, ", micromips"); - - switch ((e_flags & EF_MIPS_ARCH)) - { - case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break; - case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break; - case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break; - case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break; - case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break; - case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break; - case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break; - case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break; - case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break; - default: strcat (buf, _(", unknown ISA")); break; - } - - if (e_flags & EF_SH_PIC) - strcat (buf, ", pic"); - - if (e_flags & EF_SH_FDPIC) - strcat (buf, ", fdpic"); - break; - - case EM_SH: - switch ((e_flags & EF_SH_MACH_MASK)) - { - case EF_SH1: strcat (buf, ", sh1"); break; - case EF_SH2: strcat (buf, ", sh2"); break; - case EF_SH3: strcat (buf, ", sh3"); break; - case EF_SH_DSP: strcat (buf, ", sh-dsp"); break; - case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break; - case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break; - case EF_SH3E: strcat (buf, ", sh3e"); break; - case EF_SH4: strcat (buf, ", sh4"); break; - case EF_SH5: strcat (buf, ", sh5"); break; - case EF_SH2E: strcat (buf, ", sh2e"); break; - case EF_SH4A: strcat (buf, ", sh4a"); break; - case EF_SH2A: strcat (buf, ", sh2a"); break; - case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break; - case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break; - case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break; - case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break; - case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break; - case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break; - case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break; - case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break; - case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break; - default: strcat (buf, _(", unknown ISA")); break; - } - - break; - - case EM_SPARCV9: - if (e_flags & EF_SPARC_32PLUS) - strcat (buf, ", v8+"); - - if (e_flags & EF_SPARC_SUN_US1) - strcat (buf, ", ultrasparcI"); - - if (e_flags & EF_SPARC_SUN_US3) - strcat (buf, ", ultrasparcIII"); - - if (e_flags & EF_SPARC_HAL_R1) - strcat (buf, ", halr1"); - - if (e_flags & EF_SPARC_LEDATA) - strcat (buf, ", ledata"); - - if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO) - strcat (buf, ", tso"); - - if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO) - strcat (buf, ", pso"); - - if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO) - strcat (buf, ", rmo"); - break; - - case EM_PARISC: - switch (e_flags & EF_PARISC_ARCH) - { - case EFA_PARISC_1_0: - strcpy (buf, ", PA-RISC 1.0"); - break; - case EFA_PARISC_1_1: - strcpy (buf, ", PA-RISC 1.1"); - break; - case EFA_PARISC_2_0: - strcpy (buf, ", PA-RISC 2.0"); - break; - default: - break; - } - if (e_flags & EF_PARISC_TRAPNIL) - strcat (buf, ", trapnil"); - if (e_flags & EF_PARISC_EXT) - strcat (buf, ", ext"); - if (e_flags & EF_PARISC_LSB) - strcat (buf, ", lsb"); - if (e_flags & EF_PARISC_WIDE) - strcat (buf, ", wide"); - if (e_flags & EF_PARISC_NO_KABP) - strcat (buf, ", no kabp"); - if (e_flags & EF_PARISC_LAZYSWAP) - strcat (buf, ", lazyswap"); - break; - - case EM_PJ: - case EM_PJ_OLD: - if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS) - strcat (buf, ", new calling convention"); - - if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS) - strcat (buf, ", gnu calling convention"); - break; - - case EM_IA_64: - if ((e_flags & EF_IA_64_ABI64)) - strcat (buf, ", 64-bit"); - else - strcat (buf, ", 32-bit"); - if ((e_flags & EF_IA_64_REDUCEDFP)) - strcat (buf, ", reduced fp model"); - if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP)) - strcat (buf, ", no function descriptors, constant gp"); - else if ((e_flags & EF_IA_64_CONS_GP)) - strcat (buf, ", constant gp"); - if ((e_flags & EF_IA_64_ABSOLUTE)) - strcat (buf, ", absolute"); - if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS) - { - if ((e_flags & EF_IA_64_VMS_LINKAGES)) - strcat (buf, ", vms_linkages"); - switch ((e_flags & EF_IA_64_VMS_COMCOD)) - { - case EF_IA_64_VMS_COMCOD_SUCCESS: - break; - case EF_IA_64_VMS_COMCOD_WARNING: - strcat (buf, ", warning"); - break; - case EF_IA_64_VMS_COMCOD_ERROR: - strcat (buf, ", error"); - break; - case EF_IA_64_VMS_COMCOD_ABORT: - strcat (buf, ", abort"); - break; - default: - abort (); - } - } - break; - - case EM_VAX: - if ((e_flags & EF_VAX_NONPIC)) - strcat (buf, ", non-PIC"); - if ((e_flags & EF_VAX_DFLOAT)) - strcat (buf, ", D-Float"); - if ((e_flags & EF_VAX_GFLOAT)) - strcat (buf, ", G-Float"); - break; - - case EM_RX: - if (e_flags & E_FLAG_RX_64BIT_DOUBLES) - strcat (buf, ", 64-bit doubles"); - if (e_flags & E_FLAG_RX_DSP) - strcat (buf, ", dsp"); - - case EM_S390: - if (e_flags & EF_S390_HIGH_GPRS) - strcat (buf, ", highgprs"); - - case EM_TI_C6000: - if ((e_flags & EF_C6000_REL)) - strcat (buf, ", relocatable module"); - } - } - - return buf; -} - -static const char * -get_osabi_name (unsigned int osabi) -{ - static char buff[32]; - - switch (osabi) - { - case ELFOSABI_NONE: return "UNIX - System V"; - case ELFOSABI_HPUX: return "UNIX - HP-UX"; - case ELFOSABI_NETBSD: return "UNIX - NetBSD"; - case ELFOSABI_GNU: return "UNIX - GNU"; - case ELFOSABI_SOLARIS: return "UNIX - Solaris"; - case ELFOSABI_AIX: return "UNIX - AIX"; - case ELFOSABI_IRIX: return "UNIX - IRIX"; - case ELFOSABI_FREEBSD: return "UNIX - FreeBSD"; - case ELFOSABI_TRU64: return "UNIX - TRU64"; - case ELFOSABI_MODESTO: return "Novell - Modesto"; - case ELFOSABI_OPENBSD: return "UNIX - OpenBSD"; - case ELFOSABI_OPENVMS: return "VMS - OpenVMS"; - case ELFOSABI_NSK: return "HP - Non-Stop Kernel"; - case ELFOSABI_AROS: return "AROS"; - case ELFOSABI_FENIXOS: return "FenixOS"; - default: - if (osabi >= 64) - switch (elf_header.e_machine) - { - case EM_ARM: - switch (osabi) - { - case ELFOSABI_ARM: return "ARM"; - default: - break; - } - break; - - case EM_MSP430: - case EM_MSP430_OLD: - switch (osabi) - { - case ELFOSABI_STANDALONE: return _("Standalone App"); - default: - break; - } - break; - - case EM_TI_C6000: - switch (osabi) - { - case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000"); - case ELFOSABI_C6000_LINUX: return "Linux C6000"; - default: - break; - } - break; - - default: - break; - } - snprintf (buff, sizeof (buff), _(""), osabi); - return buff; - } -} - -static const char * -get_arm_segment_type (unsigned long type) -{ - switch (type) - { - case PT_ARM_EXIDX: - return "EXIDX"; - default: - break; - } - - return NULL; -} - -static const char * -get_mips_segment_type (unsigned long type) -{ - switch (type) - { - case PT_MIPS_REGINFO: - return "REGINFO"; - case PT_MIPS_RTPROC: - return "RTPROC"; - case PT_MIPS_OPTIONS: - return "OPTIONS"; - default: - break; - } - - return NULL; -} - -static const char * -get_parisc_segment_type (unsigned long type) -{ - switch (type) - { - case PT_HP_TLS: return "HP_TLS"; - case PT_HP_CORE_NONE: return "HP_CORE_NONE"; - case PT_HP_CORE_VERSION: return "HP_CORE_VERSION"; - case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL"; - case PT_HP_CORE_COMM: return "HP_CORE_COMM"; - case PT_HP_CORE_PROC: return "HP_CORE_PROC"; - case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE"; - case PT_HP_CORE_STACK: return "HP_CORE_STACK"; - case PT_HP_CORE_SHM: return "HP_CORE_SHM"; - case PT_HP_CORE_MMF: return "HP_CORE_MMF"; - case PT_HP_PARALLEL: return "HP_PARALLEL"; - case PT_HP_FASTBIND: return "HP_FASTBIND"; - case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT"; - case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT"; - case PT_HP_STACK: return "HP_STACK"; - case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME"; - case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT"; - case PT_PARISC_UNWIND: return "PARISC_UNWIND"; - case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER"; - default: - break; - } - - return NULL; -} - -static const char * -get_ia64_segment_type (unsigned long type) -{ - switch (type) - { - case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT"; - case PT_IA_64_UNWIND: return "IA_64_UNWIND"; - case PT_HP_TLS: return "HP_TLS"; - case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT"; - case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT"; - case PT_IA_64_HP_STACK: return "HP_STACK"; - default: - break; - } - - return NULL; -} - -static const char * -get_tic6x_segment_type (unsigned long type) -{ - switch (type) - { - case PT_C6000_PHATTR: return "C6000_PHATTR"; - default: - break; - } - - return NULL; -} - -static const char * -get_segment_type (unsigned long p_type) -{ - static char buff[32]; - - switch (p_type) - { - case PT_NULL: return "NULL"; - case PT_LOAD: return "LOAD"; - case PT_DYNAMIC: return "DYNAMIC"; - case PT_INTERP: return "INTERP"; - case PT_NOTE: return "NOTE"; - case PT_SHLIB: return "SHLIB"; - case PT_PHDR: return "PHDR"; - case PT_TLS: return "TLS"; - - case PT_GNU_EH_FRAME: - return "GNU_EH_FRAME"; - case PT_GNU_STACK: return "GNU_STACK"; - case PT_GNU_RELRO: return "GNU_RELRO"; - - default: - if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_ARM: - result = get_arm_segment_type (p_type); - break; - case EM_MIPS: - case EM_MIPS_RS3_LE: - result = get_mips_segment_type (p_type); - break; - case EM_PARISC: - result = get_parisc_segment_type (p_type); - break; - case EM_IA_64: - result = get_ia64_segment_type (p_type); - break; - case EM_TI_C6000: - result = get_tic6x_segment_type (p_type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC); - } - else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS)) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_PARISC: - result = get_parisc_segment_type (p_type); - break; - case EM_IA_64: - result = get_ia64_segment_type (p_type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - sprintf (buff, "LOOS+%lx", p_type - PT_LOOS); - } - else - snprintf (buff, sizeof (buff), _(": %lx"), p_type); - - return buff; - } -} - -static const char * -get_mips_section_type_name (unsigned int sh_type) -{ - switch (sh_type) - { - case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST"; - case SHT_MIPS_MSYM: return "MIPS_MSYM"; - case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT"; - case SHT_MIPS_GPTAB: return "MIPS_GPTAB"; - case SHT_MIPS_UCODE: return "MIPS_UCODE"; - case SHT_MIPS_DEBUG: return "MIPS_DEBUG"; - case SHT_MIPS_REGINFO: return "MIPS_REGINFO"; - case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE"; - case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM"; - case SHT_MIPS_RELD: return "MIPS_RELD"; - case SHT_MIPS_IFACE: return "MIPS_IFACE"; - case SHT_MIPS_CONTENT: return "MIPS_CONTENT"; - case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS"; - case SHT_MIPS_SHDR: return "MIPS_SHDR"; - case SHT_MIPS_FDESC: return "MIPS_FDESC"; - case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM"; - case SHT_MIPS_DENSE: return "MIPS_DENSE"; - case SHT_MIPS_PDESC: return "MIPS_PDESC"; - case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM"; - case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM"; - case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM"; - case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR"; - case SHT_MIPS_LINE: return "MIPS_LINE"; - case SHT_MIPS_RFDESC: return "MIPS_RFDESC"; - case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM"; - case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST"; - case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS"; - case SHT_MIPS_DWARF: return "MIPS_DWARF"; - case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL"; - case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; - case SHT_MIPS_EVENTS: return "MIPS_EVENTS"; - case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE"; - case SHT_MIPS_PIXIE: return "MIPS_PIXIE"; - case SHT_MIPS_XLATE: return "MIPS_XLATE"; - case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG"; - case SHT_MIPS_WHIRL: return "MIPS_WHIRL"; - case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION"; - case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD"; - case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION"; - default: - break; - } - return NULL; -} - -static const char * -get_parisc_section_type_name (unsigned int sh_type) -{ - switch (sh_type) - { - case SHT_PARISC_EXT: return "PARISC_EXT"; - case SHT_PARISC_UNWIND: return "PARISC_UNWIND"; - case SHT_PARISC_DOC: return "PARISC_DOC"; - case SHT_PARISC_ANNOT: return "PARISC_ANNOT"; - case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN"; - case SHT_PARISC_STUBS: return "PARISC_STUBS"; - case SHT_PARISC_DLKM: return "PARISC_DLKM"; - default: - break; - } - return NULL; -} - -static const char * -get_ia64_section_type_name (unsigned int sh_type) -{ - /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */ - if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG) - return get_osabi_name ((sh_type & 0x00FF0000) >> 16); - - switch (sh_type) - { - case SHT_IA_64_EXT: return "IA_64_EXT"; - case SHT_IA_64_UNWIND: return "IA_64_UNWIND"; - case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT"; - case SHT_IA_64_VMS_TRACE: return "VMS_TRACE"; - case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES"; - case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG"; - case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR"; - case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES"; - case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR"; - case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP"; - default: - break; - } - return NULL; -} - -static const char * -get_x86_64_section_type_name (unsigned int sh_type) -{ - switch (sh_type) - { - case SHT_X86_64_UNWIND: return "X86_64_UNWIND"; - default: - break; - } - return NULL; -} - -static const char * -get_arm_section_type_name (unsigned int sh_type) -{ - switch (sh_type) - { - case SHT_ARM_EXIDX: return "ARM_EXIDX"; - case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP"; - case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES"; - case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY"; - case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION"; - default: - break; - } - return NULL; -} - -static const char * -get_tic6x_section_type_name (unsigned int sh_type) -{ - switch (sh_type) - { - case SHT_C6000_UNWIND: - return "C6000_UNWIND"; - case SHT_C6000_PREEMPTMAP: - return "C6000_PREEMPTMAP"; - case SHT_C6000_ATTRIBUTES: - return "C6000_ATTRIBUTES"; - case SHT_TI_ICODE: - return "TI_ICODE"; - case SHT_TI_XREF: - return "TI_XREF"; - case SHT_TI_HANDLER: - return "TI_HANDLER"; - case SHT_TI_INITINFO: - return "TI_INITINFO"; - case SHT_TI_PHATTRS: - return "TI_PHATTRS"; - default: - break; - } - return NULL; -} - -static const char * -get_section_type_name (unsigned int sh_type) -{ - static char buff[32]; - - switch (sh_type) - { - case SHT_NULL: return "NULL"; - case SHT_PROGBITS: return "PROGBITS"; - case SHT_SYMTAB: return "SYMTAB"; - case SHT_STRTAB: return "STRTAB"; - case SHT_RELA: return "RELA"; - case SHT_HASH: return "HASH"; - case SHT_DYNAMIC: return "DYNAMIC"; - case SHT_NOTE: return "NOTE"; - case SHT_NOBITS: return "NOBITS"; - case SHT_REL: return "REL"; - case SHT_SHLIB: return "SHLIB"; - case SHT_DYNSYM: return "DYNSYM"; - case SHT_INIT_ARRAY: return "INIT_ARRAY"; - case SHT_FINI_ARRAY: return "FINI_ARRAY"; - case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY"; - case SHT_GNU_HASH: return "GNU_HASH"; - case SHT_GROUP: return "GROUP"; - case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES"; - case SHT_GNU_verdef: return "VERDEF"; - case SHT_GNU_verneed: return "VERNEED"; - case SHT_GNU_versym: return "VERSYM"; - case 0x6ffffff0: return "VERSYM"; - case 0x6ffffffc: return "VERDEF"; - case 0x7ffffffd: return "AUXILIARY"; - case 0x7fffffff: return "FILTER"; - case SHT_GNU_LIBLIST: return "GNU_LIBLIST"; - - default: - if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC)) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_MIPS: - case EM_MIPS_RS3_LE: - result = get_mips_section_type_name (sh_type); - break; - case EM_PARISC: - result = get_parisc_section_type_name (sh_type); - break; - case EM_IA_64: - result = get_ia64_section_type_name (sh_type); - break; - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - result = get_x86_64_section_type_name (sh_type); - break; - case EM_ARM: - result = get_arm_section_type_name (sh_type); - break; - case EM_TI_C6000: - result = get_tic6x_section_type_name (sh_type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC); - } - else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS)) - { - const char * result; - - switch (elf_header.e_machine) - { - case EM_IA_64: - result = get_ia64_section_type_name (sh_type); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - return result; - - sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS); - } - else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER)) - sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER); - else - /* This message is probably going to be displayed in a 15 - character wide field, so put the hex value first. */ - snprintf (buff, sizeof (buff), _("%08x: "), sh_type); - - return buff; - } -} - -#define OPTION_DEBUG_DUMP 512 -#define OPTION_DYN_SYMS 513 -#define OPTION_DWARF_DEPTH 514 -#define OPTION_DWARF_START 515 - -static struct option options[] = -{ - {"all", no_argument, 0, 'a'}, - {"file-header", no_argument, 0, 'h'}, - {"program-headers", no_argument, 0, 'l'}, - {"headers", no_argument, 0, 'e'}, - {"histogram", no_argument, 0, 'I'}, - {"segments", no_argument, 0, 'l'}, - {"sections", no_argument, 0, 'S'}, - {"section-headers", no_argument, 0, 'S'}, - {"section-groups", no_argument, 0, 'g'}, - {"section-details", no_argument, 0, 't'}, - {"full-section-name",no_argument, 0, 'N'}, - {"symbols", no_argument, 0, 's'}, - {"syms", no_argument, 0, 's'}, - {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS}, - {"relocs", no_argument, 0, 'r'}, - {"notes", no_argument, 0, 'n'}, - {"dynamic", no_argument, 0, 'd'}, - {"arch-specific", no_argument, 0, 'A'}, - {"version-info", no_argument, 0, 'V'}, - {"use-dynamic", no_argument, 0, 'D'}, - {"unwind", no_argument, 0, 'u'}, - {"archive-index", no_argument, 0, 'c'}, - {"hex-dump", required_argument, 0, 'x'}, - {"relocated-dump", required_argument, 0, 'R'}, - {"string-dump", required_argument, 0, 'p'}, -#ifdef SUPPORT_DISASSEMBLY - {"instruction-dump", required_argument, 0, 'i'}, -#endif - {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP}, - - {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH}, - {"dwarf-start", required_argument, 0, OPTION_DWARF_START}, - - {"version", no_argument, 0, 'v'}, - {"wide", no_argument, 0, 'W'}, - {"help", no_argument, 0, 'H'}, - {0, no_argument, 0, 0} -}; - -static void -usage (FILE * stream) -{ - fprintf (stream, _("Usage: readelf elf-file(s)\n")); - fprintf (stream, _(" Display information about the contents of ELF format files\n")); - fprintf (stream, _(" Options are:\n\ - -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\ - -h --file-header Display the ELF file header\n\ - -l --program-headers Display the program headers\n\ - --segments An alias for --program-headers\n\ - -S --section-headers Display the sections' header\n\ - --sections An alias for --section-headers\n\ - -g --section-groups Display the section groups\n\ - -t --section-details Display the section details\n\ - -e --headers Equivalent to: -h -l -S\n\ - -s --syms Display the symbol table\n\ - --symbols An alias for --syms\n\ - --dyn-syms Display the dynamic symbol table\n\ - -n --notes Display the core notes (if present)\n\ - -r --relocs Display the relocations (if present)\n\ - -u --unwind Display the unwind info (if present)\n\ - -d --dynamic Display the dynamic section (if present)\n\ - -V --version-info Display the version sections (if present)\n\ - -A --arch-specific Display architecture specific information (if any).\n\ - -c --archive-index Display the symbol/file index in an archive\n\ - -D --use-dynamic Use the dynamic section info when displaying symbols\n\ - -x --hex-dump=\n\ - Dump the contents of section as bytes\n\ - -p --string-dump=\n\ - Dump the contents of section as strings\n\ - -R --relocated-dump=\n\ - Dump the contents of section as relocated bytes\n\ - -w[lLiaprmfFsoRt] or\n\ - --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ - =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\ - =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\ - Display the contents of DWARF2 debug sections\n")); - fprintf (stream, _("\ - --dwarf-depth=N Do not display DIEs at depth N or greater\n\ - --dwarf-start=N Display DIEs starting with N, at the same depth\n\ - or deeper\n")); -#ifdef SUPPORT_DISASSEMBLY - fprintf (stream, _("\ - -i --instruction-dump=\n\ - Disassemble the contents of section \n")); -#endif - fprintf (stream, _("\ - -I --histogram Display histogram of bucket list lengths\n\ - -W --wide Allow output width to exceed 80 characters\n\ - @ Read options from \n\ - -H --help Display this information\n\ - -v --version Display the version number of readelf\n")); - - if (REPORT_BUGS_TO[0] && stream == stdout) - fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO); - - exit (stream == stdout ? 0 : 1); -} - -/* Record the fact that the user wants the contents of section number - SECTION to be displayed using the method(s) encoded as flags bits - in TYPE. Note, TYPE can be zero if we are creating the array for - the first time. */ - -static void -request_dump_bynumber (unsigned int section, dump_type type) -{ - if (section >= num_dump_sects) - { - dump_type * new_dump_sects; - - new_dump_sects = (dump_type *) calloc (section + 1, - sizeof (* dump_sects)); - - if (new_dump_sects == NULL) - error (_("Out of memory allocating dump request table.\n")); - else - { - /* Copy current flag settings. */ - memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects)); - - free (dump_sects); - - dump_sects = new_dump_sects; - num_dump_sects = section + 1; - } - } - - if (dump_sects) - dump_sects[section] |= type; - - return; -} - -/* Request a dump by section name. */ - -static void -request_dump_byname (const char * section, dump_type type) -{ - struct dump_list_entry * new_request; - - new_request = (struct dump_list_entry *) - malloc (sizeof (struct dump_list_entry)); - if (!new_request) - error (_("Out of memory allocating dump request table.\n")); - - new_request->name = strdup (section); - if (!new_request->name) - error (_("Out of memory allocating dump request table.\n")); - - new_request->type = type; - - new_request->next = dump_sects_byname; - dump_sects_byname = new_request; -} - -static inline void -request_dump (dump_type type) -{ - int section; - char * cp; - - do_dump++; - section = strtoul (optarg, & cp, 0); - - if (! *cp && section >= 0) - request_dump_bynumber (section, type); - else - request_dump_byname (optarg, type); -} - - -static void -parse_args (int argc, char ** argv) -{ - int c; - - if (argc < 2) - usage (stderr); - - while ((c = getopt_long - (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF) - { - switch (c) - { - case 0: - /* Long options. */ - break; - case 'H': - usage (stdout); - break; - - case 'a': - do_syms++; - do_reloc++; - do_unwind++; - do_dynamic++; - do_header++; - do_sections++; - do_section_groups++; - do_segments++; - do_version++; - do_histogram++; - do_arch++; - do_notes++; - break; - case 'g': - do_section_groups++; - break; - case 't': - case 'N': - do_sections++; - do_section_details++; - break; - case 'e': - do_header++; - do_sections++; - do_segments++; - break; - case 'A': - do_arch++; - break; - case 'D': - do_using_dynamic++; - break; - case 'r': - do_reloc++; - break; - case 'u': - do_unwind++; - break; - case 'h': - do_header++; - break; - case 'l': - do_segments++; - break; - case 's': - do_syms++; - break; - case 'S': - do_sections++; - break; - case 'd': - do_dynamic++; - break; - case 'I': - do_histogram++; - break; - case 'n': - do_notes++; - break; - case 'c': - do_archive_index++; - break; - case 'x': - request_dump (HEX_DUMP); - break; - case 'p': - request_dump (STRING_DUMP); - break; - case 'R': - request_dump (RELOC_DUMP); - break; - case 'w': - do_dump++; - if (optarg == 0) - { - do_debugging = 1; - dwarf_select_sections_all (); - } - else - { - do_debugging = 0; - dwarf_select_sections_by_letters (optarg); - } - break; - case OPTION_DEBUG_DUMP: - do_dump++; - if (optarg == 0) - do_debugging = 1; - else - { - do_debugging = 0; - dwarf_select_sections_by_names (optarg); - } - break; - case OPTION_DWARF_DEPTH: - { - char *cp; - - dwarf_cutoff_level = strtoul (optarg, & cp, 0); - } - break; - case OPTION_DWARF_START: - { - char *cp; - - dwarf_start_die = strtoul (optarg, & cp, 0); - } - break; - case OPTION_DYN_SYMS: - do_dyn_syms++; - break; -#ifdef SUPPORT_DISASSEMBLY - case 'i': - request_dump (DISASS_DUMP); - break; -#endif - case 'v': - print_version (program_name); - break; - case 'V': - do_version++; - break; - case 'W': - do_wide++; - break; - default: - /* xgettext:c-format */ - error (_("Invalid option '-%c'\n"), c); - /* Drop through. */ - case '?': - usage (stderr); - } - } - - if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections - && !do_segments && !do_header && !do_dump && !do_version - && !do_histogram && !do_debugging && !do_arch && !do_notes - && !do_section_groups && !do_archive_index - && !do_dyn_syms) - usage (stderr); - else if (argc < 3) - { - warn (_("Nothing to do.\n")); - usage (stderr); - } -} - -static const char * -get_elf_class (unsigned int elf_class) -{ - static char buff[32]; - - switch (elf_class) - { - case ELFCLASSNONE: return _("none"); - case ELFCLASS32: return "ELF32"; - case ELFCLASS64: return "ELF64"; - default: - snprintf (buff, sizeof (buff), _(""), elf_class); - return buff; - } -} - -static const char * -get_data_encoding (unsigned int encoding) -{ - static char buff[32]; - - switch (encoding) - { - case ELFDATANONE: return _("none"); - case ELFDATA2LSB: return _("2's complement, little endian"); - case ELFDATA2MSB: return _("2's complement, big endian"); - default: - snprintf (buff, sizeof (buff), _(""), encoding); - return buff; - } -} - -/* Decode the data held in 'elf_header'. */ - -static int -process_file_header (void) -{ - if ( elf_header.e_ident[EI_MAG0] != ELFMAG0 - || elf_header.e_ident[EI_MAG1] != ELFMAG1 - || elf_header.e_ident[EI_MAG2] != ELFMAG2 - || elf_header.e_ident[EI_MAG3] != ELFMAG3) - { - error - (_("Not an ELF file - it has the wrong magic bytes at the start\n")); - return 0; - } - - init_dwarf_regnames (elf_header.e_machine); - - if (do_header) - { - int i; - - printf (_("ELF Header:\n")); - printf (_(" Magic: ")); - for (i = 0; i < EI_NIDENT; i++) - printf ("%2.2x ", elf_header.e_ident[i]); - printf ("\n"); - printf (_(" Class: %s\n"), - get_elf_class (elf_header.e_ident[EI_CLASS])); - printf (_(" Data: %s\n"), - get_data_encoding (elf_header.e_ident[EI_DATA])); - printf (_(" Version: %d %s\n"), - elf_header.e_ident[EI_VERSION], - (elf_header.e_ident[EI_VERSION] == EV_CURRENT - ? "(current)" - : (elf_header.e_ident[EI_VERSION] != EV_NONE - ? _("") - : ""))); - printf (_(" OS/ABI: %s\n"), - get_osabi_name (elf_header.e_ident[EI_OSABI])); - printf (_(" ABI Version: %d\n"), - elf_header.e_ident[EI_ABIVERSION]); - printf (_(" Type: %s\n"), - get_file_type (elf_header.e_type)); - printf (_(" Machine: %s\n"), - get_machine_name (elf_header.e_machine)); - printf (_(" Version: 0x%lx\n"), - (unsigned long) elf_header.e_version); - - printf (_(" Entry point address: ")); - print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX); - printf (_("\n Start of program headers: ")); - print_vma ((bfd_vma) elf_header.e_phoff, DEC); - printf (_(" (bytes into file)\n Start of section headers: ")); - print_vma ((bfd_vma) elf_header.e_shoff, DEC); - printf (_(" (bytes into file)\n")); - - printf (_(" Flags: 0x%lx%s\n"), - (unsigned long) elf_header.e_flags, - get_machine_flags (elf_header.e_flags, elf_header.e_machine)); - printf (_(" Size of this header: %ld (bytes)\n"), - (long) elf_header.e_ehsize); - printf (_(" Size of program headers: %ld (bytes)\n"), - (long) elf_header.e_phentsize); - printf (_(" Number of program headers: %ld"), - (long) elf_header.e_phnum); - if (section_headers != NULL - && elf_header.e_phnum == PN_XNUM - && section_headers[0].sh_info != 0) - printf (" (%ld)", (long) section_headers[0].sh_info); - putc ('\n', stdout); - printf (_(" Size of section headers: %ld (bytes)\n"), - (long) elf_header.e_shentsize); - printf (_(" Number of section headers: %ld"), - (long) elf_header.e_shnum); - if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF) - printf (" (%ld)", (long) section_headers[0].sh_size); - putc ('\n', stdout); - printf (_(" Section header string table index: %ld"), - (long) elf_header.e_shstrndx); - if (section_headers != NULL - && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff)) - printf (" (%u)", section_headers[0].sh_link); - else if (elf_header.e_shstrndx != SHN_UNDEF - && elf_header.e_shstrndx >= elf_header.e_shnum) - printf (_(" ")); - putc ('\n', stdout); - } - - if (section_headers != NULL) - { - if (elf_header.e_phnum == PN_XNUM - && section_headers[0].sh_info != 0) - elf_header.e_phnum = section_headers[0].sh_info; - if (elf_header.e_shnum == SHN_UNDEF) - elf_header.e_shnum = section_headers[0].sh_size; - if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff)) - elf_header.e_shstrndx = section_headers[0].sh_link; - else if (elf_header.e_shstrndx >= elf_header.e_shnum) - elf_header.e_shstrndx = SHN_UNDEF; - free (section_headers); - section_headers = NULL; - } - - return 1; -} - - -static int -get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders) -{ - Elf32_External_Phdr * phdrs; - Elf32_External_Phdr * external; - Elf_Internal_Phdr * internal; - unsigned int i; - - phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff, - elf_header.e_phentsize, - elf_header.e_phnum, - _("program headers")); - if (!phdrs) - return 0; - - for (i = 0, internal = pheaders, external = phdrs; - i < elf_header.e_phnum; - i++, internal++, external++) - { - internal->p_type = BYTE_GET (external->p_type); - internal->p_offset = BYTE_GET (external->p_offset); - internal->p_vaddr = BYTE_GET (external->p_vaddr); - internal->p_paddr = BYTE_GET (external->p_paddr); - internal->p_filesz = BYTE_GET (external->p_filesz); - internal->p_memsz = BYTE_GET (external->p_memsz); - internal->p_flags = BYTE_GET (external->p_flags); - internal->p_align = BYTE_GET (external->p_align); - } - - free (phdrs); - - return 1; -} - -static int -get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders) -{ - Elf64_External_Phdr * phdrs; - Elf64_External_Phdr * external; - Elf_Internal_Phdr * internal; - unsigned int i; - - phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff, - elf_header.e_phentsize, - elf_header.e_phnum, - _("program headers")); - if (!phdrs) - return 0; - - for (i = 0, internal = pheaders, external = phdrs; - i < elf_header.e_phnum; - i++, internal++, external++) - { - internal->p_type = BYTE_GET (external->p_type); - internal->p_flags = BYTE_GET (external->p_flags); - internal->p_offset = BYTE_GET (external->p_offset); - internal->p_vaddr = BYTE_GET (external->p_vaddr); - internal->p_paddr = BYTE_GET (external->p_paddr); - internal->p_filesz = BYTE_GET (external->p_filesz); - internal->p_memsz = BYTE_GET (external->p_memsz); - internal->p_align = BYTE_GET (external->p_align); - } - - free (phdrs); - - return 1; -} - -/* Returns 1 if the program headers were read into `program_headers'. */ - -static int -get_program_headers (FILE * file) -{ - Elf_Internal_Phdr * phdrs; - - /* Check cache of prior read. */ - if (program_headers != NULL) - return 1; - - phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum, - sizeof (Elf_Internal_Phdr)); - - if (phdrs == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - if (is_32bit_elf - ? get_32bit_program_headers (file, phdrs) - : get_64bit_program_headers (file, phdrs)) - { - program_headers = phdrs; - return 1; - } - - free (phdrs); - return 0; -} - -/* Returns 1 if the program headers were loaded. */ - -static int -process_program_headers (FILE * file) -{ - Elf_Internal_Phdr * segment; - unsigned int i; - - if (elf_header.e_phnum == 0) - { - /* PR binutils/12467. */ - if (elf_header.e_phoff != 0) - warn (_("possibly corrupt ELF header - it has a non-zero program" - " header offset, but no program headers")); - else if (do_segments) - printf (_("\nThere are no program headers in this file.\n")); - return 0; - } - - if (do_segments && !do_header) - { - printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type)); - printf (_("Entry point ")); - print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX); - printf (_("\nThere are %d program headers, starting at offset "), - elf_header.e_phnum); - print_vma ((bfd_vma) elf_header.e_phoff, DEC); - printf ("\n"); - } - - if (! get_program_headers (file)) - return 0; - - if (do_segments) - { - if (elf_header.e_phnum > 1) - printf (_("\nProgram Headers:\n")); - else - printf (_("\nProgram Headers:\n")); - - if (is_32bit_elf) - printf - (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n")); - else if (do_wide) - printf - (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n")); - else - { - printf - (_(" Type Offset VirtAddr PhysAddr\n")); - printf - (_(" FileSiz MemSiz Flags Align\n")); - } - } - - dynamic_addr = 0; - dynamic_size = 0; - - for (i = 0, segment = program_headers; - i < elf_header.e_phnum; - i++, segment++) - { - if (do_segments) - { - printf (" %-14.14s ", get_segment_type (segment->p_type)); - - if (is_32bit_elf) - { - printf ("0x%6.6lx ", (unsigned long) segment->p_offset); - printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr); - printf ("0x%8.8lx ", (unsigned long) segment->p_paddr); - printf ("0x%5.5lx ", (unsigned long) segment->p_filesz); - printf ("0x%5.5lx ", (unsigned long) segment->p_memsz); - printf ("%c%c%c ", - (segment->p_flags & PF_R ? 'R' : ' '), - (segment->p_flags & PF_W ? 'W' : ' '), - (segment->p_flags & PF_X ? 'E' : ' ')); - printf ("%#lx", (unsigned long) segment->p_align); - } - else if (do_wide) - { - if ((unsigned long) segment->p_offset == segment->p_offset) - printf ("0x%6.6lx ", (unsigned long) segment->p_offset); - else - { - print_vma (segment->p_offset, FULL_HEX); - putchar (' '); - } - - print_vma (segment->p_vaddr, FULL_HEX); - putchar (' '); - print_vma (segment->p_paddr, FULL_HEX); - putchar (' '); - - if ((unsigned long) segment->p_filesz == segment->p_filesz) - printf ("0x%6.6lx ", (unsigned long) segment->p_filesz); - else - { - print_vma (segment->p_filesz, FULL_HEX); - putchar (' '); - } - - if ((unsigned long) segment->p_memsz == segment->p_memsz) - printf ("0x%6.6lx", (unsigned long) segment->p_memsz); - else - { - print_vma (segment->p_offset, FULL_HEX); - } - - printf (" %c%c%c ", - (segment->p_flags & PF_R ? 'R' : ' '), - (segment->p_flags & PF_W ? 'W' : ' '), - (segment->p_flags & PF_X ? 'E' : ' ')); - - if ((unsigned long) segment->p_align == segment->p_align) - printf ("%#lx", (unsigned long) segment->p_align); - else - { - print_vma (segment->p_align, PREFIX_HEX); - } - } - else - { - print_vma (segment->p_offset, FULL_HEX); - putchar (' '); - print_vma (segment->p_vaddr, FULL_HEX); - putchar (' '); - print_vma (segment->p_paddr, FULL_HEX); - printf ("\n "); - print_vma (segment->p_filesz, FULL_HEX); - putchar (' '); - print_vma (segment->p_memsz, FULL_HEX); - printf (" %c%c%c ", - (segment->p_flags & PF_R ? 'R' : ' '), - (segment->p_flags & PF_W ? 'W' : ' '), - (segment->p_flags & PF_X ? 'E' : ' ')); - print_vma (segment->p_align, HEX); - } - } - - switch (segment->p_type) - { - case PT_DYNAMIC: - if (dynamic_addr) - error (_("more than one dynamic segment\n")); - - /* By default, assume that the .dynamic section is the first - section in the DYNAMIC segment. */ - dynamic_addr = segment->p_offset; - dynamic_size = segment->p_filesz; - - /* Try to locate the .dynamic section. If there is - a section header table, we can easily locate it. */ - if (section_headers != NULL) - { - Elf_Internal_Shdr * sec; - - sec = find_section (".dynamic"); - if (sec == NULL || sec->sh_size == 0) - { - /* A corresponding .dynamic section is expected, but on - IA-64/OpenVMS it is OK for it to be missing. */ - if (!is_ia64_vms ()) - error (_("no .dynamic section in the dynamic segment\n")); - break; - } - - if (sec->sh_type == SHT_NOBITS) - { - dynamic_size = 0; - break; - } - - dynamic_addr = sec->sh_offset; - dynamic_size = sec->sh_size; - - if (dynamic_addr < segment->p_offset - || dynamic_addr > segment->p_offset + segment->p_filesz) - warn (_("the .dynamic section is not contained" - " within the dynamic segment\n")); - else if (dynamic_addr > segment->p_offset) - warn (_("the .dynamic section is not the first section" - " in the dynamic segment.\n")); - } - break; - - case PT_INTERP: - if (fseek (file, archive_file_offset + (long) segment->p_offset, - SEEK_SET)) - error (_("Unable to find program interpreter name\n")); - else - { - char fmt [32]; - int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX); - - if (ret >= (int) sizeof (fmt) || ret < 0) - error (_("Internal error: failed to create format string to display program interpreter\n")); - - program_interpreter[0] = 0; - if (fscanf (file, fmt, program_interpreter) <= 0) - error (_("Unable to read program interpreter name\n")); - - if (do_segments) - printf (_("\n [Requesting program interpreter: %s]"), - program_interpreter); - } - break; - } - - if (do_segments) - putc ('\n', stdout); - } - - if (do_segments && section_headers != NULL && string_table != NULL) - { - printf (_("\n Section to Segment mapping:\n")); - printf (_(" Segment Sections...\n")); - - for (i = 0; i < elf_header.e_phnum; i++) - { - unsigned int j; - Elf_Internal_Shdr * section; - - segment = program_headers + i; - section = section_headers + 1; - - printf (" %2.2d ", i); - - for (j = 1; j < elf_header.e_shnum; j++, section++) - { - if (!ELF_TBSS_SPECIAL (section, segment) - && ELF_SECTION_IN_SEGMENT_STRICT (section, segment)) - printf ("%s ", SECTION_NAME (section)); - } - - putc ('\n',stdout); - } - } - - return 1; -} - - -/* Find the file offset corresponding to VMA by using the program headers. */ - -static long -offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size) -{ - Elf_Internal_Phdr * seg; - - if (! get_program_headers (file)) - { - warn (_("Cannot interpret virtual addresses without program headers.\n")); - return (long) vma; - } - - for (seg = program_headers; - seg < program_headers + elf_header.e_phnum; - ++seg) - { - if (seg->p_type != PT_LOAD) - continue; - - if (vma >= (seg->p_vaddr & -seg->p_align) - && vma + size <= seg->p_vaddr + seg->p_filesz) - return vma - seg->p_vaddr + seg->p_offset; - } - - warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"), - (unsigned long) vma); - return (long) vma; -} - - -static int -get_32bit_section_headers (FILE * file, unsigned int num) -{ - Elf32_External_Shdr * shdrs; - Elf_Internal_Shdr * internal; - unsigned int i; - - shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff, - elf_header.e_shentsize, num, - _("section headers")); - if (!shdrs) - return 0; - - section_headers = (Elf_Internal_Shdr *) cmalloc (num, - sizeof (Elf_Internal_Shdr)); - - if (section_headers == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - for (i = 0, internal = section_headers; - i < num; - i++, internal++) - { - internal->sh_name = BYTE_GET (shdrs[i].sh_name); - internal->sh_type = BYTE_GET (shdrs[i].sh_type); - internal->sh_flags = BYTE_GET (shdrs[i].sh_flags); - internal->sh_addr = BYTE_GET (shdrs[i].sh_addr); - internal->sh_offset = BYTE_GET (shdrs[i].sh_offset); - internal->sh_size = BYTE_GET (shdrs[i].sh_size); - internal->sh_link = BYTE_GET (shdrs[i].sh_link); - internal->sh_info = BYTE_GET (shdrs[i].sh_info); - internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign); - internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize); - } - - free (shdrs); - - return 1; -} - -static int -get_64bit_section_headers (FILE * file, unsigned int num) -{ - Elf64_External_Shdr * shdrs; - Elf_Internal_Shdr * internal; - unsigned int i; - - shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff, - elf_header.e_shentsize, num, - _("section headers")); - if (!shdrs) - return 0; - - section_headers = (Elf_Internal_Shdr *) cmalloc (num, - sizeof (Elf_Internal_Shdr)); - - if (section_headers == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - for (i = 0, internal = section_headers; - i < num; - i++, internal++) - { - internal->sh_name = BYTE_GET (shdrs[i].sh_name); - internal->sh_type = BYTE_GET (shdrs[i].sh_type); - internal->sh_flags = BYTE_GET (shdrs[i].sh_flags); - internal->sh_addr = BYTE_GET (shdrs[i].sh_addr); - internal->sh_size = BYTE_GET (shdrs[i].sh_size); - internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize); - internal->sh_link = BYTE_GET (shdrs[i].sh_link); - internal->sh_info = BYTE_GET (shdrs[i].sh_info); - internal->sh_offset = BYTE_GET (shdrs[i].sh_offset); - internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign); - } - - free (shdrs); - - return 1; -} - -static Elf_Internal_Sym * -get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) -{ - unsigned long number; - Elf32_External_Sym * esyms = NULL; - Elf_External_Sym_Shndx * shndx; - Elf_Internal_Sym * isyms = NULL; - Elf_Internal_Sym * psym; - unsigned int j; - - /* Run some sanity checks first. */ - if (section->sh_entsize == 0) - { - error (_("sh_entsize is zero\n")); - return NULL; - } - - number = section->sh_size / section->sh_entsize; - - if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1) - { - error (_("Invalid sh_entsize\n")); - return NULL; - } - - esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1, - section->sh_size, _("symbols")); - if (esyms == NULL) - return NULL; - - shndx = NULL; - if (symtab_shndx_hdr != NULL - && (symtab_shndx_hdr->sh_link - == (unsigned long) (section - section_headers))) - { - shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file, - symtab_shndx_hdr->sh_offset, - 1, symtab_shndx_hdr->sh_size, - _("symtab shndx")); - if (shndx == NULL) - goto exit_point; - } - - isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym)); - - if (isyms == NULL) - { - error (_("Out of memory\n")); - goto exit_point; - } - - for (j = 0, psym = isyms; j < number; j++, psym++) - { - psym->st_name = BYTE_GET (esyms[j].st_name); - psym->st_value = BYTE_GET (esyms[j].st_value); - psym->st_size = BYTE_GET (esyms[j].st_size); - psym->st_shndx = BYTE_GET (esyms[j].st_shndx); - if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL) - psym->st_shndx - = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); - else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff)) - psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); - psym->st_info = BYTE_GET (esyms[j].st_info); - psym->st_other = BYTE_GET (esyms[j].st_other); - } - - exit_point: - if (shndx) - free (shndx); - if (esyms) - free (esyms); - - return isyms; -} - -static Elf_Internal_Sym * -get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section) -{ - unsigned long number; - Elf64_External_Sym * esyms; - Elf_External_Sym_Shndx * shndx; - Elf_Internal_Sym * isyms; - Elf_Internal_Sym * psym; - unsigned int j; - - /* Run some sanity checks first. */ - if (section->sh_entsize == 0) - { - error (_("sh_entsize is zero\n")); - return NULL; - } - - number = section->sh_size / section->sh_entsize; - - if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1) - { - error (_("Invalid sh_entsize\n")); - return NULL; - } - - esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1, - section->sh_size, _("symbols")); - if (!esyms) - return NULL; - - shndx = NULL; - if (symtab_shndx_hdr != NULL - && (symtab_shndx_hdr->sh_link - == (unsigned long) (section - section_headers))) - { - shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file, - symtab_shndx_hdr->sh_offset, - 1, symtab_shndx_hdr->sh_size, - _("symtab shndx")); - if (!shndx) - { - free (esyms); - return NULL; - } - } - - isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym)); - - if (isyms == NULL) - { - error (_("Out of memory\n")); - if (shndx) - free (shndx); - free (esyms); - return NULL; - } - - for (j = 0, psym = isyms; - j < number; - j++, psym++) - { - psym->st_name = BYTE_GET (esyms[j].st_name); - psym->st_info = BYTE_GET (esyms[j].st_info); - psym->st_other = BYTE_GET (esyms[j].st_other); - psym->st_shndx = BYTE_GET (esyms[j].st_shndx); - if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL) - psym->st_shndx - = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j])); - else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff)) - psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff); - psym->st_value = BYTE_GET (esyms[j].st_value); - psym->st_size = BYTE_GET (esyms[j].st_size); - } - - if (shndx) - free (shndx); - free (esyms); - - return isyms; -} - -static const char * -get_elf_section_flags (bfd_vma sh_flags) -{ - static char buff[1024]; - char * p = buff; - int field_size = is_32bit_elf ? 8 : 16; - int sindex; - int size = sizeof (buff) - (field_size + 4 + 1); - bfd_vma os_flags = 0; - bfd_vma proc_flags = 0; - bfd_vma unknown_flags = 0; - static const struct - { - const char * str; - int len; - } - flags [] = - { - /* 0 */ { STRING_COMMA_LEN ("WRITE") }, - /* 1 */ { STRING_COMMA_LEN ("ALLOC") }, - /* 2 */ { STRING_COMMA_LEN ("EXEC") }, - /* 3 */ { STRING_COMMA_LEN ("MERGE") }, - /* 4 */ { STRING_COMMA_LEN ("STRINGS") }, - /* 5 */ { STRING_COMMA_LEN ("INFO LINK") }, - /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") }, - /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") }, - /* 8 */ { STRING_COMMA_LEN ("GROUP") }, - /* 9 */ { STRING_COMMA_LEN ("TLS") }, - /* IA-64 specific. */ - /* 10 */ { STRING_COMMA_LEN ("SHORT") }, - /* 11 */ { STRING_COMMA_LEN ("NORECOV") }, - /* IA-64 OpenVMS specific. */ - /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") }, - /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") }, - /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") }, - /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") }, - /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") }, - /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") }, - /* Generic. */ - /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") }, - /* SPARC specific. */ - /* 19 */ { STRING_COMMA_LEN ("ORDERED") } - }; - - if (do_section_details) - { - sprintf (buff, "[%*.*lx]: ", - field_size, field_size, (unsigned long) sh_flags); - p += field_size + 4; - } - - while (sh_flags) - { - bfd_vma flag; - - flag = sh_flags & - sh_flags; - sh_flags &= ~ flag; - - if (do_section_details) - { - switch (flag) - { - case SHF_WRITE: sindex = 0; break; - case SHF_ALLOC: sindex = 1; break; - case SHF_EXECINSTR: sindex = 2; break; - case SHF_MERGE: sindex = 3; break; - case SHF_STRINGS: sindex = 4; break; - case SHF_INFO_LINK: sindex = 5; break; - case SHF_LINK_ORDER: sindex = 6; break; - case SHF_OS_NONCONFORMING: sindex = 7; break; - case SHF_GROUP: sindex = 8; break; - case SHF_TLS: sindex = 9; break; - case SHF_EXCLUDE: sindex = 18; break; - - default: - sindex = -1; - switch (elf_header.e_machine) - { - case EM_IA_64: - if (flag == SHF_IA_64_SHORT) - sindex = 10; - else if (flag == SHF_IA_64_NORECOV) - sindex = 11; -#ifdef BFD64 - else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS) - switch (flag) - { - case SHF_IA_64_VMS_GLOBAL: sindex = 12; break; - case SHF_IA_64_VMS_OVERLAID: sindex = 13; break; - case SHF_IA_64_VMS_SHARED: sindex = 14; break; - case SHF_IA_64_VMS_VECTOR: sindex = 15; break; - case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break; - case SHF_IA_64_VMS_PROTECTED: sindex = 17; break; - default: break; - } -#endif - break; - - case EM_386: - case EM_486: - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - case EM_OLD_SPARCV9: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - if (flag == SHF_ORDERED) - sindex = 19; - break; - default: - break; - } - } - - if (sindex != -1) - { - if (p != buff + field_size + 4) - { - if (size < (10 + 2)) - abort (); - size -= 2; - *p++ = ','; - *p++ = ' '; - } - - size -= flags [sindex].len; - p = stpcpy (p, flags [sindex].str); - } - else if (flag & SHF_MASKOS) - os_flags |= flag; - else if (flag & SHF_MASKPROC) - proc_flags |= flag; - else - unknown_flags |= flag; - } - else - { - switch (flag) - { - case SHF_WRITE: *p = 'W'; break; - case SHF_ALLOC: *p = 'A'; break; - case SHF_EXECINSTR: *p = 'X'; break; - case SHF_MERGE: *p = 'M'; break; - case SHF_STRINGS: *p = 'S'; break; - case SHF_INFO_LINK: *p = 'I'; break; - case SHF_LINK_ORDER: *p = 'L'; break; - case SHF_OS_NONCONFORMING: *p = 'O'; break; - case SHF_GROUP: *p = 'G'; break; - case SHF_TLS: *p = 'T'; break; - case SHF_EXCLUDE: *p = 'E'; break; - - default: - if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM - || elf_header.e_machine == EM_K1OM) - && flag == SHF_X86_64_LARGE) - *p = 'l'; - else if (flag & SHF_MASKOS) - { - *p = 'o'; - sh_flags &= ~ SHF_MASKOS; - } - else if (flag & SHF_MASKPROC) - { - *p = 'p'; - sh_flags &= ~ SHF_MASKPROC; - } - else - *p = 'x'; - break; - } - p++; - } - } - - if (do_section_details) - { - if (os_flags) - { - size -= 5 + field_size; - if (p != buff + field_size + 4) - { - if (size < (2 + 1)) - abort (); - size -= 2; - *p++ = ','; - *p++ = ' '; - } - sprintf (p, "OS (%*.*lx)", field_size, field_size, - (unsigned long) os_flags); - p += 5 + field_size; - } - if (proc_flags) - { - size -= 7 + field_size; - if (p != buff + field_size + 4) - { - if (size < (2 + 1)) - abort (); - size -= 2; - *p++ = ','; - *p++ = ' '; - } - sprintf (p, "PROC (%*.*lx)", field_size, field_size, - (unsigned long) proc_flags); - p += 7 + field_size; - } - if (unknown_flags) - { - size -= 10 + field_size; - if (p != buff + field_size + 4) - { - if (size < (2 + 1)) - abort (); - size -= 2; - *p++ = ','; - *p++ = ' '; - } - sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size, - (unsigned long) unknown_flags); - p += 10 + field_size; - } - } - - *p = '\0'; - return buff; -} - -static int -process_section_headers (FILE * file) -{ - Elf_Internal_Shdr * section; - unsigned int i; - - section_headers = NULL; - - if (elf_header.e_shnum == 0) - { - /* PR binutils/12467. */ - if (elf_header.e_shoff != 0) - warn (_("possibly corrupt ELF file header - it has a non-zero" - " section header offset, but no section headers\n")); - else if (do_sections) - printf (_("\nThere are no sections in this file.\n")); - - return 1; - } - - if (do_sections && !do_header) - printf (_("There are %d section headers, starting at offset 0x%lx:\n"), - elf_header.e_shnum, (unsigned long) elf_header.e_shoff); - - if (is_32bit_elf) - { - if (! get_32bit_section_headers (file, elf_header.e_shnum)) - return 0; - } - else if (! get_64bit_section_headers (file, elf_header.e_shnum)) - return 0; - - /* Read in the string table, so that we have names to display. */ - if (elf_header.e_shstrndx != SHN_UNDEF - && elf_header.e_shstrndx < elf_header.e_shnum) - { - section = section_headers + elf_header.e_shstrndx; - - if (section->sh_size != 0) - { - string_table = (char *) get_data (NULL, file, section->sh_offset, - 1, section->sh_size, - _("string table")); - - string_table_length = string_table != NULL ? section->sh_size : 0; - } - } - - /* Scan the sections for the dynamic symbol table - and dynamic string table and debug sections. */ - dynamic_symbols = NULL; - dynamic_strings = NULL; - dynamic_syminfo = NULL; - symtab_shndx_hdr = NULL; - - eh_addr_size = is_32bit_elf ? 4 : 8; - switch (elf_header.e_machine) - { - case EM_MIPS: - case EM_MIPS_RS3_LE: - /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit - FDE addresses. However, the ABI also has a semi-official ILP32 - variant for which the normal FDE address size rules apply. - - GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX - section, where XX is the size of longs in bits. Unfortunately, - earlier compilers provided no way of distinguishing ILP32 objects - from LP64 objects, so if there's any doubt, we should assume that - the official LP64 form is being used. */ - if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64 - && find_section (".gcc_compiled_long32") == NULL) - eh_addr_size = 8; - break; - - case EM_H8_300: - case EM_H8_300H: - switch (elf_header.e_flags & EF_H8_MACH) - { - case E_H8_MACH_H8300: - case E_H8_MACH_H8300HN: - case E_H8_MACH_H8300SN: - case E_H8_MACH_H8300SXN: - eh_addr_size = 2; - break; - case E_H8_MACH_H8300H: - case E_H8_MACH_H8300S: - case E_H8_MACH_H8300SX: - eh_addr_size = 4; - break; - } - break; - - case EM_M32C_OLD: - case EM_M32C: - switch (elf_header.e_flags & EF_M32C_CPU_MASK) - { - case EF_M32C_CPU_M16C: - eh_addr_size = 2; - break; - } - break; - } - -#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \ - do \ - { \ - size_t expected_entsize \ - = is_32bit_elf ? size32 : size64; \ - if (section->sh_entsize != expected_entsize) \ - error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \ - i, (unsigned long int) section->sh_entsize, \ - (unsigned long int) expected_entsize); \ - section->sh_entsize = expected_entsize; \ - } \ - while (0) -#define CHECK_ENTSIZE(section, i, type) \ - CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \ - sizeof (Elf64_External_##type)) - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - char * name = SECTION_NAME (section); - - if (section->sh_type == SHT_DYNSYM) - { - if (dynamic_symbols != NULL) - { - error (_("File contains multiple dynamic symbol tables\n")); - continue; - } - - CHECK_ENTSIZE (section, i, Sym); - num_dynamic_syms = section->sh_size / section->sh_entsize; - dynamic_symbols = GET_ELF_SYMBOLS (file, section); - } - else if (section->sh_type == SHT_STRTAB - && streq (name, ".dynstr")) - { - if (dynamic_strings != NULL) - { - error (_("File contains multiple dynamic string tables\n")); - continue; - } - - dynamic_strings = (char *) get_data (NULL, file, section->sh_offset, - 1, section->sh_size, - _("dynamic strings")); - dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size; - } - else if (section->sh_type == SHT_SYMTAB_SHNDX) - { - if (symtab_shndx_hdr != NULL) - { - error (_("File contains multiple symtab shndx tables\n")); - continue; - } - symtab_shndx_hdr = section; - } - else if (section->sh_type == SHT_SYMTAB) - CHECK_ENTSIZE (section, i, Sym); - else if (section->sh_type == SHT_GROUP) - CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE); - else if (section->sh_type == SHT_REL) - CHECK_ENTSIZE (section, i, Rel); - else if (section->sh_type == SHT_RELA) - CHECK_ENTSIZE (section, i, Rela); - else if ((do_debugging || do_debug_info || do_debug_abbrevs - || do_debug_lines || do_debug_pubnames || do_debug_pubtypes - || do_debug_aranges || do_debug_frames || do_debug_macinfo - || do_debug_str || do_debug_loc || do_debug_ranges) - && (const_strneq (name, ".debug_") - || const_strneq (name, ".zdebug_"))) - { - if (name[1] == 'z') - name += sizeof (".zdebug_") - 1; - else - name += sizeof (".debug_") - 1; - - if (do_debugging - || (do_debug_info && streq (name, "info")) - || (do_debug_info && streq (name, "types")) - || (do_debug_abbrevs && streq (name, "abbrev")) - || (do_debug_lines && streq (name, "line")) - || (do_debug_pubnames && streq (name, "pubnames")) - || (do_debug_pubtypes && streq (name, "pubtypes")) - || (do_debug_aranges && streq (name, "aranges")) - || (do_debug_ranges && streq (name, "ranges")) - || (do_debug_frames && streq (name, "frame")) - || (do_debug_macinfo && streq (name, "macinfo")) - || (do_debug_macinfo && streq (name, "macro")) - || (do_debug_str && streq (name, "str")) - || (do_debug_loc && streq (name, "loc")) - ) - request_dump_bynumber (i, DEBUG_DUMP); - } - /* Linkonce section to be combined with .debug_info at link time. */ - else if ((do_debugging || do_debug_info) - && const_strneq (name, ".gnu.linkonce.wi.")) - request_dump_bynumber (i, DEBUG_DUMP); - else if (do_debug_frames && streq (name, ".eh_frame")) - request_dump_bynumber (i, DEBUG_DUMP); - else if (do_gdb_index && streq (name, ".gdb_index")) - request_dump_bynumber (i, DEBUG_DUMP); - /* Trace sections for Itanium VMS. */ - else if ((do_debugging || do_trace_info || do_trace_abbrevs - || do_trace_aranges) - && const_strneq (name, ".trace_")) - { - name += sizeof (".trace_") - 1; - - if (do_debugging - || (do_trace_info && streq (name, "info")) - || (do_trace_abbrevs && streq (name, "abbrev")) - || (do_trace_aranges && streq (name, "aranges")) - ) - request_dump_bynumber (i, DEBUG_DUMP); - } - - } - - if (! do_sections) - return 1; - - if (elf_header.e_shnum > 1) - printf (_("\nSection Headers:\n")); - else - printf (_("\nSection Header:\n")); - - if (is_32bit_elf) - { - if (do_section_details) - { - printf (_(" [Nr] Name\n")); - printf (_(" Type Addr Off Size ES Lk Inf Al\n")); - } - else - printf - (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n")); - } - else if (do_wide) - { - if (do_section_details) - { - printf (_(" [Nr] Name\n")); - printf (_(" Type Address Off Size ES Lk Inf Al\n")); - } - else - printf - (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n")); - } - else - { - if (do_section_details) - { - printf (_(" [Nr] Name\n")); - printf (_(" Type Address Offset Link\n")); - printf (_(" Size EntSize Info Align\n")); - } - else - { - printf (_(" [Nr] Name Type Address Offset\n")); - printf (_(" Size EntSize Flags Link Info Align\n")); - } - } - - if (do_section_details) - printf (_(" Flags\n")); - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - if (do_section_details) - { - printf (" [%2u] %s\n", - i, - SECTION_NAME (section)); - if (is_32bit_elf || do_wide) - printf (" %-15.15s ", - get_section_type_name (section->sh_type)); - } - else - printf ((do_wide ? " [%2u] %-17s %-15s " - : " [%2u] %-17.17s %-15.15s "), - i, - SECTION_NAME (section), - get_section_type_name (section->sh_type)); - - if (is_32bit_elf) - { - const char * link_too_big = NULL; - - print_vma (section->sh_addr, LONG_HEX); - - printf ( " %6.6lx %6.6lx %2.2lx", - (unsigned long) section->sh_offset, - (unsigned long) section->sh_size, - (unsigned long) section->sh_entsize); - - if (do_section_details) - fputs (" ", stdout); - else - printf (" %3s ", get_elf_section_flags (section->sh_flags)); - - if (section->sh_link >= elf_header.e_shnum) - { - link_too_big = ""; - /* The sh_link value is out of range. Normally this indicates - an error but it can have special values in Solaris binaries. */ - switch (elf_header.e_machine) - { - case EM_386: - case EM_486: - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - case EM_OLD_SPARCV9: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - if (section->sh_link == (SHN_BEFORE & 0xffff)) - link_too_big = "BEFORE"; - else if (section->sh_link == (SHN_AFTER & 0xffff)) - link_too_big = "AFTER"; - break; - default: - break; - } - } - - if (do_section_details) - { - if (link_too_big != NULL && * link_too_big) - printf ("<%s> ", link_too_big); - else - printf ("%2u ", section->sh_link); - printf ("%3u %2lu\n", section->sh_info, - (unsigned long) section->sh_addralign); - } - else - printf ("%2u %3u %2lu\n", - section->sh_link, - section->sh_info, - (unsigned long) section->sh_addralign); - - if (link_too_big && ! * link_too_big) - warn (_("section %u: sh_link value of %u is larger than the number of sections\n"), - i, section->sh_link); - } - else if (do_wide) - { - print_vma (section->sh_addr, LONG_HEX); - - if ((long) section->sh_offset == section->sh_offset) - printf (" %6.6lx", (unsigned long) section->sh_offset); - else - { - putchar (' '); - print_vma (section->sh_offset, LONG_HEX); - } - - if ((unsigned long) section->sh_size == section->sh_size) - printf (" %6.6lx", (unsigned long) section->sh_size); - else - { - putchar (' '); - print_vma (section->sh_size, LONG_HEX); - } - - if ((unsigned long) section->sh_entsize == section->sh_entsize) - printf (" %2.2lx", (unsigned long) section->sh_entsize); - else - { - putchar (' '); - print_vma (section->sh_entsize, LONG_HEX); - } - - if (do_section_details) - fputs (" ", stdout); - else - printf (" %3s ", get_elf_section_flags (section->sh_flags)); - - printf ("%2u %3u ", section->sh_link, section->sh_info); - - if ((unsigned long) section->sh_addralign == section->sh_addralign) - printf ("%2lu\n", (unsigned long) section->sh_addralign); - else - { - print_vma (section->sh_addralign, DEC); - putchar ('\n'); - } - } - else if (do_section_details) - { - printf (" %-15.15s ", - get_section_type_name (section->sh_type)); - print_vma (section->sh_addr, LONG_HEX); - if ((long) section->sh_offset == section->sh_offset) - printf (" %16.16lx", (unsigned long) section->sh_offset); - else - { - printf (" "); - print_vma (section->sh_offset, LONG_HEX); - } - printf (" %u\n ", section->sh_link); - print_vma (section->sh_size, LONG_HEX); - putchar (' '); - print_vma (section->sh_entsize, LONG_HEX); - - printf (" %-16u %lu\n", - section->sh_info, - (unsigned long) section->sh_addralign); - } - else - { - putchar (' '); - print_vma (section->sh_addr, LONG_HEX); - if ((long) section->sh_offset == section->sh_offset) - printf (" %8.8lx", (unsigned long) section->sh_offset); - else - { - printf (" "); - print_vma (section->sh_offset, LONG_HEX); - } - printf ("\n "); - print_vma (section->sh_size, LONG_HEX); - printf (" "); - print_vma (section->sh_entsize, LONG_HEX); - - printf (" %3s ", get_elf_section_flags (section->sh_flags)); - - printf (" %2u %3u %lu\n", - section->sh_link, - section->sh_info, - (unsigned long) section->sh_addralign); - } - - if (do_section_details) - printf (" %s\n", get_elf_section_flags (section->sh_flags)); - } - - if (!do_section_details) - { - if (elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM - || elf_header.e_machine == EM_K1OM) - printf (_("Key to Flags:\n\ - W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\ - I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\ - O (extra OS processing required) o (OS specific), p (processor specific)\n")); - else - printf (_("Key to Flags:\n\ - W (write), A (alloc), X (execute), M (merge), S (strings)\n\ - I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\ - O (extra OS processing required) o (OS specific), p (processor specific)\n")); - } - - return 1; -} - -static const char * -get_group_flags (unsigned int flags) -{ - static char buff[32]; - switch (flags) - { - case 0: - return ""; - - case GRP_COMDAT: - return "COMDAT "; - - default: - snprintf (buff, sizeof (buff), _("[: 0x%x] "), flags); - break; - } - return buff; -} - -static int -process_section_groups (FILE * file) -{ - Elf_Internal_Shdr * section; - unsigned int i; - struct group * group; - Elf_Internal_Shdr * symtab_sec; - Elf_Internal_Shdr * strtab_sec; - Elf_Internal_Sym * symtab; - char * strtab; - size_t strtab_size; - - /* Don't process section groups unless needed. */ - if (!do_unwind && !do_section_groups) - return 1; - - if (elf_header.e_shnum == 0) - { - if (do_section_groups) - printf (_("\nThere are no sections to group in this file.\n")); - - return 1; - } - - if (section_headers == NULL) - { - error (_("Section headers are not available!\n")); - abort (); - } - - section_headers_groups = (struct group **) calloc (elf_header.e_shnum, - sizeof (struct group *)); - - if (section_headers_groups == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - /* Scan the sections for the group section. */ - group_count = 0; - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - if (section->sh_type == SHT_GROUP) - group_count++; - - if (group_count == 0) - { - if (do_section_groups) - printf (_("\nThere are no section groups in this file.\n")); - - return 1; - } - - section_groups = (struct group *) calloc (group_count, sizeof (struct group)); - - if (section_groups == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - symtab_sec = NULL; - strtab_sec = NULL; - symtab = NULL; - strtab = NULL; - strtab_size = 0; - for (i = 0, section = section_headers, group = section_groups; - i < elf_header.e_shnum; - i++, section++) - { - if (section->sh_type == SHT_GROUP) - { - char * name = SECTION_NAME (section); - char * group_name; - unsigned char * start; - unsigned char * indices; - unsigned int entry, j, size; - Elf_Internal_Shdr * sec; - Elf_Internal_Sym * sym; - - /* Get the symbol table. */ - if (section->sh_link >= elf_header.e_shnum - || ((sec = section_headers + section->sh_link)->sh_type - != SHT_SYMTAB)) - { - error (_("Bad sh_link in group section `%s'\n"), name); - continue; - } - - if (symtab_sec != sec) - { - symtab_sec = sec; - if (symtab) - free (symtab); - symtab = GET_ELF_SYMBOLS (file, symtab_sec); - } - - if (symtab == NULL) - { - error (_("Corrupt header in group section `%s'\n"), name); - continue; - } - - sym = symtab + section->sh_info; - - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - if (sym->st_shndx == 0 - || sym->st_shndx >= elf_header.e_shnum) - { - error (_("Bad sh_info in group section `%s'\n"), name); - continue; - } - - group_name = SECTION_NAME (section_headers + sym->st_shndx); - strtab_sec = NULL; - if (strtab) - free (strtab); - strtab = NULL; - strtab_size = 0; - } - else - { - /* Get the string table. */ - if (symtab_sec->sh_link >= elf_header.e_shnum) - { - strtab_sec = NULL; - if (strtab) - free (strtab); - strtab = NULL; - strtab_size = 0; - } - else if (strtab_sec - != (sec = section_headers + symtab_sec->sh_link)) - { - strtab_sec = sec; - if (strtab) - free (strtab); - strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset, - 1, strtab_sec->sh_size, - _("string table")); - strtab_size = strtab != NULL ? strtab_sec->sh_size : 0; - } - group_name = sym->st_name < strtab_size - ? strtab + sym->st_name : _(""); - } - - start = (unsigned char *) get_data (NULL, file, section->sh_offset, - 1, section->sh_size, - _("section data")); - if (start == NULL) - continue; - - indices = start; - size = (section->sh_size / section->sh_entsize) - 1; - entry = byte_get (indices, 4); - indices += 4; - - if (do_section_groups) - { - printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"), - get_group_flags (entry), i, name, group_name, size); - - printf (_(" [Index] Name\n")); - } - - group->group_index = i; - - for (j = 0; j < size; j++) - { - struct group_list * g; - - entry = byte_get (indices, 4); - indices += 4; - - if (entry >= elf_header.e_shnum) - { - error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"), - entry, i, elf_header.e_shnum - 1); - continue; - } - - if (section_headers_groups [entry] != NULL) - { - if (entry) - { - error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"), - entry, i, - section_headers_groups [entry]->group_index); - continue; - } - else - { - /* Intel C/C++ compiler may put section 0 in a - section group. We just warn it the first time - and ignore it afterwards. */ - static int warned = 0; - if (!warned) - { - error (_("section 0 in group section [%5u]\n"), - section_headers_groups [entry]->group_index); - warned++; - } - } - } - - section_headers_groups [entry] = group; - - if (do_section_groups) - { - sec = section_headers + entry; - printf (" [%5u] %s\n", entry, SECTION_NAME (sec)); - } - - g = (struct group_list *) xmalloc (sizeof (struct group_list)); - g->section_index = entry; - g->next = group->root; - group->root = g; - } - - if (start) - free (start); - - group++; - } - } - - if (symtab) - free (symtab); - if (strtab) - free (strtab); - return 1; -} - -/* Data used to display dynamic fixups. */ - -struct ia64_vms_dynfixup -{ - bfd_vma needed_ident; /* Library ident number. */ - bfd_vma needed; /* Index in the dstrtab of the library name. */ - bfd_vma fixup_needed; /* Index of the library. */ - bfd_vma fixup_rela_cnt; /* Number of fixups. */ - bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */ -}; - -/* Data used to display dynamic relocations. */ - -struct ia64_vms_dynimgrela -{ - bfd_vma img_rela_cnt; /* Number of relocations. */ - bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */ -}; - -/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared - library). */ - -static void -dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup, - const char *strtab, unsigned int strtab_sz) -{ - Elf64_External_VMS_IMAGE_FIXUP *imfs; - long i; - const char *lib_name; - - imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off, - 1, fixup->fixup_rela_cnt * sizeof (*imfs), - _("dynamic section image fixups")); - if (!imfs) - return; - - if (fixup->needed < strtab_sz) - lib_name = strtab + fixup->needed; - else - { - warn ("corrupt library name index of 0x%lx found in dynamic entry", - (unsigned long) fixup->needed); - lib_name = "???"; - } - printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"), - (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident); - printf - (_("Seg Offset Type SymVec DataType\n")); - - for (i = 0; i < (long) fixup->fixup_rela_cnt; i++) - { - unsigned int type; - const char *rtype; - - printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg)); - printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset)); - type = BYTE_GET (imfs [i].type); - rtype = elf_ia64_reloc_type (type); - if (rtype == NULL) - printf (" 0x%08x ", type); - else - printf (" %-32s ", rtype); - printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index)); - printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type)); - } - - free (imfs); -} - -/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */ - -static void -dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela) -{ - Elf64_External_VMS_IMAGE_RELA *imrs; - long i; - - imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off, - 1, imgrela->img_rela_cnt * sizeof (*imrs), - _("dynamic section image relas")); - if (!imrs) - return; - - printf (_("\nImage relocs\n")); - printf - (_("Seg Offset Type Addend Seg Sym Off\n")); - - for (i = 0; i < (long) imgrela->img_rela_cnt; i++) - { - unsigned int type; - const char *rtype; - - printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg)); - printf ("%08" BFD_VMA_FMT "x ", - (bfd_vma) BYTE_GET (imrs [i].rela_offset)); - type = BYTE_GET (imrs [i].type); - rtype = elf_ia64_reloc_type (type); - if (rtype == NULL) - printf ("0x%08x ", type); - else - printf ("%-31s ", rtype); - print_vma (BYTE_GET (imrs [i].addend), FULL_HEX); - printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg)); - printf ("%08" BFD_VMA_FMT "x\n", - (bfd_vma) BYTE_GET (imrs [i].sym_offset)); - } - - free (imrs); -} - -/* Display IA-64 OpenVMS dynamic relocations and fixups. */ - -static int -process_ia64_vms_dynamic_relocs (FILE *file) -{ - struct ia64_vms_dynfixup fixup; - struct ia64_vms_dynimgrela imgrela; - Elf_Internal_Dyn *entry; - int res = 0; - bfd_vma strtab_off = 0; - bfd_vma strtab_sz = 0; - char *strtab = NULL; - - memset (&fixup, 0, sizeof (fixup)); - memset (&imgrela, 0, sizeof (imgrela)); - - /* Note: the order of the entries is specified by the OpenVMS specs. */ - for (entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - entry++) - { - switch (entry->d_tag) - { - case DT_IA_64_VMS_STRTAB_OFFSET: - strtab_off = entry->d_un.d_val; - break; - case DT_STRSZ: - strtab_sz = entry->d_un.d_val; - if (strtab == NULL) - strtab = get_data (NULL, file, dynamic_addr + strtab_off, - 1, strtab_sz, _("dynamic string section")); - break; - - case DT_IA_64_VMS_NEEDED_IDENT: - fixup.needed_ident = entry->d_un.d_val; - break; - case DT_NEEDED: - fixup.needed = entry->d_un.d_val; - break; - case DT_IA_64_VMS_FIXUP_NEEDED: - fixup.fixup_needed = entry->d_un.d_val; - break; - case DT_IA_64_VMS_FIXUP_RELA_CNT: - fixup.fixup_rela_cnt = entry->d_un.d_val; - break; - case DT_IA_64_VMS_FIXUP_RELA_OFF: - fixup.fixup_rela_off = entry->d_un.d_val; - res++; - dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz); - break; - - case DT_IA_64_VMS_IMG_RELA_CNT: - imgrela.img_rela_cnt = entry->d_un.d_val; - break; - case DT_IA_64_VMS_IMG_RELA_OFF: - imgrela.img_rela_off = entry->d_un.d_val; - res++; - dump_ia64_vms_dynamic_relocs (file, &imgrela); - break; - - default: - break; - } - } - - if (strtab != NULL) - free (strtab); - - return res; -} - -static struct -{ - const char * name; - int reloc; - int size; - int rela; -} dynamic_relocations [] = -{ - { "REL", DT_REL, DT_RELSZ, FALSE }, - { "RELA", DT_RELA, DT_RELASZ, TRUE }, - { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN } -}; - -/* Process the reloc section. */ - -static int -process_relocs (FILE * file) -{ - unsigned long rel_size; - unsigned long rel_offset; - - - if (!do_reloc) - return 1; - - if (do_using_dynamic) - { - int is_rela; - const char * name; - int has_dynamic_reloc; - unsigned int i; - - has_dynamic_reloc = 0; - - for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++) - { - is_rela = dynamic_relocations [i].rela; - name = dynamic_relocations [i].name; - rel_size = dynamic_info [dynamic_relocations [i].size]; - rel_offset = dynamic_info [dynamic_relocations [i].reloc]; - - has_dynamic_reloc |= rel_size; - - if (is_rela == UNKNOWN) - { - if (dynamic_relocations [i].reloc == DT_JMPREL) - switch (dynamic_info[DT_PLTREL]) - { - case DT_REL: - is_rela = FALSE; - break; - case DT_RELA: - is_rela = TRUE; - break; - } - } - - if (rel_size) - { - printf - (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"), - name, rel_offset, rel_size); - - dump_relocations (file, - offset_from_vma (file, rel_offset, rel_size), - rel_size, - dynamic_symbols, num_dynamic_syms, - dynamic_strings, dynamic_strings_length, is_rela); - } - } - - if (is_ia64_vms ()) - has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file); - - if (! has_dynamic_reloc) - printf (_("\nThere are no dynamic relocations in this file.\n")); - } - else - { - Elf_Internal_Shdr * section; - unsigned long i; - int found = 0; - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - if ( section->sh_type != SHT_RELA - && section->sh_type != SHT_REL) - continue; - - rel_offset = section->sh_offset; - rel_size = section->sh_size; - - if (rel_size) - { - Elf_Internal_Shdr * strsec; - int is_rela; - - printf (_("\nRelocation section ")); - - if (string_table == NULL) - printf ("%d", section->sh_name); - else - printf (_("'%s'"), SECTION_NAME (section)); - - printf (_(" at offset 0x%lx contains %lu entries:\n"), - rel_offset, (unsigned long) (rel_size / section->sh_entsize)); - - is_rela = section->sh_type == SHT_RELA; - - if (section->sh_link != 0 - && section->sh_link < elf_header.e_shnum) - { - Elf_Internal_Shdr * symsec; - Elf_Internal_Sym * symtab; - unsigned long nsyms; - unsigned long strtablen = 0; - char * strtab = NULL; - - symsec = section_headers + section->sh_link; - if (symsec->sh_type != SHT_SYMTAB - && symsec->sh_type != SHT_DYNSYM) - continue; - - nsyms = symsec->sh_size / symsec->sh_entsize; - symtab = GET_ELF_SYMBOLS (file, symsec); - - if (symtab == NULL) - continue; - - if (symsec->sh_link != 0 - && symsec->sh_link < elf_header.e_shnum) - { - strsec = section_headers + symsec->sh_link; - - strtab = (char *) get_data (NULL, file, strsec->sh_offset, - 1, strsec->sh_size, - _("string table")); - strtablen = strtab == NULL ? 0 : strsec->sh_size; - } - - dump_relocations (file, rel_offset, rel_size, - symtab, nsyms, strtab, strtablen, is_rela); - if (strtab) - free (strtab); - free (symtab); - } - else - dump_relocations (file, rel_offset, rel_size, - NULL, 0, NULL, 0, is_rela); - - found = 1; - } - } - - if (! found) - printf (_("\nThere are no relocations in this file.\n")); - } - - return 1; -} - -/* Process the unwind section. */ - -#include "unwind-ia64.h" - -/* An absolute address consists of a section and an offset. If the - section is NULL, the offset itself is the address, otherwise, the - address equals to LOAD_ADDRESS(section) + offset. */ - -struct absaddr - { - unsigned short section; - bfd_vma offset; - }; - -#define ABSADDR(a) \ - ((a).section \ - ? section_headers [(a).section].sh_addr + (a).offset \ - : (a).offset) - -struct ia64_unw_table_entry - { - struct absaddr start; - struct absaddr end; - struct absaddr info; - }; - -struct ia64_unw_aux_info - { - - struct ia64_unw_table_entry *table; /* Unwind table. */ - unsigned long table_len; /* Length of unwind table. */ - unsigned char * info; /* Unwind info. */ - unsigned long info_size; /* Size of unwind info. */ - bfd_vma info_addr; /* starting address of unwind info. */ - bfd_vma seg_base; /* Starting address of segment. */ - Elf_Internal_Sym * symtab; /* The symbol table. */ - unsigned long nsyms; /* Number of symbols. */ - char * strtab; /* The string table. */ - unsigned long strtab_size; /* Size of string table. */ - }; - -static void -find_symbol_for_address (Elf_Internal_Sym * symtab, - unsigned long nsyms, - const char * strtab, - unsigned long strtab_size, - struct absaddr addr, - const char ** symname, - bfd_vma * offset) -{ - bfd_vma dist = 0x100000; - Elf_Internal_Sym * sym; - Elf_Internal_Sym * best = NULL; - unsigned long i; - - REMOVE_ARCH_BITS (addr.offset); - - for (i = 0, sym = symtab; i < nsyms; ++i, ++sym) - { - bfd_vma value = sym->st_value; - - REMOVE_ARCH_BITS (value); - - if (ELF_ST_TYPE (sym->st_info) == STT_FUNC - && sym->st_name != 0 - && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx) - && addr.offset >= value - && addr.offset - value < dist) - { - best = sym; - dist = addr.offset - value; - if (!dist) - break; - } - } - if (best) - { - *symname = (best->st_name >= strtab_size - ? _("") : strtab + best->st_name); - *offset = dist; - return; - } - *symname = NULL; - *offset = addr.offset; -} - -static void -dump_ia64_unwind (struct ia64_unw_aux_info * aux) -{ - struct ia64_unw_table_entry * tp; - int in_body; - - for (tp = aux->table; tp < aux->table + aux->table_len; ++tp) - { - bfd_vma stamp; - bfd_vma offset; - const unsigned char * dp; - const unsigned char * head; - const char * procname; - - find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab, - aux->strtab_size, tp->start, &procname, &offset); - - fputs ("\n<", stdout); - - if (procname) - { - fputs (procname, stdout); - - if (offset) - printf ("+%lx", (unsigned long) offset); - } - - fputs (">: [", stdout); - print_vma (tp->start.offset, PREFIX_HEX); - fputc ('-', stdout); - print_vma (tp->end.offset, PREFIX_HEX); - printf ("], info at +0x%lx\n", - (unsigned long) (tp->info.offset - aux->seg_base)); - - head = aux->info + (ABSADDR (tp->info) - aux->info_addr); - stamp = byte_get ((unsigned char *) head, sizeof (stamp)); - - printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n", - (unsigned) UNW_VER (stamp), - (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32), - UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "", - UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "", - (unsigned long) (eh_addr_size * UNW_LENGTH (stamp))); - - if (UNW_VER (stamp) != 1) - { - printf (_("\tUnknown version.\n")); - continue; - } - - in_body = 0; - for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);) - dp = unw_decode (dp, in_body, & in_body); - } -} - -static int -slurp_ia64_unwind_table (FILE * file, - struct ia64_unw_aux_info * aux, - Elf_Internal_Shdr * sec) -{ - unsigned long size, nrelas, i; - Elf_Internal_Phdr * seg; - struct ia64_unw_table_entry * tep; - Elf_Internal_Shdr * relsec; - Elf_Internal_Rela * rela; - Elf_Internal_Rela * rp; - unsigned char * table; - unsigned char * tp; - Elf_Internal_Sym * sym; - const char * relname; - - /* First, find the starting address of the segment that includes - this section: */ - - if (elf_header.e_phnum) - { - if (! get_program_headers (file)) - return 0; - - for (seg = program_headers; - seg < program_headers + elf_header.e_phnum; - ++seg) - { - if (seg->p_type != PT_LOAD) - continue; - - if (sec->sh_addr >= seg->p_vaddr - && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz)) - { - aux->seg_base = seg->p_vaddr; - break; - } - } - } - - /* Second, build the unwind table from the contents of the unwind section: */ - size = sec->sh_size; - table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size, - _("unwind table")); - if (!table) - return 0; - - aux->table = (struct ia64_unw_table_entry *) - xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0])); - tep = aux->table; - for (tp = table; tp < table + size; ++tep) - { - tep->start.section = SHN_UNDEF; - tep->end.section = SHN_UNDEF; - tep->info.section = SHN_UNDEF; - tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size; - tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size; - tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size; - tep->start.offset += aux->seg_base; - tep->end.offset += aux->seg_base; - tep->info.offset += aux->seg_base; - } - free (table); - - /* Third, apply any relocations to the unwind table: */ - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - if (relsec->sh_type != SHT_RELA - || relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != sec) - continue; - - if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, - & rela, & nrelas)) - return 0; - - for (rp = rela; rp < rela + nrelas; ++rp) - { - relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info)); - sym = aux->symtab + get_reloc_symindex (rp->r_info); - - if (! const_strneq (relname, "R_IA64_SEGREL")) - { - warn (_("Skipping unexpected relocation type %s\n"), relname); - continue; - } - - i = rp->r_offset / (3 * eh_addr_size); - - switch (rp->r_offset/eh_addr_size % 3) - { - case 0: - aux->table[i].start.section = sym->st_shndx; - aux->table[i].start.offset = rp->r_addend + sym->st_value; - break; - case 1: - aux->table[i].end.section = sym->st_shndx; - aux->table[i].end.offset = rp->r_addend + sym->st_value; - break; - case 2: - aux->table[i].info.section = sym->st_shndx; - aux->table[i].info.offset = rp->r_addend + sym->st_value; - break; - default: - break; - } - } - - free (rela); - } - - aux->table_len = size / (3 * eh_addr_size); - return 1; -} - -static int -ia64_process_unwind (FILE * file) -{ - Elf_Internal_Shdr * sec; - Elf_Internal_Shdr * unwsec = NULL; - Elf_Internal_Shdr * strsec; - unsigned long i, unwcount = 0, unwstart = 0; - struct ia64_unw_aux_info aux; - - memset (& aux, 0, sizeof (aux)); - - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (sec->sh_type == SHT_SYMTAB - && sec->sh_link < elf_header.e_shnum) - { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); - - strsec = section_headers + sec->sh_link; - assert (aux.strtab == NULL); - aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset, - 1, strsec->sh_size, - _("string table")); - aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; - } - else if (sec->sh_type == SHT_IA_64_UNWIND) - unwcount++; - } - - if (!unwcount) - printf (_("\nThere are no unwind sections in this file.\n")); - - while (unwcount-- > 0) - { - char * suffix; - size_t len, len2; - - for (i = unwstart, sec = section_headers + unwstart; - i < elf_header.e_shnum; ++i, ++sec) - if (sec->sh_type == SHT_IA_64_UNWIND) - { - unwsec = sec; - break; - } - - unwstart = i + 1; - len = sizeof (ELF_STRING_ia64_unwind_once) - 1; - - if ((unwsec->sh_flags & SHF_GROUP) != 0) - { - /* We need to find which section group it is in. */ - struct group_list * g = section_headers_groups [i]->root; - - for (; g != NULL; g = g->next) - { - sec = section_headers + g->section_index; - - if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)) - break; - } - - if (g == NULL) - i = elf_header.e_shnum; - } - else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len)) - { - /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */ - len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1; - suffix = SECTION_NAME (unwsec) + len; - for (i = 0, sec = section_headers; i < elf_header.e_shnum; - ++i, ++sec) - if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2) - && streq (SECTION_NAME (sec) + len2, suffix)) - break; - } - else - { - /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO - .IA_64.unwind or BAR -> .IA_64.unwind_info. */ - len = sizeof (ELF_STRING_ia64_unwind) - 1; - len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1; - suffix = ""; - if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len)) - suffix = SECTION_NAME (unwsec) + len; - for (i = 0, sec = section_headers; i < elf_header.e_shnum; - ++i, ++sec) - if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2) - && streq (SECTION_NAME (sec) + len2, suffix)) - break; - } - - if (i == elf_header.e_shnum) - { - printf (_("\nCould not find unwind info section for ")); - - if (string_table == NULL) - printf ("%d", unwsec->sh_name); - else - printf (_("'%s'"), SECTION_NAME (unwsec)); - } - else - { - aux.info_addr = sec->sh_addr; - aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, - sec->sh_size, - _("unwind info")); - aux.info_size = aux.info == NULL ? 0 : sec->sh_size; - - printf (_("\nUnwind section ")); - - if (string_table == NULL) - printf ("%d", unwsec->sh_name); - else - printf (_("'%s'"), SECTION_NAME (unwsec)); - - printf (_(" at offset 0x%lx contains %lu entries:\n"), - (unsigned long) unwsec->sh_offset, - (unsigned long) (unwsec->sh_size / (3 * eh_addr_size))); - - (void) slurp_ia64_unwind_table (file, & aux, unwsec); - - if (aux.table_len > 0) - dump_ia64_unwind (& aux); - - if (aux.table) - free ((char *) aux.table); - if (aux.info) - free ((char *) aux.info); - aux.table = NULL; - aux.info = NULL; - } - } - - if (aux.symtab) - free (aux.symtab); - if (aux.strtab) - free ((char *) aux.strtab); - - return 1; -} - -struct hppa_unw_table_entry - { - struct absaddr start; - struct absaddr end; - unsigned int Cannot_unwind:1; /* 0 */ - unsigned int Millicode:1; /* 1 */ - unsigned int Millicode_save_sr0:1; /* 2 */ - unsigned int Region_description:2; /* 3..4 */ - unsigned int reserved1:1; /* 5 */ - unsigned int Entry_SR:1; /* 6 */ - unsigned int Entry_FR:4; /* number saved */ /* 7..10 */ - unsigned int Entry_GR:5; /* number saved */ /* 11..15 */ - unsigned int Args_stored:1; /* 16 */ - unsigned int Variable_Frame:1; /* 17 */ - unsigned int Separate_Package_Body:1; /* 18 */ - unsigned int Frame_Extension_Millicode:1; /* 19 */ - unsigned int Stack_Overflow_Check:1; /* 20 */ - unsigned int Two_Instruction_SP_Increment:1; /* 21 */ - unsigned int Ada_Region:1; /* 22 */ - unsigned int cxx_info:1; /* 23 */ - unsigned int cxx_try_catch:1; /* 24 */ - unsigned int sched_entry_seq:1; /* 25 */ - unsigned int reserved2:1; /* 26 */ - unsigned int Save_SP:1; /* 27 */ - unsigned int Save_RP:1; /* 28 */ - unsigned int Save_MRP_in_frame:1; /* 29 */ - unsigned int extn_ptr_defined:1; /* 30 */ - unsigned int Cleanup_defined:1; /* 31 */ - - unsigned int MPE_XL_interrupt_marker:1; /* 0 */ - unsigned int HP_UX_interrupt_marker:1; /* 1 */ - unsigned int Large_frame:1; /* 2 */ - unsigned int Pseudo_SP_Set:1; /* 3 */ - unsigned int reserved4:1; /* 4 */ - unsigned int Total_frame_size:27; /* 5..31 */ - }; - -struct hppa_unw_aux_info - { - struct hppa_unw_table_entry *table; /* Unwind table. */ - unsigned long table_len; /* Length of unwind table. */ - bfd_vma seg_base; /* Starting address of segment. */ - Elf_Internal_Sym * symtab; /* The symbol table. */ - unsigned long nsyms; /* Number of symbols. */ - char * strtab; /* The string table. */ - unsigned long strtab_size; /* Size of string table. */ - }; - -static void -dump_hppa_unwind (struct hppa_unw_aux_info * aux) -{ - struct hppa_unw_table_entry * tp; - - for (tp = aux->table; tp < aux->table + aux->table_len; ++tp) - { - bfd_vma offset; - const char * procname; - - find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab, - aux->strtab_size, tp->start, &procname, - &offset); - - fputs ("\n<", stdout); - - if (procname) - { - fputs (procname, stdout); - - if (offset) - printf ("+%lx", (unsigned long) offset); - } - - fputs (">: [", stdout); - print_vma (tp->start.offset, PREFIX_HEX); - fputc ('-', stdout); - print_vma (tp->end.offset, PREFIX_HEX); - printf ("]\n\t"); - -#define PF(_m) if (tp->_m) printf (#_m " "); -#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m); - PF(Cannot_unwind); - PF(Millicode); - PF(Millicode_save_sr0); - /* PV(Region_description); */ - PF(Entry_SR); - PV(Entry_FR); - PV(Entry_GR); - PF(Args_stored); - PF(Variable_Frame); - PF(Separate_Package_Body); - PF(Frame_Extension_Millicode); - PF(Stack_Overflow_Check); - PF(Two_Instruction_SP_Increment); - PF(Ada_Region); - PF(cxx_info); - PF(cxx_try_catch); - PF(sched_entry_seq); - PF(Save_SP); - PF(Save_RP); - PF(Save_MRP_in_frame); - PF(extn_ptr_defined); - PF(Cleanup_defined); - PF(MPE_XL_interrupt_marker); - PF(HP_UX_interrupt_marker); - PF(Large_frame); - PF(Pseudo_SP_Set); - PV(Total_frame_size); -#undef PF -#undef PV - } - - printf ("\n"); -} - -static int -slurp_hppa_unwind_table (FILE * file, - struct hppa_unw_aux_info * aux, - Elf_Internal_Shdr * sec) -{ - unsigned long size, unw_ent_size, nentries, nrelas, i; - Elf_Internal_Phdr * seg; - struct hppa_unw_table_entry * tep; - Elf_Internal_Shdr * relsec; - Elf_Internal_Rela * rela; - Elf_Internal_Rela * rp; - unsigned char * table; - unsigned char * tp; - Elf_Internal_Sym * sym; - const char * relname; - - /* First, find the starting address of the segment that includes - this section. */ - - if (elf_header.e_phnum) - { - if (! get_program_headers (file)) - return 0; - - for (seg = program_headers; - seg < program_headers + elf_header.e_phnum; - ++seg) - { - if (seg->p_type != PT_LOAD) - continue; - - if (sec->sh_addr >= seg->p_vaddr - && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz)) - { - aux->seg_base = seg->p_vaddr; - break; - } - } - } - - /* Second, build the unwind table from the contents of the unwind - section. */ - size = sec->sh_size; - table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size, - _("unwind table")); - if (!table) - return 0; - - unw_ent_size = 16; - nentries = size / unw_ent_size; - size = unw_ent_size * nentries; - - tep = aux->table = (struct hppa_unw_table_entry *) - xcmalloc (nentries, sizeof (aux->table[0])); - - for (tp = table; tp < table + size; tp += unw_ent_size, ++tep) - { - unsigned int tmp1, tmp2; - - tep->start.section = SHN_UNDEF; - tep->end.section = SHN_UNDEF; - - tep->start.offset = byte_get ((unsigned char *) tp + 0, 4); - tep->end.offset = byte_get ((unsigned char *) tp + 4, 4); - tmp1 = byte_get ((unsigned char *) tp + 8, 4); - tmp2 = byte_get ((unsigned char *) tp + 12, 4); - - tep->start.offset += aux->seg_base; - tep->end.offset += aux->seg_base; - - tep->Cannot_unwind = (tmp1 >> 31) & 0x1; - tep->Millicode = (tmp1 >> 30) & 0x1; - tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1; - tep->Region_description = (tmp1 >> 27) & 0x3; - tep->reserved1 = (tmp1 >> 26) & 0x1; - tep->Entry_SR = (tmp1 >> 25) & 0x1; - tep->Entry_FR = (tmp1 >> 21) & 0xf; - tep->Entry_GR = (tmp1 >> 16) & 0x1f; - tep->Args_stored = (tmp1 >> 15) & 0x1; - tep->Variable_Frame = (tmp1 >> 14) & 0x1; - tep->Separate_Package_Body = (tmp1 >> 13) & 0x1; - tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1; - tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1; - tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1; - tep->Ada_Region = (tmp1 >> 9) & 0x1; - tep->cxx_info = (tmp1 >> 8) & 0x1; - tep->cxx_try_catch = (tmp1 >> 7) & 0x1; - tep->sched_entry_seq = (tmp1 >> 6) & 0x1; - tep->reserved2 = (tmp1 >> 5) & 0x1; - tep->Save_SP = (tmp1 >> 4) & 0x1; - tep->Save_RP = (tmp1 >> 3) & 0x1; - tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1; - tep->extn_ptr_defined = (tmp1 >> 1) & 0x1; - tep->Cleanup_defined = tmp1 & 0x1; - - tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1; - tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1; - tep->Large_frame = (tmp2 >> 29) & 0x1; - tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1; - tep->reserved4 = (tmp2 >> 27) & 0x1; - tep->Total_frame_size = tmp2 & 0x7ffffff; - } - free (table); - - /* Third, apply any relocations to the unwind table. */ - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - if (relsec->sh_type != SHT_RELA - || relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != sec) - continue; - - if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, - & rela, & nrelas)) - return 0; - - for (rp = rela; rp < rela + nrelas; ++rp) - { - relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info)); - sym = aux->symtab + get_reloc_symindex (rp->r_info); - - /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */ - if (! const_strneq (relname, "R_PARISC_SEGREL")) - { - warn (_("Skipping unexpected relocation type %s\n"), relname); - continue; - } - - i = rp->r_offset / unw_ent_size; - - switch ((rp->r_offset % unw_ent_size) / eh_addr_size) - { - case 0: - aux->table[i].start.section = sym->st_shndx; - aux->table[i].start.offset = sym->st_value + rp->r_addend; - break; - case 1: - aux->table[i].end.section = sym->st_shndx; - aux->table[i].end.offset = sym->st_value + rp->r_addend; - break; - default: - break; - } - } - - free (rela); - } - - aux->table_len = nentries; - - return 1; -} - -static int -hppa_process_unwind (FILE * file) -{ - struct hppa_unw_aux_info aux; - Elf_Internal_Shdr * unwsec = NULL; - Elf_Internal_Shdr * strsec; - Elf_Internal_Shdr * sec; - unsigned long i; - - memset (& aux, 0, sizeof (aux)); - - if (string_table == NULL) - return 1; - - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (sec->sh_type == SHT_SYMTAB - && sec->sh_link < elf_header.e_shnum) - { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); - - strsec = section_headers + sec->sh_link; - assert (aux.strtab == NULL); - aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset, - 1, strsec->sh_size, - _("string table")); - aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; - } - else if (streq (SECTION_NAME (sec), ".PARISC.unwind")) - unwsec = sec; - } - - if (!unwsec) - printf (_("\nThere are no unwind sections in this file.\n")); - - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (streq (SECTION_NAME (sec), ".PARISC.unwind")) - { - printf (_("\nUnwind section ")); - printf (_("'%s'"), SECTION_NAME (sec)); - - printf (_(" at offset 0x%lx contains %lu entries:\n"), - (unsigned long) sec->sh_offset, - (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8))); - - slurp_hppa_unwind_table (file, &aux, sec); - if (aux.table_len > 0) - dump_hppa_unwind (&aux); - - if (aux.table) - free ((char *) aux.table); - aux.table = NULL; - } - } - - if (aux.symtab) - free (aux.symtab); - if (aux.strtab) - free ((char *) aux.strtab); - - return 1; -} - -struct arm_section -{ - unsigned char *data; - - Elf_Internal_Shdr *sec; - Elf_Internal_Rela *rela; - unsigned long nrelas; - unsigned int rel_type; - - Elf_Internal_Rela *next_rela; -}; - -struct arm_unw_aux_info -{ - FILE *file; - - Elf_Internal_Sym *symtab; /* The symbol table. */ - unsigned long nsyms; /* Number of symbols. */ - char *strtab; /* The string table. */ - unsigned long strtab_size; /* Size of string table. */ -}; - -static const char * -arm_print_vma_and_name (struct arm_unw_aux_info *aux, - bfd_vma fn, struct absaddr addr) -{ - const char *procname; - bfd_vma sym_offset; - - if (addr.section == SHN_UNDEF) - addr.offset = fn; - - find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab, - aux->strtab_size, addr, &procname, - &sym_offset); - - print_vma (fn, PREFIX_HEX); - - if (procname) - { - fputs (" <", stdout); - fputs (procname, stdout); - - if (sym_offset) - printf ("+0x%lx", (unsigned long) sym_offset); - fputc ('>', stdout); - } - - return procname; -} - -static void -arm_free_section (struct arm_section *arm_sec) -{ - if (arm_sec->data != NULL) - free (arm_sec->data); - - if (arm_sec->rela != NULL) - free (arm_sec->rela); -} - -static int -arm_section_get_word (struct arm_unw_aux_info *aux, - struct arm_section *arm_sec, - Elf_Internal_Shdr *sec, bfd_vma word_offset, - unsigned int *wordp, struct absaddr *addr) -{ - Elf_Internal_Rela *rp; - Elf_Internal_Sym *sym; - const char * relname; - unsigned int word; - bfd_boolean wrapped; - - addr->section = SHN_UNDEF; - addr->offset = 0; - - if (sec != arm_sec->sec) - { - Elf_Internal_Shdr *relsec; - - arm_free_section (arm_sec); - - arm_sec->sec = sec; - arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1, - sec->sh_size, _("unwind data")); - arm_sec->rela = NULL; - arm_sec->nrelas = 0; - - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - if (relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != sec) - continue; - - if (relsec->sh_type == SHT_REL) - { - if (!slurp_rel_relocs (aux->file, relsec->sh_offset, - relsec->sh_size, - & arm_sec->rela, & arm_sec->nrelas)) - return 0; - break; - } - else if (relsec->sh_type == SHT_RELA) - { - if (!slurp_rela_relocs (aux->file, relsec->sh_offset, - relsec->sh_size, - & arm_sec->rela, & arm_sec->nrelas)) - return 0; - break; - } - } - - arm_sec->next_rela = arm_sec->rela; - } - - if (arm_sec->data == NULL) - return 0; - - word = byte_get (arm_sec->data + word_offset, 4); - - wrapped = FALSE; - for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++) - { - bfd_vma prelval, offset; - - if (rp->r_offset > word_offset && !wrapped) - { - rp = arm_sec->rela; - wrapped = TRUE; - } - if (rp->r_offset > word_offset) - break; - - if (rp->r_offset & 3) - { - warn (_("Skipping unexpected relocation at offset 0x%lx\n"), - (unsigned long) rp->r_offset); - continue; - } - - if (rp->r_offset < word_offset) - continue; - - switch (elf_header.e_machine) - { - case EM_ARM: - relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info)); - break; - - case EM_TI_C6000: - relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info)); - break; - - default: - abort(); - } - - if (streq (relname, "R_ARM_NONE") - || streq (relname, "R_C6000_NONE")) - continue; - - if (!(streq (relname, "R_ARM_PREL31") - || streq (relname, "R_C6000_PREL31"))) - { - warn (_("Skipping unexpected relocation type %s\n"), relname); - continue; - } - - sym = aux->symtab + ELF32_R_SYM (rp->r_info); - - if (arm_sec->rel_type == SHT_REL) - { - offset = word & 0x7fffffff; - if (offset & 0x40000000) - offset |= ~ (bfd_vma) 0x7fffffff; - } - else - offset = rp->r_addend; - - offset += sym->st_value; - prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset); - - if (streq (relname, "R_C6000_PREL31")) - prelval >>= 1; - - word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff); - addr->section = sym->st_shndx; - addr->offset = offset; - break; - } - - *wordp = word; - arm_sec->next_rela = rp; - - return 1; -} - -static const char *tic6x_unwind_regnames[16] = { - "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3", - "A14", "A13", "A12", "A11", "A10", - "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"}; - -static void -decode_tic6x_unwind_regmask (unsigned int mask) -{ - int i; - - for (i = 12; mask; mask >>= 1, i--) - { - if (mask & 1) - { - fputs (tic6x_unwind_regnames[i], stdout); - if (mask > 1) - fputs (", ", stdout); - } - } -} - -#define ADVANCE \ - if (remaining == 0 && more_words) \ - { \ - data_offset += 4; \ - if (!arm_section_get_word (aux, data_arm_sec, data_sec, \ - data_offset, &word, &addr)) \ - return; \ - remaining = 4; \ - more_words--; \ - } \ - -#define GET_OP(OP) \ - ADVANCE; \ - if (remaining) \ - { \ - remaining--; \ - (OP) = word >> 24; \ - word <<= 8; \ - } \ - else \ - { \ - printf (_("[Truncated opcode]\n")); \ - return; \ - } \ - printf ("0x%02x ", OP) - -static void -decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux, - unsigned int word, unsigned int remaining, - unsigned int more_words, - bfd_vma data_offset, Elf_Internal_Shdr *data_sec, - struct arm_section *data_arm_sec) -{ - struct absaddr addr; - - /* Decode the unwinding instructions. */ - while (1) - { - unsigned int op, op2; - - ADVANCE; - if (remaining == 0) - break; - remaining--; - op = word >> 24; - word <<= 8; - - printf (" 0x%02x ", op); - - if ((op & 0xc0) == 0x00) - { - int offset = ((op & 0x3f) << 2) + 4; - - printf (" vsp = vsp + %d", offset); - } - else if ((op & 0xc0) == 0x40) - { - int offset = ((op & 0x3f) << 2) + 4; - - printf (" vsp = vsp - %d", offset); - } - else if ((op & 0xf0) == 0x80) - { - GET_OP (op2); - if (op == 0x80 && op2 == 0) - printf (_("Refuse to unwind")); - else - { - unsigned int mask = ((op & 0x0f) << 8) | op2; - int first = 1; - int i; - - printf ("pop {"); - for (i = 0; i < 12; i++) - if (mask & (1 << i)) - { - if (first) - first = 0; - else - printf (", "); - printf ("r%d", 4 + i); - } - printf ("}"); - } - } - else if ((op & 0xf0) == 0x90) - { - if (op == 0x9d || op == 0x9f) - printf (_(" [Reserved]")); - else - printf (" vsp = r%d", op & 0x0f); - } - else if ((op & 0xf0) == 0xa0) - { - int end = 4 + (op & 0x07); - int first = 1; - int i; - - printf (" pop {"); - for (i = 4; i <= end; i++) - { - if (first) - first = 0; - else - printf (", "); - printf ("r%d", i); - } - if (op & 0x08) - { - if (first) - printf (", "); - printf ("r14"); - } - printf ("}"); - } - else if (op == 0xb0) - printf (_(" finish")); - else if (op == 0xb1) - { - GET_OP (op2); - if (op2 == 0 || (op2 & 0xf0) != 0) - printf (_("[Spare]")); - else - { - unsigned int mask = op2 & 0x0f; - int first = 1; - int i; - - printf ("pop {"); - for (i = 0; i < 12; i++) - if (mask & (1 << i)) - { - if (first) - first = 0; - else - printf (", "); - printf ("r%d", i); - } - printf ("}"); - } - } - else if (op == 0xb2) - { - unsigned char buf[9]; - unsigned int i, len; - unsigned long offset; - - for (i = 0; i < sizeof (buf); i++) - { - GET_OP (buf[i]); - if ((buf[i] & 0x80) == 0) - break; - } - assert (i < sizeof (buf)); - offset = read_uleb128 (buf, &len); - assert (len == i + 1); - offset = offset * 4 + 0x204; - printf ("vsp = vsp + %ld", offset); - } - else if (op == 0xb3 || op == 0xc8 || op == 0xc9) - { - unsigned int first, last; - - GET_OP (op2); - first = op2 >> 4; - last = op2 & 0x0f; - if (op == 0xc8) - first = first + 16; - printf ("pop {D%d", first); - if (last) - printf ("-D%d", first + last); - printf ("}"); - } - else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) - { - unsigned int count = op & 0x07; - - printf ("pop {D8"); - if (count) - printf ("-D%d", 8 + count); - printf ("}"); - } - else if (op >= 0xc0 && op <= 0xc5) - { - unsigned int count = op & 0x07; - - printf (" pop {wR10"); - if (count) - printf ("-wR%d", 10 + count); - printf ("}"); - } - else if (op == 0xc6) - { - unsigned int first, last; - - GET_OP (op2); - first = op2 >> 4; - last = op2 & 0x0f; - printf ("pop {wR%d", first); - if (last) - printf ("-wR%d", first + last); - printf ("}"); - } - else if (op == 0xc7) - { - GET_OP (op2); - if (op2 == 0 || (op2 & 0xf0) != 0) - printf (_("[Spare]")); - else - { - unsigned int mask = op2 & 0x0f; - int first = 1; - int i; - - printf ("pop {"); - for (i = 0; i < 4; i++) - if (mask & (1 << i)) - { - if (first) - first = 0; - else - printf (", "); - printf ("wCGR%d", i); - } - printf ("}"); - } - } - else - printf (_(" [unsupported opcode]")); - printf ("\n"); - } -} - -static void -decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux, - unsigned int word, unsigned int remaining, - unsigned int more_words, - bfd_vma data_offset, Elf_Internal_Shdr *data_sec, - struct arm_section *data_arm_sec) -{ - struct absaddr addr; - - /* Decode the unwinding instructions. */ - while (1) - { - unsigned int op, op2; - - ADVANCE; - if (remaining == 0) - break; - remaining--; - op = word >> 24; - word <<= 8; - - printf (_(" 0x%02x "), op); - - if ((op & 0xc0) == 0x00) - { - int offset = ((op & 0x3f) << 3) + 8; - printf (_(" sp = sp + %d"), offset); - } - else if ((op & 0xc0) == 0x80) - { - GET_OP (op2); - if (op == 0x80 && op2 == 0) - printf (_("Refuse to unwind")); - else - { - unsigned int mask = ((op & 0x1f) << 8) | op2; - if (op & 0x20) - printf ("pop compact {"); - else - printf ("pop {"); - - decode_tic6x_unwind_regmask (mask); - printf("}"); - } - } - else if ((op & 0xf0) == 0xc0) - { - unsigned int reg; - unsigned int nregs; - unsigned int i; - const char *name; - struct { - unsigned int offset; - unsigned int reg; - } regpos[16]; - - /* Scan entire instruction first so that GET_OP output is not - interleaved with disassembly. */ - nregs = 0; - for (i = 0; nregs < (op & 0xf); i++) - { - GET_OP (op2); - reg = op2 >> 4; - if (reg != 0xf) - { - regpos[nregs].offset = i * 2; - regpos[nregs].reg = reg; - nregs++; - } - - reg = op2 & 0xf; - if (reg != 0xf) - { - regpos[nregs].offset = i * 2 + 1; - regpos[nregs].reg = reg; - nregs++; - } - } - - printf (_("pop frame {")); - reg = nregs - 1; - for (i = i * 2; i > 0; i--) - { - if (regpos[reg].offset == i - 1) - { - name = tic6x_unwind_regnames[regpos[reg].reg]; - if (reg > 0) - reg--; - } - else - name = _("[pad]"); - - fputs (name, stdout); - if (i > 1) - printf (", "); - } - - printf ("}"); - } - else if (op == 0xd0) - printf (" MOV FP, SP"); - else if (op == 0xd1) - printf (" __c6xabi_pop_rts"); - else if (op == 0xd2) - { - unsigned char buf[9]; - unsigned int i, len; - unsigned long offset; - for (i = 0; i < sizeof (buf); i++) - { - GET_OP (buf[i]); - if ((buf[i] & 0x80) == 0) - break; - } - assert (i < sizeof (buf)); - offset = read_uleb128 (buf, &len); - assert (len == i + 1); - offset = offset * 8 + 0x408; - printf (_("sp = sp + %ld"), offset); - } - else if ((op & 0xf0) == 0xe0) - { - if ((op & 0x0f) == 7) - printf (" RETURN"); - else - printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]); - } - else - { - printf (_(" [unsupported opcode]")); - } - putchar ('\n'); - } -} - -static bfd_vma -expand_prel31 (bfd_vma word, bfd_vma where) -{ - bfd_vma offset; - - offset = word & 0x7fffffff; - if (offset & 0x40000000) - offset |= ~ (bfd_vma) 0x7fffffff; - - if (elf_header.e_machine == EM_TI_C6000) - offset <<= 1; - - return offset + where; -} - -static void -decode_arm_unwind (struct arm_unw_aux_info *aux, - unsigned int word, unsigned int remaining, - bfd_vma data_offset, Elf_Internal_Shdr *data_sec, - struct arm_section *data_arm_sec) -{ - int per_index; - unsigned int more_words = 0; - struct absaddr addr; - - if (remaining == 0) - { - /* Fetch the first word. */ - if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset, - &word, &addr)) - return; - remaining = 4; - } - - if ((word & 0x80000000) == 0) - { - /* Expand prel31 for personality routine. */ - bfd_vma fn; - const char *procname; - - fn = expand_prel31 (word, data_sec->sh_addr + data_offset); - printf (_(" Personality routine: ")); - procname = arm_print_vma_and_name (aux, fn, addr); - fputc ('\n', stdout); - - /* The GCC personality routines use the standard compact - encoding, starting with one byte giving the number of - words. */ - if (procname != NULL - && (const_strneq (procname, "__gcc_personality_v0") - || const_strneq (procname, "__gxx_personality_v0") - || const_strneq (procname, "__gcj_personality_v0") - || const_strneq (procname, "__gnu_objc_personality_v0"))) - { - remaining = 0; - more_words = 1; - ADVANCE; - if (!remaining) - { - printf (_(" [Truncated data]\n")); - return; - } - more_words = word >> 24; - word <<= 8; - remaining--; - per_index = -1; - } - else - return; - } - else - { - - per_index = (word >> 24) & 0x7f; - printf (_(" Compact model %d\n"), per_index); - if (per_index == 0) - { - more_words = 0; - word <<= 8; - remaining--; - } - else if (per_index < 3) - { - more_words = (word >> 16) & 0xff; - word <<= 16; - remaining -= 2; - } - } - - switch (elf_header.e_machine) - { - case EM_ARM: - if (per_index < 3) - { - decode_arm_unwind_bytecode (aux, word, remaining, more_words, - data_offset, data_sec, data_arm_sec); - } - else - printf (" [reserved]\n"); - break; - - case EM_TI_C6000: - if (per_index < 3) - { - decode_tic6x_unwind_bytecode (aux, word, remaining, more_words, - data_offset, data_sec, data_arm_sec); - } - else if (per_index < 5) - { - if (((word >> 17) & 0x7f) == 0x7f) - printf (_(" Restore stack from frame pointer\n")); - else - printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc); - printf (_(" Registers restored: ")); - if (per_index == 4) - printf (" (compact) "); - decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff); - putchar ('\n'); - printf (_(" Return register: %s\n"), - tic6x_unwind_regnames[word & 0xf]); - } - else - printf (" [reserved]\n"); - break; - - default: - abort (); - } - - /* Decode the descriptors. Not implemented. */ -} - -static void -dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec) -{ - struct arm_section exidx_arm_sec, extab_arm_sec; - unsigned int i, exidx_len; - - memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec)); - memset (&extab_arm_sec, 0, sizeof (extab_arm_sec)); - exidx_len = exidx_sec->sh_size / 8; - - for (i = 0; i < exidx_len; i++) - { - unsigned int exidx_fn, exidx_entry; - struct absaddr fn_addr, entry_addr; - bfd_vma fn; - - fputc ('\n', stdout); - - if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec, - 8 * i, &exidx_fn, &fn_addr) - || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec, - 8 * i + 4, &exidx_entry, &entry_addr)) - { - arm_free_section (&exidx_arm_sec); - arm_free_section (&extab_arm_sec); - return; - } - - fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i); - - arm_print_vma_and_name (aux, fn, entry_addr); - fputs (": ", stdout); - - if (exidx_entry == 1) - { - print_vma (exidx_entry, PREFIX_HEX); - fputs (" [cantunwind]\n", stdout); - } - else if (exidx_entry & 0x80000000) - { - print_vma (exidx_entry, PREFIX_HEX); - fputc ('\n', stdout); - decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL); - } - else - { - bfd_vma table, table_offset = 0; - Elf_Internal_Shdr *table_sec; - - fputs ("@", stdout); - table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4); - print_vma (table, PREFIX_HEX); - printf ("\n"); - - /* Locate the matching .ARM.extab. */ - if (entry_addr.section != SHN_UNDEF - && entry_addr.section < elf_header.e_shnum) - { - table_sec = section_headers + entry_addr.section; - table_offset = entry_addr.offset; - } - else - { - table_sec = find_section_by_address (table); - if (table_sec != NULL) - table_offset = table - table_sec->sh_addr; - } - if (table_sec == NULL) - { - warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"), - (unsigned long) table); - continue; - } - decode_arm_unwind (aux, 0, 0, table_offset, table_sec, - &extab_arm_sec); - } - } - - printf ("\n"); - - arm_free_section (&exidx_arm_sec); - arm_free_section (&extab_arm_sec); -} - -/* Used for both ARM and C6X unwinding tables. */ -static int -arm_process_unwind (FILE *file) -{ - struct arm_unw_aux_info aux; - Elf_Internal_Shdr *unwsec = NULL; - Elf_Internal_Shdr *strsec; - Elf_Internal_Shdr *sec; - unsigned long i; - unsigned int sec_type; - - memset (& aux, 0, sizeof (aux)); - aux.file = file; - - switch (elf_header.e_machine) - { - case EM_ARM: - sec_type = SHT_ARM_EXIDX; - break; - - case EM_TI_C6000: - sec_type = SHT_C6000_UNWIND; - break; - - default: - abort(); - } - - if (string_table == NULL) - return 1; - - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum) - { - aux.nsyms = sec->sh_size / sec->sh_entsize; - aux.symtab = GET_ELF_SYMBOLS (file, sec); - - strsec = section_headers + sec->sh_link; - assert (aux.strtab == NULL); - aux.strtab = get_data (NULL, file, strsec->sh_offset, - 1, strsec->sh_size, _("string table")); - aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; - } - else if (sec->sh_type == sec_type) - unwsec = sec; - } - - if (!unwsec) - printf (_("\nThere are no unwind sections in this file.\n")); - - for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) - { - if (sec->sh_type == sec_type) - { - printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"), - SECTION_NAME (sec), - (unsigned long) sec->sh_offset, - (unsigned long) (sec->sh_size / (2 * eh_addr_size))); - - dump_arm_unwind (&aux, sec); - } - } - - if (aux.symtab) - free (aux.symtab); - if (aux.strtab) - free ((char *) aux.strtab); - - return 1; -} - -static int -process_unwind (FILE * file) -{ - struct unwind_handler - { - int machtype; - int (* handler)(FILE *); - } handlers[] = - { - { EM_ARM, arm_process_unwind }, - { EM_IA_64, ia64_process_unwind }, - { EM_PARISC, hppa_process_unwind }, - { EM_TI_C6000, arm_process_unwind }, - { 0, 0 } - }; - int i; - - if (!do_unwind) - return 1; - - for (i = 0; handlers[i].handler != NULL; i++) - if (elf_header.e_machine == handlers[i].machtype) - return handlers[i].handler (file); - - printf (_("\nThere are no unwind sections in this file.\n")); - return 1; -} - -static void -dynamic_section_mips_val (Elf_Internal_Dyn * entry) -{ - switch (entry->d_tag) - { - case DT_MIPS_FLAGS: - if (entry->d_un.d_val == 0) - printf (_("NONE\n")); - else - { - static const char * opts[] = - { - "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT", - "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS", - "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD", - "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF", - "RLD_ORDER_SAFE" - }; - unsigned int cnt; - int first = 1; - - for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt) - if (entry->d_un.d_val & (1 << cnt)) - { - printf ("%s%s", first ? "" : " ", opts[cnt]); - first = 0; - } - puts (""); - } - break; - - case DT_MIPS_IVERSION: - if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) - printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val)); - else - printf (_("\n"), (long) entry->d_un.d_ptr); - break; - - case DT_MIPS_TIME_STAMP: - { - char timebuf[20]; - struct tm * tmp; - - time_t atime = entry->d_un.d_val; - tmp = gmtime (&atime); - snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u", - tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - printf (_("Time Stamp: %s\n"), timebuf); - } - break; - - case DT_MIPS_RLD_VERSION: - case DT_MIPS_LOCAL_GOTNO: - case DT_MIPS_CONFLICTNO: - case DT_MIPS_LIBLISTNO: - case DT_MIPS_SYMTABNO: - case DT_MIPS_UNREFEXTNO: - case DT_MIPS_HIPAGENO: - case DT_MIPS_DELTA_CLASS_NO: - case DT_MIPS_DELTA_INSTANCE_NO: - case DT_MIPS_DELTA_RELOC_NO: - case DT_MIPS_DELTA_SYM_NO: - case DT_MIPS_DELTA_CLASSSYM_NO: - case DT_MIPS_COMPACT_SIZE: - printf ("%ld\n", (long) entry->d_un.d_ptr); - break; - - default: - printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr); - } -} - -static void -dynamic_section_parisc_val (Elf_Internal_Dyn * entry) -{ - switch (entry->d_tag) - { - case DT_HP_DLD_FLAGS: - { - static struct - { - long int bit; - const char * str; - } - flags[] = - { - { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" }, - { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" }, - { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" }, - { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" }, - { DT_HP_BIND_NOW, "HP_BIND_NOW" }, - { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" }, - { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" }, - { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" }, - { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" }, - { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" }, - { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }, - { DT_HP_GST, "HP_GST" }, - { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" }, - { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" }, - { DT_HP_NODELETE, "HP_NODELETE" }, - { DT_HP_GROUP, "HP_GROUP" }, - { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" } - }; - int first = 1; - size_t cnt; - bfd_vma val = entry->d_un.d_val; - - for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt) - if (val & flags[cnt].bit) - { - if (! first) - putchar (' '); - fputs (flags[cnt].str, stdout); - first = 0; - val ^= flags[cnt].bit; - } - - if (val != 0 || first) - { - if (! first) - putchar (' '); - print_vma (val, HEX); - } - } - break; - - default: - print_vma (entry->d_un.d_ptr, PREFIX_HEX); - break; - } - putchar ('\n'); -} - -#ifdef BFD64 - -/* VMS vs Unix time offset and factor. */ - -#define VMS_EPOCH_OFFSET 35067168000000000LL -#define VMS_GRANULARITY_FACTOR 10000000 - -/* Display a VMS time in a human readable format. */ - -static void -print_vms_time (bfd_int64_t vmstime) -{ - struct tm *tm; - time_t unxtime; - - unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR; - tm = gmtime (&unxtime); - printf ("%04u-%02u-%02uT%02u:%02u:%02u", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); -} -#endif /* BFD64 */ - -static void -dynamic_section_ia64_val (Elf_Internal_Dyn * entry) -{ - switch (entry->d_tag) - { - case DT_IA_64_PLT_RESERVE: - /* First 3 slots reserved. */ - print_vma (entry->d_un.d_ptr, PREFIX_HEX); - printf (" -- "); - print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX); - break; - - case DT_IA_64_VMS_LINKTIME: -#ifdef BFD64 - print_vms_time (entry->d_un.d_val); -#endif - break; - - case DT_IA_64_VMS_LNKFLAGS: - print_vma (entry->d_un.d_ptr, PREFIX_HEX); - if (entry->d_un.d_val & VMS_LF_CALL_DEBUG) - printf (" CALL_DEBUG"); - if (entry->d_un.d_val & VMS_LF_NOP0BUFS) - printf (" NOP0BUFS"); - if (entry->d_un.d_val & VMS_LF_P0IMAGE) - printf (" P0IMAGE"); - if (entry->d_un.d_val & VMS_LF_MKTHREADS) - printf (" MKTHREADS"); - if (entry->d_un.d_val & VMS_LF_UPCALLS) - printf (" UPCALLS"); - if (entry->d_un.d_val & VMS_LF_IMGSTA) - printf (" IMGSTA"); - if (entry->d_un.d_val & VMS_LF_INITIALIZE) - printf (" INITIALIZE"); - if (entry->d_un.d_val & VMS_LF_MAIN) - printf (" MAIN"); - if (entry->d_un.d_val & VMS_LF_EXE_INIT) - printf (" EXE_INIT"); - if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG) - printf (" TBK_IN_IMG"); - if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG) - printf (" DBG_IN_IMG"); - if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF) - printf (" TBK_IN_DSF"); - if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF) - printf (" DBG_IN_DSF"); - if (entry->d_un.d_val & VMS_LF_SIGNATURES) - printf (" SIGNATURES"); - if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF) - printf (" REL_SEG_OFF"); - break; - - default: - print_vma (entry->d_un.d_ptr, PREFIX_HEX); - break; - } - putchar ('\n'); -} - -static int -get_32bit_dynamic_section (FILE * file) -{ - Elf32_External_Dyn * edyn; - Elf32_External_Dyn * ext; - Elf_Internal_Dyn * entry; - - edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1, - dynamic_size, _("dynamic section")); - if (!edyn) - return 0; - -/* SGI's ELF has more than one section in the DYNAMIC segment, and we - might not have the luxury of section headers. Look for the DT_NULL - terminator to determine the number of entries. */ - for (ext = edyn, dynamic_nent = 0; - (char *) ext < (char *) edyn + dynamic_size; - ext++) - { - dynamic_nent++; - if (BYTE_GET (ext->d_tag) == DT_NULL) - break; - } - - dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent, - sizeof (* entry)); - if (dynamic_section == NULL) - { - error (_("Out of memory\n")); - free (edyn); - return 0; - } - - for (ext = edyn, entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - ext++, entry++) - { - entry->d_tag = BYTE_GET (ext->d_tag); - entry->d_un.d_val = BYTE_GET (ext->d_un.d_val); - } - - free (edyn); - - return 1; -} - -static int -get_64bit_dynamic_section (FILE * file) -{ - Elf64_External_Dyn * edyn; - Elf64_External_Dyn * ext; - Elf_Internal_Dyn * entry; - - edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1, - dynamic_size, _("dynamic section")); - if (!edyn) - return 0; - -/* SGI's ELF has more than one section in the DYNAMIC segment, and we - might not have the luxury of section headers. Look for the DT_NULL - terminator to determine the number of entries. */ - for (ext = edyn, dynamic_nent = 0; - (char *) ext < (char *) edyn + dynamic_size; - ext++) - { - dynamic_nent++; - if (BYTE_GET (ext->d_tag) == DT_NULL) - break; - } - - dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent, - sizeof (* entry)); - if (dynamic_section == NULL) - { - error (_("Out of memory\n")); - free (edyn); - return 0; - } - - for (ext = edyn, entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - ext++, entry++) - { - entry->d_tag = BYTE_GET (ext->d_tag); - entry->d_un.d_val = BYTE_GET (ext->d_un.d_val); - } - - free (edyn); - - return 1; -} - -static void -print_dynamic_flags (bfd_vma flags) -{ - int first = 1; - - while (flags) - { - bfd_vma flag; - - flag = flags & - flags; - flags &= ~ flag; - - if (first) - first = 0; - else - putc (' ', stdout); - - switch (flag) - { - case DF_ORIGIN: fputs ("ORIGIN", stdout); break; - case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break; - case DF_TEXTREL: fputs ("TEXTREL", stdout); break; - case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break; - case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break; - default: fputs (_("unknown"), stdout); break; - } - } - puts (""); -} - -/* Parse and display the contents of the dynamic section. */ - -static int -process_dynamic_section (FILE * file) -{ - Elf_Internal_Dyn * entry; - - if (dynamic_size == 0) - { - if (do_dynamic) - printf (_("\nThere is no dynamic section in this file.\n")); - - return 1; - } - - if (is_32bit_elf) - { - if (! get_32bit_dynamic_section (file)) - return 0; - } - else if (! get_64bit_dynamic_section (file)) - return 0; - - /* Find the appropriate symbol table. */ - if (dynamic_symbols == NULL) - { - for (entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - ++entry) - { - Elf_Internal_Shdr section; - - if (entry->d_tag != DT_SYMTAB) - continue; - - dynamic_info[DT_SYMTAB] = entry->d_un.d_val; - - /* Since we do not know how big the symbol table is, - we default to reading in the entire file (!) and - processing that. This is overkill, I know, but it - should work. */ - section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0); - - if (archive_file_offset != 0) - section.sh_size = archive_file_size - section.sh_offset; - else - { - if (fseek (file, 0, SEEK_END)) - error (_("Unable to seek to end of file!\n")); - - section.sh_size = ftell (file) - section.sh_offset; - } - - if (is_32bit_elf) - section.sh_entsize = sizeof (Elf32_External_Sym); - else - section.sh_entsize = sizeof (Elf64_External_Sym); - - num_dynamic_syms = section.sh_size / section.sh_entsize; - if (num_dynamic_syms < 1) - { - error (_("Unable to determine the number of symbols to load\n")); - continue; - } - - dynamic_symbols = GET_ELF_SYMBOLS (file, §ion); - } - } - - /* Similarly find a string table. */ - if (dynamic_strings == NULL) - { - for (entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - ++entry) - { - unsigned long offset; - long str_tab_len; - - if (entry->d_tag != DT_STRTAB) - continue; - - dynamic_info[DT_STRTAB] = entry->d_un.d_val; - - /* Since we do not know how big the string table is, - we default to reading in the entire file (!) and - processing that. This is overkill, I know, but it - should work. */ - - offset = offset_from_vma (file, entry->d_un.d_val, 0); - - if (archive_file_offset != 0) - str_tab_len = archive_file_size - offset; - else - { - if (fseek (file, 0, SEEK_END)) - error (_("Unable to seek to end of file\n")); - str_tab_len = ftell (file) - offset; - } - - if (str_tab_len < 1) - { - error - (_("Unable to determine the length of the dynamic string table\n")); - continue; - } - - dynamic_strings = (char *) get_data (NULL, file, offset, 1, - str_tab_len, - _("dynamic string table")); - dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len; - break; - } - } - - /* And find the syminfo section if available. */ - if (dynamic_syminfo == NULL) - { - unsigned long syminsz = 0; - - for (entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - ++entry) - { - if (entry->d_tag == DT_SYMINENT) - { - /* Note: these braces are necessary to avoid a syntax - error from the SunOS4 C compiler. */ - assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val); - } - else if (entry->d_tag == DT_SYMINSZ) - syminsz = entry->d_un.d_val; - else if (entry->d_tag == DT_SYMINFO) - dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val, - syminsz); - } - - if (dynamic_syminfo_offset != 0 && syminsz != 0) - { - Elf_External_Syminfo * extsyminfo; - Elf_External_Syminfo * extsym; - Elf_Internal_Syminfo * syminfo; - - /* There is a syminfo section. Read the data. */ - extsyminfo = (Elf_External_Syminfo *) - get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz, - _("symbol information")); - if (!extsyminfo) - return 0; - - dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz); - if (dynamic_syminfo == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo); - for (syminfo = dynamic_syminfo, extsym = extsyminfo; - syminfo < dynamic_syminfo + dynamic_syminfo_nent; - ++syminfo, ++extsym) - { - syminfo->si_boundto = BYTE_GET (extsym->si_boundto); - syminfo->si_flags = BYTE_GET (extsym->si_flags); - } - - free (extsyminfo); - } - } - - if (do_dynamic && dynamic_addr) - printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"), - dynamic_addr, dynamic_nent); - if (do_dynamic) - printf (_(" Tag Type Name/Value\n")); - - for (entry = dynamic_section; - entry < dynamic_section + dynamic_nent; - entry++) - { - if (do_dynamic) - { - const char * dtype; - - putchar (' '); - print_vma (entry->d_tag, FULL_HEX); - dtype = get_dynamic_type (entry->d_tag); - printf (" (%s)%*s", dtype, - ((is_32bit_elf ? 27 : 19) - - (int) strlen (dtype)), - " "); - } - - switch (entry->d_tag) - { - case DT_FLAGS: - if (do_dynamic) - print_dynamic_flags (entry->d_un.d_val); - break; - - case DT_AUXILIARY: - case DT_FILTER: - case DT_CONFIG: - case DT_DEPAUDIT: - case DT_AUDIT: - if (do_dynamic) - { - switch (entry->d_tag) - { - case DT_AUXILIARY: - printf (_("Auxiliary library")); - break; - - case DT_FILTER: - printf (_("Filter library")); - break; - - case DT_CONFIG: - printf (_("Configuration file")); - break; - - case DT_DEPAUDIT: - printf (_("Dependency audit library")); - break; - - case DT_AUDIT: - printf (_("Audit library")); - break; - } - - if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) - printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val)); - else - { - printf (": "); - print_vma (entry->d_un.d_val, PREFIX_HEX); - putchar ('\n'); - } - } - break; - - case DT_FEATURE: - if (do_dynamic) - { - printf (_("Flags:")); - - if (entry->d_un.d_val == 0) - printf (_(" None\n")); - else - { - unsigned long int val = entry->d_un.d_val; - - if (val & DTF_1_PARINIT) - { - printf (" PARINIT"); - val ^= DTF_1_PARINIT; - } - if (val & DTF_1_CONFEXP) - { - printf (" CONFEXP"); - val ^= DTF_1_CONFEXP; - } - if (val != 0) - printf (" %lx", val); - puts (""); - } - } - break; - - case DT_POSFLAG_1: - if (do_dynamic) - { - printf (_("Flags:")); - - if (entry->d_un.d_val == 0) - printf (_(" None\n")); - else - { - unsigned long int val = entry->d_un.d_val; - - if (val & DF_P1_LAZYLOAD) - { - printf (" LAZYLOAD"); - val ^= DF_P1_LAZYLOAD; - } - if (val & DF_P1_GROUPPERM) - { - printf (" GROUPPERM"); - val ^= DF_P1_GROUPPERM; - } - if (val != 0) - printf (" %lx", val); - puts (""); - } - } - break; - - case DT_FLAGS_1: - if (do_dynamic) - { - printf (_("Flags:")); - if (entry->d_un.d_val == 0) - printf (_(" None\n")); - else - { - unsigned long int val = entry->d_un.d_val; - - if (val & DF_1_NOW) - { - printf (" NOW"); - val ^= DF_1_NOW; - } - if (val & DF_1_GLOBAL) - { - printf (" GLOBAL"); - val ^= DF_1_GLOBAL; - } - if (val & DF_1_GROUP) - { - printf (" GROUP"); - val ^= DF_1_GROUP; - } - if (val & DF_1_NODELETE) - { - printf (" NODELETE"); - val ^= DF_1_NODELETE; - } - if (val & DF_1_LOADFLTR) - { - printf (" LOADFLTR"); - val ^= DF_1_LOADFLTR; - } - if (val & DF_1_INITFIRST) - { - printf (" INITFIRST"); - val ^= DF_1_INITFIRST; - } - if (val & DF_1_NOOPEN) - { - printf (" NOOPEN"); - val ^= DF_1_NOOPEN; - } - if (val & DF_1_ORIGIN) - { - printf (" ORIGIN"); - val ^= DF_1_ORIGIN; - } - if (val & DF_1_DIRECT) - { - printf (" DIRECT"); - val ^= DF_1_DIRECT; - } - if (val & DF_1_TRANS) - { - printf (" TRANS"); - val ^= DF_1_TRANS; - } - if (val & DF_1_INTERPOSE) - { - printf (" INTERPOSE"); - val ^= DF_1_INTERPOSE; - } - if (val & DF_1_NODEFLIB) - { - printf (" NODEFLIB"); - val ^= DF_1_NODEFLIB; - } - if (val & DF_1_NODUMP) - { - printf (" NODUMP"); - val ^= DF_1_NODUMP; - } - if (val & DF_1_CONLFAT) - { - printf (" CONLFAT"); - val ^= DF_1_CONLFAT; - } - if (val != 0) - printf (" %lx", val); - puts (""); - } - } - break; - - case DT_PLTREL: - dynamic_info[entry->d_tag] = entry->d_un.d_val; - if (do_dynamic) - puts (get_dynamic_type (entry->d_un.d_val)); - break; - - case DT_NULL : - case DT_NEEDED : - case DT_PLTGOT : - case DT_HASH : - case DT_STRTAB : - case DT_SYMTAB : - case DT_RELA : - case DT_INIT : - case DT_FINI : - case DT_SONAME : - case DT_RPATH : - case DT_SYMBOLIC: - case DT_REL : - case DT_DEBUG : - case DT_TEXTREL : - case DT_JMPREL : - case DT_RUNPATH : - dynamic_info[entry->d_tag] = entry->d_un.d_val; - - if (do_dynamic) - { - char * name; - - if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) - name = GET_DYNAMIC_NAME (entry->d_un.d_val); - else - name = NULL; - - if (name) - { - switch (entry->d_tag) - { - case DT_NEEDED: - printf (_("Shared library: [%s]"), name); - - if (streq (name, program_interpreter)) - printf (_(" program interpreter")); - break; - - case DT_SONAME: - printf (_("Library soname: [%s]"), name); - break; - - case DT_RPATH: - printf (_("Library rpath: [%s]"), name); - break; - - case DT_RUNPATH: - printf (_("Library runpath: [%s]"), name); - break; - - default: - print_vma (entry->d_un.d_val, PREFIX_HEX); - break; - } - } - else - print_vma (entry->d_un.d_val, PREFIX_HEX); - - putchar ('\n'); - } - break; - - case DT_PLTRELSZ: - case DT_RELASZ : - case DT_STRSZ : - case DT_RELSZ : - case DT_RELAENT : - case DT_SYMENT : - case DT_RELENT : - dynamic_info[entry->d_tag] = entry->d_un.d_val; - case DT_PLTPADSZ: - case DT_MOVEENT : - case DT_MOVESZ : - case DT_INIT_ARRAYSZ: - case DT_FINI_ARRAYSZ: - case DT_GNU_CONFLICTSZ: - case DT_GNU_LIBLISTSZ: - if (do_dynamic) - { - print_vma (entry->d_un.d_val, UNSIGNED); - printf (_(" (bytes)\n")); - } - break; - - case DT_VERDEFNUM: - case DT_VERNEEDNUM: - case DT_RELACOUNT: - case DT_RELCOUNT: - if (do_dynamic) - { - print_vma (entry->d_un.d_val, UNSIGNED); - putchar ('\n'); - } - break; - - case DT_SYMINSZ: - case DT_SYMINENT: - case DT_SYMINFO: - case DT_USED: - case DT_INIT_ARRAY: - case DT_FINI_ARRAY: - if (do_dynamic) - { - if (entry->d_tag == DT_USED - && VALID_DYNAMIC_NAME (entry->d_un.d_val)) - { - char * name = GET_DYNAMIC_NAME (entry->d_un.d_val); - - if (*name) - { - printf (_("Not needed object: [%s]\n"), name); - break; - } - } - - print_vma (entry->d_un.d_val, PREFIX_HEX); - putchar ('\n'); - } - break; - - case DT_BIND_NOW: - /* The value of this entry is ignored. */ - if (do_dynamic) - putchar ('\n'); - break; - - case DT_GNU_PRELINKED: - if (do_dynamic) - { - struct tm * tmp; - time_t atime = entry->d_un.d_val; - - tmp = gmtime (&atime); - printf ("%04u-%02u-%02uT%02u:%02u:%02u\n", - tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - - } - break; - - case DT_GNU_HASH: - dynamic_info_DT_GNU_HASH = entry->d_un.d_val; - if (do_dynamic) - { - print_vma (entry->d_un.d_val, PREFIX_HEX); - putchar ('\n'); - } - break; - - default: - if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM)) - version_info[DT_VERSIONTAGIDX (entry->d_tag)] = - entry->d_un.d_val; - - if (do_dynamic) - { - switch (elf_header.e_machine) - { - case EM_MIPS: - case EM_MIPS_RS3_LE: - dynamic_section_mips_val (entry); - break; - case EM_PARISC: - dynamic_section_parisc_val (entry); - break; - case EM_IA_64: - dynamic_section_ia64_val (entry); - break; - default: - print_vma (entry->d_un.d_val, PREFIX_HEX); - putchar ('\n'); - } - } - break; - } - } - - return 1; -} - -static char * -get_ver_flags (unsigned int flags) -{ - static char buff[32]; - - buff[0] = 0; - - if (flags == 0) - return _("none"); - - if (flags & VER_FLG_BASE) - strcat (buff, "BASE "); - - if (flags & VER_FLG_WEAK) - { - if (flags & VER_FLG_BASE) - strcat (buff, "| "); - - strcat (buff, "WEAK "); - } - - if (flags & VER_FLG_INFO) - { - if (flags & (VER_FLG_BASE|VER_FLG_WEAK)) - strcat (buff, "| "); - - strcat (buff, "INFO "); - } - - if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO)) - strcat (buff, _("| ")); - - return buff; -} - -/* Display the contents of the version sections. */ - -static int -process_version_sections (FILE * file) -{ - Elf_Internal_Shdr * section; - unsigned i; - int found = 0; - - if (! do_version) - return 1; - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - switch (section->sh_type) - { - case SHT_GNU_verdef: - { - Elf_External_Verdef * edefs; - unsigned int idx; - unsigned int cnt; - char * endbuf; - - found = 1; - - printf - (_("\nVersion definition section '%s' contains %u entries:\n"), - SECTION_NAME (section), section->sh_info); - - printf (_(" Addr: 0x")); - printf_vma (section->sh_addr); - printf (_(" Offset: %#08lx Link: %u (%s)\n"), - (unsigned long) section->sh_offset, section->sh_link, - section->sh_link < elf_header.e_shnum - ? SECTION_NAME (section_headers + section->sh_link) - : _("")); - - edefs = (Elf_External_Verdef *) - get_data (NULL, file, section->sh_offset, 1,section->sh_size, - _("version definition section")); - if (!edefs) - break; - endbuf = (char *) edefs + section->sh_size; - - for (idx = cnt = 0; cnt < section->sh_info; ++cnt) - { - char * vstart; - Elf_External_Verdef * edef; - Elf_Internal_Verdef ent; - Elf_External_Verdaux * eaux; - Elf_Internal_Verdaux aux; - int j; - int isum; - - /* Check for negative or very large indicies. */ - if ((unsigned char *) edefs + idx < (unsigned char *) edefs) - break; - - vstart = ((char *) edefs) + idx; - if (vstart + sizeof (*edef) > endbuf) - break; - - edef = (Elf_External_Verdef *) vstart; - - ent.vd_version = BYTE_GET (edef->vd_version); - ent.vd_flags = BYTE_GET (edef->vd_flags); - ent.vd_ndx = BYTE_GET (edef->vd_ndx); - ent.vd_cnt = BYTE_GET (edef->vd_cnt); - ent.vd_hash = BYTE_GET (edef->vd_hash); - ent.vd_aux = BYTE_GET (edef->vd_aux); - ent.vd_next = BYTE_GET (edef->vd_next); - - printf (_(" %#06x: Rev: %d Flags: %s"), - idx, ent.vd_version, get_ver_flags (ent.vd_flags)); - - printf (_(" Index: %d Cnt: %d "), - ent.vd_ndx, ent.vd_cnt); - - /* Check for overflow. */ - if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart - || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf) - break; - - vstart += ent.vd_aux; - - eaux = (Elf_External_Verdaux *) vstart; - - aux.vda_name = BYTE_GET (eaux->vda_name); - aux.vda_next = BYTE_GET (eaux->vda_next); - - if (VALID_DYNAMIC_NAME (aux.vda_name)) - printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name)); - else - printf (_("Name index: %ld\n"), aux.vda_name); - - isum = idx + ent.vd_aux; - - for (j = 1; j < ent.vd_cnt; j++) - { - /* Check for overflow. */ - if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart - || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf) - break; - - isum += aux.vda_next; - vstart += aux.vda_next; - - eaux = (Elf_External_Verdaux *) vstart; - if (vstart + sizeof (*eaux) > endbuf) - break; - - aux.vda_name = BYTE_GET (eaux->vda_name); - aux.vda_next = BYTE_GET (eaux->vda_next); - - if (VALID_DYNAMIC_NAME (aux.vda_name)) - printf (_(" %#06x: Parent %d: %s\n"), - isum, j, GET_DYNAMIC_NAME (aux.vda_name)); - else - printf (_(" %#06x: Parent %d, name index: %ld\n"), - isum, j, aux.vda_name); - } - - if (j < ent.vd_cnt) - printf (_(" Version def aux past end of section\n")); - - idx += ent.vd_next; - } - - if (cnt < section->sh_info) - printf (_(" Version definition past end of section\n")); - - free (edefs); - } - break; - - case SHT_GNU_verneed: - { - Elf_External_Verneed * eneed; - unsigned int idx; - unsigned int cnt; - char * endbuf; - - found = 1; - - printf (_("\nVersion needs section '%s' contains %u entries:\n"), - SECTION_NAME (section), section->sh_info); - - printf (_(" Addr: 0x")); - printf_vma (section->sh_addr); - printf (_(" Offset: %#08lx Link: %u (%s)\n"), - (unsigned long) section->sh_offset, section->sh_link, - section->sh_link < elf_header.e_shnum - ? SECTION_NAME (section_headers + section->sh_link) - : _("")); - - eneed = (Elf_External_Verneed *) get_data (NULL, file, - section->sh_offset, 1, - section->sh_size, - _("version need section")); - if (!eneed) - break; - endbuf = (char *) eneed + section->sh_size; - - for (idx = cnt = 0; cnt < section->sh_info; ++cnt) - { - Elf_External_Verneed * entry; - Elf_Internal_Verneed ent; - int j; - int isum; - char * vstart; - - if ((unsigned char *) eneed + idx < (unsigned char *) eneed) - break; - - vstart = ((char *) eneed) + idx; - if (vstart + sizeof (*entry) > endbuf) - break; - - entry = (Elf_External_Verneed *) vstart; - - ent.vn_version = BYTE_GET (entry->vn_version); - ent.vn_cnt = BYTE_GET (entry->vn_cnt); - ent.vn_file = BYTE_GET (entry->vn_file); - ent.vn_aux = BYTE_GET (entry->vn_aux); - ent.vn_next = BYTE_GET (entry->vn_next); - - printf (_(" %#06x: Version: %d"), idx, ent.vn_version); - - if (VALID_DYNAMIC_NAME (ent.vn_file)) - printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file)); - else - printf (_(" File: %lx"), ent.vn_file); - - printf (_(" Cnt: %d\n"), ent.vn_cnt); - - /* Check for overflow. */ - if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart - || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf) - break; - - vstart += ent.vn_aux; - - for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j) - { - Elf_External_Vernaux * eaux; - Elf_Internal_Vernaux aux; - - if (vstart + sizeof (*eaux) > endbuf) - break; - eaux = (Elf_External_Vernaux *) vstart; - - aux.vna_hash = BYTE_GET (eaux->vna_hash); - aux.vna_flags = BYTE_GET (eaux->vna_flags); - aux.vna_other = BYTE_GET (eaux->vna_other); - aux.vna_name = BYTE_GET (eaux->vna_name); - aux.vna_next = BYTE_GET (eaux->vna_next); - - if (VALID_DYNAMIC_NAME (aux.vna_name)) - printf (_(" %#06x: Name: %s"), - isum, GET_DYNAMIC_NAME (aux.vna_name)); - else - printf (_(" %#06x: Name index: %lx"), - isum, aux.vna_name); - - printf (_(" Flags: %s Version: %d\n"), - get_ver_flags (aux.vna_flags), aux.vna_other); - - /* Check for overflow. */ - if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart - || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf) - break; - - isum += aux.vna_next; - vstart += aux.vna_next; - } - if (j < ent.vn_cnt) - printf (_(" Version need aux past end of section\n")); - - idx += ent.vn_next; - } - if (cnt < section->sh_info) - printf (_(" Version need past end of section\n")); - - free (eneed); - } - break; - - case SHT_GNU_versym: - { - Elf_Internal_Shdr * link_section; - int total; - int cnt; - unsigned char * edata; - unsigned short * data; - char * strtab; - Elf_Internal_Sym * symbols; - Elf_Internal_Shdr * string_sec; - long off; - - if (section->sh_link >= elf_header.e_shnum) - break; - - link_section = section_headers + section->sh_link; - total = section->sh_size / sizeof (Elf_External_Versym); - - if (link_section->sh_link >= elf_header.e_shnum) - break; - - found = 1; - - symbols = GET_ELF_SYMBOLS (file, link_section); - if (symbols == NULL) - break; - - string_sec = section_headers + link_section->sh_link; - - strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1, - string_sec->sh_size, - _("version string table")); - if (!strtab) - { - free (symbols); - break; - } - - printf (_("\nVersion symbols section '%s' contains %d entries:\n"), - SECTION_NAME (section), total); - - printf (_(" Addr: ")); - printf_vma (section->sh_addr); - printf (_(" Offset: %#08lx Link: %u (%s)\n"), - (unsigned long) section->sh_offset, section->sh_link, - SECTION_NAME (link_section)); - - off = offset_from_vma (file, - version_info[DT_VERSIONTAGIDX (DT_VERSYM)], - total * sizeof (short)); - edata = (unsigned char *) get_data (NULL, file, off, total, - sizeof (short), - _("version symbol data")); - if (!edata) - { - free (strtab); - free (symbols); - break; - } - - data = (short unsigned int *) cmalloc (total, sizeof (short)); - - for (cnt = total; cnt --;) - data[cnt] = byte_get (edata + cnt * sizeof (short), - sizeof (short)); - - free (edata); - - for (cnt = 0; cnt < total; cnt += 4) - { - int j, nn; - int check_def, check_need; - char * name; - - printf (" %03x:", cnt); - - for (j = 0; (j < 4) && (cnt + j) < total; ++j) - switch (data[cnt + j]) - { - case 0: - fputs (_(" 0 (*local*) "), stdout); - break; - - case 1: - fputs (_(" 1 (*global*) "), stdout); - break; - - default: - nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION, - data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' '); - - /* If this index value is greater than the size of the symbols - array, break to avoid an out-of-bounds read, */ - if ((unsigned long)(cnt + j) >= - ((unsigned long)link_section->sh_size / - (unsigned long)link_section->sh_entsize)) - { - warn (_("invalid index into symbol array\n")); - break; - } - - check_def = 1; - check_need = 1; - if (symbols[cnt + j].st_shndx >= elf_header.e_shnum - || section_headers[symbols[cnt + j].st_shndx].sh_type - != SHT_NOBITS) - { - if (symbols[cnt + j].st_shndx == SHN_UNDEF) - check_def = 0; - else - check_need = 0; - } - - if (check_need - && version_info[DT_VERSIONTAGIDX (DT_VERNEED)]) - { - Elf_Internal_Verneed ivn; - unsigned long offset; - - offset = offset_from_vma - (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)], - sizeof (Elf_External_Verneed)); - - do - { - Elf_Internal_Vernaux ivna; - Elf_External_Verneed evn; - Elf_External_Vernaux evna; - unsigned long a_off; - - if (get_data (&evn, file, offset, sizeof (evn), 1, - _("version need")) == NULL) - break; - - ivn.vn_aux = BYTE_GET (evn.vn_aux); - ivn.vn_next = BYTE_GET (evn.vn_next); - - a_off = offset + ivn.vn_aux; - - do - { - if (get_data (&evna, file, a_off, sizeof (evna), - 1, _("version need aux (2)")) == NULL) - { - ivna.vna_next = 0; - ivna.vna_other = 0; - } - else - { - ivna.vna_next = BYTE_GET (evna.vna_next); - ivna.vna_other = BYTE_GET (evna.vna_other); - } - - a_off += ivna.vna_next; - } - while (ivna.vna_other != data[cnt + j] - && ivna.vna_next != 0); - - if (ivna.vna_other == data[cnt + j]) - { - ivna.vna_name = BYTE_GET (evna.vna_name); - - if (ivna.vna_name >= string_sec->sh_size) - name = _("*invalid*"); - else - name = strtab + ivna.vna_name; - nn += printf ("(%s%-*s", - name, - 12 - (int) strlen (name), - ")"); - check_def = 0; - break; - } - - offset += ivn.vn_next; - } - while (ivn.vn_next); - } - - if (check_def && data[cnt + j] != 0x8001 - && version_info[DT_VERSIONTAGIDX (DT_VERDEF)]) - { - Elf_Internal_Verdef ivd; - Elf_External_Verdef evd; - unsigned long offset; - - offset = offset_from_vma - (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)], - sizeof evd); - - do - { - if (get_data (&evd, file, offset, sizeof (evd), 1, - _("version def")) == NULL) - { - ivd.vd_next = 0; - ivd.vd_ndx = 0; - } - else - { - ivd.vd_next = BYTE_GET (evd.vd_next); - ivd.vd_ndx = BYTE_GET (evd.vd_ndx); - } - - offset += ivd.vd_next; - } - while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION) - && ivd.vd_next != 0); - - if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION)) - { - Elf_External_Verdaux evda; - Elf_Internal_Verdaux ivda; - - ivd.vd_aux = BYTE_GET (evd.vd_aux); - - if (get_data (&evda, file, - offset - ivd.vd_next + ivd.vd_aux, - sizeof (evda), 1, - _("version def aux")) == NULL) - break; - - ivda.vda_name = BYTE_GET (evda.vda_name); - - if (ivda.vda_name >= string_sec->sh_size) - name = _("*invalid*"); - else - name = strtab + ivda.vda_name; - nn += printf ("(%s%-*s", - name, - 12 - (int) strlen (name), - ")"); - } - } - - if (nn < 18) - printf ("%*c", 18 - nn, ' '); - } - - putchar ('\n'); - } - - free (data); - free (strtab); - free (symbols); - } - break; - - default: - break; - } - } - - if (! found) - printf (_("\nNo version information found in this file.\n")); - - return 1; -} - -static const char * -get_symbol_binding (unsigned int binding) -{ - static char buff[32]; - - switch (binding) - { - case STB_LOCAL: return "LOCAL"; - case STB_GLOBAL: return "GLOBAL"; - case STB_WEAK: return "WEAK"; - default: - if (binding >= STB_LOPROC && binding <= STB_HIPROC) - snprintf (buff, sizeof (buff), _(": %d"), - binding); - else if (binding >= STB_LOOS && binding <= STB_HIOS) - { - if (binding == STB_GNU_UNIQUE - && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU - /* GNU is still using the default value 0. */ - || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)) - return "UNIQUE"; - snprintf (buff, sizeof (buff), _(": %d"), binding); - } - else - snprintf (buff, sizeof (buff), _(": %d"), binding); - return buff; - } -} - -static const char * -get_symbol_type (unsigned int type) -{ - static char buff[32]; - - switch (type) - { - case STT_NOTYPE: return "NOTYPE"; - case STT_OBJECT: return "OBJECT"; - case STT_FUNC: return "FUNC"; - case STT_SECTION: return "SECTION"; - case STT_FILE: return "FILE"; - case STT_COMMON: return "COMMON"; - case STT_TLS: return "TLS"; - case STT_RELC: return "RELC"; - case STT_SRELC: return "SRELC"; - default: - if (type >= STT_LOPROC && type <= STT_HIPROC) - { - if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC) - return "THUMB_FUNC"; - - if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER) - return "REGISTER"; - - if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI) - return "PARISC_MILLI"; - - snprintf (buff, sizeof (buff), _(": %d"), type); - } - else if (type >= STT_LOOS && type <= STT_HIOS) - { - if (elf_header.e_machine == EM_PARISC) - { - if (type == STT_HP_OPAQUE) - return "HP_OPAQUE"; - if (type == STT_HP_STUB) - return "HP_STUB"; - } - - if (type == STT_GNU_IFUNC - && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU - /* GNU is still using the default value 0. */ - || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE)) - return "IFUNC"; - - snprintf (buff, sizeof (buff), _(": %d"), type); - } - else - snprintf (buff, sizeof (buff), _(": %d"), type); - return buff; - } -} - -static const char * -get_symbol_visibility (unsigned int visibility) -{ - switch (visibility) - { - case STV_DEFAULT: return "DEFAULT"; - case STV_INTERNAL: return "INTERNAL"; - case STV_HIDDEN: return "HIDDEN"; - case STV_PROTECTED: return "PROTECTED"; - default: abort (); - } -} - -static const char * -get_mips_symbol_other (unsigned int other) -{ - switch (other) - { - case STO_OPTIONAL: - return "OPTIONAL"; - case STO_MIPS_PLT: - return "MIPS PLT"; - case STO_MIPS_PIC: - return "MIPS PIC"; - case STO_MICROMIPS: - return "MICROMIPS"; - case STO_MICROMIPS | STO_MIPS_PIC: - return "MICROMIPS, MIPS PIC"; - case STO_MIPS16: - return "MIPS16"; - default: - return NULL; - } -} - -static const char * -get_ia64_symbol_other (unsigned int other) -{ - if (is_ia64_vms ()) - { - static char res[32]; - - res[0] = 0; - - /* Function types is for images and .STB files only. */ - switch (elf_header.e_type) - { - case ET_DYN: - case ET_EXEC: - switch (VMS_ST_FUNC_TYPE (other)) - { - case VMS_SFT_CODE_ADDR: - strcat (res, " CA"); - break; - case VMS_SFT_SYMV_IDX: - strcat (res, " VEC"); - break; - case VMS_SFT_FD: - strcat (res, " FD"); - break; - case VMS_SFT_RESERVE: - strcat (res, " RSV"); - break; - default: - abort (); - } - break; - default: - break; - } - switch (VMS_ST_LINKAGE (other)) - { - case VMS_STL_IGNORE: - strcat (res, " IGN"); - break; - case VMS_STL_RESERVE: - strcat (res, " RSV"); - break; - case VMS_STL_STD: - strcat (res, " STD"); - break; - case VMS_STL_LNK: - strcat (res, " LNK"); - break; - default: - abort (); - } - - if (res[0] != 0) - return res + 1; - else - return res; - } - return NULL; -} - -static const char * -get_symbol_other (unsigned int other) -{ - const char * result = NULL; - static char buff [32]; - - if (other == 0) - return ""; - - switch (elf_header.e_machine) - { - case EM_MIPS: - result = get_mips_symbol_other (other); - break; - case EM_IA_64: - result = get_ia64_symbol_other (other); - break; - default: - break; - } - - if (result) - return result; - - snprintf (buff, sizeof buff, _(": %x"), other); - return buff; -} - -static const char * -get_symbol_index_type (unsigned int type) -{ - static char buff[32]; - - switch (type) - { - case SHN_UNDEF: return "UND"; - case SHN_ABS: return "ABS"; - case SHN_COMMON: return "COM"; - default: - if (type == SHN_IA_64_ANSI_COMMON - && elf_header.e_machine == EM_IA_64 - && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX) - return "ANSI_COM"; - else if ((elf_header.e_machine == EM_X86_64 - || elf_header.e_machine == EM_L1OM - || elf_header.e_machine == EM_K1OM) - && type == SHN_X86_64_LCOMMON) - return "LARGE_COM"; - else if ((type == SHN_MIPS_SCOMMON - && elf_header.e_machine == EM_MIPS) - || (type == SHN_TIC6X_SCOMMON - && elf_header.e_machine == EM_TI_C6000)) - return "SCOM"; - else if (type == SHN_MIPS_SUNDEFINED - && elf_header.e_machine == EM_MIPS) - return "SUND"; - else if (type >= SHN_LOPROC && type <= SHN_HIPROC) - sprintf (buff, "PRC[0x%04x]", type & 0xffff); - else if (type >= SHN_LOOS && type <= SHN_HIOS) - sprintf (buff, "OS [0x%04x]", type & 0xffff); - else if (type >= SHN_LORESERVE) - sprintf (buff, "RSV[0x%04x]", type & 0xffff); - else - sprintf (buff, "%3d", type); - break; - } - - return buff; -} - -static bfd_vma * -get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size) -{ - unsigned char * e_data; - bfd_vma * i_data; - - e_data = (unsigned char *) cmalloc (number, ent_size); - - if (e_data == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - - if (fread (e_data, ent_size, number, file) != number) - { - error (_("Unable to read in dynamic data\n")); - return NULL; - } - - i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data)); - - if (i_data == NULL) - { - error (_("Out of memory\n")); - free (e_data); - return NULL; - } - - while (number--) - i_data[number] = byte_get (e_data + number * ent_size, ent_size); - - free (e_data); - - return i_data; -} - -static void -print_dynamic_symbol (bfd_vma si, unsigned long hn) -{ - Elf_Internal_Sym * psym; - int n; - - psym = dynamic_symbols + si; - - n = print_vma (si, DEC_5); - if (n < 5) - fputs (" " + n, stdout); - printf (" %3lu: ", hn); - print_vma (psym->st_value, LONG_HEX); - putchar (' '); - print_vma (psym->st_size, DEC_5); - - printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); - printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); - printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); - /* Check to see if any other bits in the st_other field are set. - Note - displaying this information disrupts the layout of the - table being generated, but for the moment this case is very - rare. */ - if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) - printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); - printf (" %3.3s ", get_symbol_index_type (psym->st_shndx)); - if (VALID_DYNAMIC_NAME (psym->st_name)) - print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); - else - printf (_(" "), psym->st_name); - putchar ('\n'); -} - -/* Dump the symbol table. */ -static int -process_symbol_table (FILE * file) -{ - Elf_Internal_Shdr * section; - bfd_vma nbuckets = 0; - bfd_vma nchains = 0; - bfd_vma * buckets = NULL; - bfd_vma * chains = NULL; - bfd_vma ngnubuckets = 0; - bfd_vma * gnubuckets = NULL; - bfd_vma * gnuchains = NULL; - bfd_vma gnusymidx = 0; - - if (!do_syms && !do_dyn_syms && !do_histogram) - return 1; - - if (dynamic_info[DT_HASH] - && (do_histogram - || (do_using_dynamic - && !do_dyn_syms - && dynamic_strings != NULL))) - { - unsigned char nb[8]; - unsigned char nc[8]; - int hash_ent_size = 4; - - if ((elf_header.e_machine == EM_ALPHA - || elf_header.e_machine == EM_S390 - || elf_header.e_machine == EM_S390_OLD) - && elf_header.e_ident[EI_CLASS] == ELFCLASS64) - hash_ent_size = 8; - - if (fseek (file, - (archive_file_offset - + offset_from_vma (file, dynamic_info[DT_HASH], - sizeof nb + sizeof nc)), - SEEK_SET)) - { - error (_("Unable to seek to start of dynamic information\n")); - goto no_hash; - } - - if (fread (nb, hash_ent_size, 1, file) != 1) - { - error (_("Failed to read in number of buckets\n")); - goto no_hash; - } - - if (fread (nc, hash_ent_size, 1, file) != 1) - { - error (_("Failed to read in number of chains\n")); - goto no_hash; - } - - nbuckets = byte_get (nb, hash_ent_size); - nchains = byte_get (nc, hash_ent_size); - - buckets = get_dynamic_data (file, nbuckets, hash_ent_size); - chains = get_dynamic_data (file, nchains, hash_ent_size); - - no_hash: - if (buckets == NULL || chains == NULL) - { - if (do_using_dynamic) - return 0; - free (buckets); - free (chains); - buckets = NULL; - chains = NULL; - nbuckets = 0; - nchains = 0; - } - } - - if (dynamic_info_DT_GNU_HASH - && (do_histogram - || (do_using_dynamic - && !do_dyn_syms - && dynamic_strings != NULL))) - { - unsigned char nb[16]; - bfd_vma i, maxchain = 0xffffffff, bitmaskwords; - bfd_vma buckets_vma; - - if (fseek (file, - (archive_file_offset - + offset_from_vma (file, dynamic_info_DT_GNU_HASH, - sizeof nb)), - SEEK_SET)) - { - error (_("Unable to seek to start of dynamic information\n")); - goto no_gnu_hash; - } - - if (fread (nb, 16, 1, file) != 1) - { - error (_("Failed to read in number of buckets\n")); - goto no_gnu_hash; - } - - ngnubuckets = byte_get (nb, 4); - gnusymidx = byte_get (nb + 4, 4); - bitmaskwords = byte_get (nb + 8, 4); - buckets_vma = dynamic_info_DT_GNU_HASH + 16; - if (is_32bit_elf) - buckets_vma += bitmaskwords * 4; - else - buckets_vma += bitmaskwords * 8; - - if (fseek (file, - (archive_file_offset - + offset_from_vma (file, buckets_vma, 4)), - SEEK_SET)) - { - error (_("Unable to seek to start of dynamic information\n")); - goto no_gnu_hash; - } - - gnubuckets = get_dynamic_data (file, ngnubuckets, 4); - - if (gnubuckets == NULL) - goto no_gnu_hash; - - for (i = 0; i < ngnubuckets; i++) - if (gnubuckets[i] != 0) - { - if (gnubuckets[i] < gnusymidx) - return 0; - - if (maxchain == 0xffffffff || gnubuckets[i] > maxchain) - maxchain = gnubuckets[i]; - } - - if (maxchain == 0xffffffff) - goto no_gnu_hash; - - maxchain -= gnusymidx; - - if (fseek (file, - (archive_file_offset - + offset_from_vma (file, buckets_vma - + 4 * (ngnubuckets + maxchain), 4)), - SEEK_SET)) - { - error (_("Unable to seek to start of dynamic information\n")); - goto no_gnu_hash; - } - - do - { - if (fread (nb, 4, 1, file) != 1) - { - error (_("Failed to determine last chain length\n")); - goto no_gnu_hash; - } - - if (maxchain + 1 == 0) - goto no_gnu_hash; - - ++maxchain; - } - while ((byte_get (nb, 4) & 1) == 0); - - if (fseek (file, - (archive_file_offset - + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)), - SEEK_SET)) - { - error (_("Unable to seek to start of dynamic information\n")); - goto no_gnu_hash; - } - - gnuchains = get_dynamic_data (file, maxchain, 4); - - no_gnu_hash: - if (gnuchains == NULL) - { - free (gnubuckets); - gnubuckets = NULL; - ngnubuckets = 0; - if (do_using_dynamic) - return 0; - } - } - - if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH) - && do_syms - && do_using_dynamic - && dynamic_strings != NULL) - { - unsigned long hn; - - if (dynamic_info[DT_HASH]) - { - bfd_vma si; - - printf (_("\nSymbol table for image:\n")); - if (is_32bit_elf) - printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n")); - else - printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n")); - - for (hn = 0; hn < nbuckets; hn++) - { - if (! buckets[hn]) - continue; - - for (si = buckets[hn]; si < nchains && si > 0; si = chains[si]) - print_dynamic_symbol (si, hn); - } - } - - if (dynamic_info_DT_GNU_HASH) - { - printf (_("\nSymbol table of `.gnu.hash' for image:\n")); - if (is_32bit_elf) - printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n")); - else - printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n")); - - for (hn = 0; hn < ngnubuckets; ++hn) - if (gnubuckets[hn] != 0) - { - bfd_vma si = gnubuckets[hn]; - bfd_vma off = si - gnusymidx; - - do - { - print_dynamic_symbol (si, hn); - si++; - } - while ((gnuchains[off++] & 1) == 0); - } - } - } - else if (do_dyn_syms || (do_syms && !do_using_dynamic)) - { - unsigned int i; - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - unsigned int si; - char * strtab = NULL; - unsigned long int strtab_size = 0; - Elf_Internal_Sym * symtab; - Elf_Internal_Sym * psym; - - if ((section->sh_type != SHT_SYMTAB - && section->sh_type != SHT_DYNSYM) - || (!do_syms - && section->sh_type == SHT_SYMTAB)) - continue; - - if (section->sh_entsize == 0) - { - printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"), - SECTION_NAME (section)); - continue; - } - - printf (_("\nSymbol table '%s' contains %lu entries:\n"), - SECTION_NAME (section), - (unsigned long) (section->sh_size / section->sh_entsize)); - - if (is_32bit_elf) - printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); - else - printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); - - symtab = GET_ELF_SYMBOLS (file, section); - if (symtab == NULL) - continue; - - if (section->sh_link == elf_header.e_shstrndx) - { - strtab = string_table; - strtab_size = string_table_length; - } - else if (section->sh_link < elf_header.e_shnum) - { - Elf_Internal_Shdr * string_sec; - - string_sec = section_headers + section->sh_link; - - strtab = (char *) get_data (NULL, file, string_sec->sh_offset, - 1, string_sec->sh_size, - _("string table")); - strtab_size = strtab != NULL ? string_sec->sh_size : 0; - } - - for (si = 0, psym = symtab; - si < section->sh_size / section->sh_entsize; - si++, psym++) - { - printf ("%6d: ", si); - print_vma (psym->st_value, LONG_HEX); - putchar (' '); - print_vma (psym->st_size, DEC_5); - printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); - printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); - printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); - /* Check to see if any other bits in the st_other field are set. - Note - displaying this information disrupts the layout of the - table being generated, but for the moment this case is very rare. */ - if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) - printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); - printf (" %4s ", get_symbol_index_type (psym->st_shndx)); - print_symbol (25, psym->st_name < strtab_size - ? strtab + psym->st_name : _("")); - - if (section->sh_type == SHT_DYNSYM - && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0) - { - unsigned char data[2]; - unsigned short vers_data; - unsigned long offset; - int is_nobits; - int check_def; - - offset = offset_from_vma - (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)], - sizeof data + si * sizeof (vers_data)); - - if (get_data (&data, file, offset + si * sizeof (vers_data), - sizeof (data), 1, _("version data")) == NULL) - break; - - vers_data = byte_get (data, 2); - - is_nobits = (psym->st_shndx < elf_header.e_shnum - && section_headers[psym->st_shndx].sh_type - == SHT_NOBITS); - - check_def = (psym->st_shndx != SHN_UNDEF); - - if ((vers_data & VERSYM_HIDDEN) || vers_data > 1) - { - if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)] - && (is_nobits || ! check_def)) - { - Elf_External_Verneed evn; - Elf_Internal_Verneed ivn; - Elf_Internal_Vernaux ivna; - - /* We must test both. */ - offset = offset_from_vma - (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)], - sizeof evn); - - do - { - unsigned long vna_off; - - if (get_data (&evn, file, offset, sizeof (evn), 1, - _("version need")) == NULL) - { - ivna.vna_next = 0; - ivna.vna_other = 0; - ivna.vna_name = 0; - break; - } - - ivn.vn_aux = BYTE_GET (evn.vn_aux); - ivn.vn_next = BYTE_GET (evn.vn_next); - - vna_off = offset + ivn.vn_aux; - - do - { - Elf_External_Vernaux evna; - - if (get_data (&evna, file, vna_off, - sizeof (evna), 1, - _("version need aux (3)")) == NULL) - { - ivna.vna_next = 0; - ivna.vna_other = 0; - ivna.vna_name = 0; - } - else - { - ivna.vna_other = BYTE_GET (evna.vna_other); - ivna.vna_next = BYTE_GET (evna.vna_next); - ivna.vna_name = BYTE_GET (evna.vna_name); - } - - vna_off += ivna.vna_next; - } - while (ivna.vna_other != vers_data - && ivna.vna_next != 0); - - if (ivna.vna_other == vers_data) - break; - - offset += ivn.vn_next; - } - while (ivn.vn_next != 0); - - if (ivna.vna_other == vers_data) - { - printf ("@%s (%d)", - ivna.vna_name < strtab_size - ? strtab + ivna.vna_name : _(""), - ivna.vna_other); - check_def = 0; - } - else if (! is_nobits) - error (_("bad dynamic symbol\n")); - else - check_def = 1; - } - - if (check_def) - { - if (vers_data != 0x8001 - && version_info[DT_VERSIONTAGIDX (DT_VERDEF)]) - { - Elf_Internal_Verdef ivd; - Elf_Internal_Verdaux ivda; - Elf_External_Verdaux evda; - unsigned long off; - - off = offset_from_vma - (file, - version_info[DT_VERSIONTAGIDX (DT_VERDEF)], - sizeof (Elf_External_Verdef)); - - do - { - Elf_External_Verdef evd; - - if (get_data (&evd, file, off, sizeof (evd), - 1, _("version def")) == NULL) - { - ivd.vd_ndx = 0; - ivd.vd_aux = 0; - ivd.vd_next = 0; - } - else - { - ivd.vd_ndx = BYTE_GET (evd.vd_ndx); - ivd.vd_aux = BYTE_GET (evd.vd_aux); - ivd.vd_next = BYTE_GET (evd.vd_next); - } - - off += ivd.vd_next; - } - while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) - && ivd.vd_next != 0); - - off -= ivd.vd_next; - off += ivd.vd_aux; - - if (get_data (&evda, file, off, sizeof (evda), - 1, _("version def aux")) == NULL) - break; - - ivda.vda_name = BYTE_GET (evda.vda_name); - - if (psym->st_name != ivda.vda_name) - printf ((vers_data & VERSYM_HIDDEN) - ? "@%s" : "@@%s", - ivda.vda_name < strtab_size - ? strtab + ivda.vda_name : _("")); - } - } - } - } - - putchar ('\n'); - } - - free (symtab); - if (strtab != string_table) - free (strtab); - } - } - else if (do_syms) - printf - (_("\nDynamic symbol information is not available for displaying symbols.\n")); - - if (do_histogram && buckets != NULL) - { - unsigned long * lengths; - unsigned long * counts; - unsigned long hn; - bfd_vma si; - unsigned long maxlength = 0; - unsigned long nzero_counts = 0; - unsigned long nsyms = 0; - - printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"), - (unsigned long) nbuckets); - printf (_(" Length Number %% of total Coverage\n")); - - lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths)); - if (lengths == NULL) - { - error (_("Out of memory\n")); - return 0; - } - for (hn = 0; hn < nbuckets; ++hn) - { - for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si]) - { - ++nsyms; - if (maxlength < ++lengths[hn]) - ++maxlength; - } - } - - counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts)); - if (counts == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - for (hn = 0; hn < nbuckets; ++hn) - ++counts[lengths[hn]]; - - if (nbuckets > 0) - { - unsigned long i; - printf (" 0 %-10lu (%5.1f%%)\n", - counts[0], (counts[0] * 100.0) / nbuckets); - for (i = 1; i <= maxlength; ++i) - { - nzero_counts += counts[i] * i; - printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n", - i, counts[i], (counts[i] * 100.0) / nbuckets, - (nzero_counts * 100.0) / nsyms); - } - } - - free (counts); - free (lengths); - } - - if (buckets != NULL) - { - free (buckets); - free (chains); - } - - if (do_histogram && gnubuckets != NULL) - { - unsigned long * lengths; - unsigned long * counts; - unsigned long hn; - unsigned long maxlength = 0; - unsigned long nzero_counts = 0; - unsigned long nsyms = 0; - - lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths)); - if (lengths == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"), - (unsigned long) ngnubuckets); - printf (_(" Length Number %% of total Coverage\n")); - - for (hn = 0; hn < ngnubuckets; ++hn) - if (gnubuckets[hn] != 0) - { - bfd_vma off, length = 1; - - for (off = gnubuckets[hn] - gnusymidx; - (gnuchains[off] & 1) == 0; ++off) - ++length; - lengths[hn] = length; - if (length > maxlength) - maxlength = length; - nsyms += length; - } - - counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts)); - if (counts == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - for (hn = 0; hn < ngnubuckets; ++hn) - ++counts[lengths[hn]]; - - if (ngnubuckets > 0) - { - unsigned long j; - printf (" 0 %-10lu (%5.1f%%)\n", - counts[0], (counts[0] * 100.0) / ngnubuckets); - for (j = 1; j <= maxlength; ++j) - { - nzero_counts += counts[j] * j; - printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n", - j, counts[j], (counts[j] * 100.0) / ngnubuckets, - (nzero_counts * 100.0) / nsyms); - } - } - - free (counts); - free (lengths); - free (gnubuckets); - free (gnuchains); - } - - return 1; -} - -static int -process_syminfo (FILE * file ATTRIBUTE_UNUSED) -{ - unsigned int i; - - if (dynamic_syminfo == NULL - || !do_dynamic) - /* No syminfo, this is ok. */ - return 1; - - /* There better should be a dynamic symbol section. */ - if (dynamic_symbols == NULL || dynamic_strings == NULL) - return 0; - - if (dynamic_addr) - printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"), - dynamic_syminfo_offset, dynamic_syminfo_nent); - - printf (_(" Num: Name BoundTo Flags\n")); - for (i = 0; i < dynamic_syminfo_nent; ++i) - { - unsigned short int flags = dynamic_syminfo[i].si_flags; - - printf ("%4d: ", i); - if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name)) - print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name)); - else - printf (_(""), dynamic_symbols[i].st_name); - putchar (' '); - - switch (dynamic_syminfo[i].si_boundto) - { - case SYMINFO_BT_SELF: - fputs ("SELF ", stdout); - break; - case SYMINFO_BT_PARENT: - fputs ("PARENT ", stdout); - break; - default: - if (dynamic_syminfo[i].si_boundto > 0 - && dynamic_syminfo[i].si_boundto < dynamic_nent - && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val)) - { - print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val)); - putchar (' ' ); - } - else - printf ("%-10d ", dynamic_syminfo[i].si_boundto); - break; - } - - if (flags & SYMINFO_FLG_DIRECT) - printf (" DIRECT"); - if (flags & SYMINFO_FLG_PASSTHRU) - printf (" PASSTHRU"); - if (flags & SYMINFO_FLG_COPY) - printf (" COPY"); - if (flags & SYMINFO_FLG_LAZYLOAD) - printf (" LAZYLOAD"); - - puts (""); - } - - return 1; -} - -/* Check to see if the given reloc needs to be handled in a target specific - manner. If so then process the reloc and return TRUE otherwise return - FALSE. */ - -static bfd_boolean -target_specific_reloc_handling (Elf_Internal_Rela * reloc, - unsigned char * start, - Elf_Internal_Sym * symtab) -{ - unsigned int reloc_type = get_reloc_type (reloc->r_info); - - switch (elf_header.e_machine) - { - case EM_MN10300: - case EM_CYGNUS_MN10300: - { - static Elf_Internal_Sym * saved_sym = NULL; - - switch (reloc_type) - { - case 34: /* R_MN10300_ALIGN */ - return TRUE; - case 33: /* R_MN10300_SYM_DIFF */ - saved_sym = symtab + get_reloc_symindex (reloc->r_info); - return TRUE; - case 1: /* R_MN10300_32 */ - case 2: /* R_MN10300_16 */ - if (saved_sym != NULL) - { - bfd_vma value; - - value = reloc->r_addend - + (symtab[get_reloc_symindex (reloc->r_info)].st_value - - saved_sym->st_value); - - byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2); - - saved_sym = NULL; - return TRUE; - } - break; - default: - if (saved_sym != NULL) - error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc")); - break; - } - break; - } - } - - return FALSE; -} - -/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in - DWARF debug sections. This is a target specific test. Note - we do not - go through the whole including-target-headers-multiple-times route, (as - we have already done with ) because this would become very - messy and even then this function would have to contain target specific - information (the names of the relocs instead of their numeric values). - FIXME: This is not the correct way to solve this problem. The proper way - is to have target specific reloc sizing and typing functions created by - the reloc-macros.h header, in the same way that it already creates the - reloc naming functions. */ - -static bfd_boolean -is_32bit_abs_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_386: - case EM_486: - return reloc_type == 1; /* R_386_32. */ - case EM_68K: - return reloc_type == 1; /* R_68K_32. */ - case EM_860: - return reloc_type == 1; /* R_860_32. */ - case EM_960: - return reloc_type == 2; /* R_960_32. */ - case EM_ALPHA: - return reloc_type == 1; /* R_ALPHA_REFLONG. */ - case EM_ARC: - return reloc_type == 1; /* R_ARC_32. */ - case EM_ARM: - return reloc_type == 2; /* R_ARM_ABS32 */ - case EM_AVR_OLD: - case EM_AVR: - return reloc_type == 1; - case EM_BLACKFIN: - return reloc_type == 0x12; /* R_byte4_data. */ - case EM_CRIS: - return reloc_type == 3; /* R_CRIS_32. */ - case EM_CR16: - case EM_CR16_OLD: - return reloc_type == 3; /* R_CR16_NUM32. */ - case EM_CRX: - return reloc_type == 15; /* R_CRX_NUM32. */ - case EM_CYGNUS_FRV: - return reloc_type == 1; - case EM_CYGNUS_D10V: - case EM_D10V: - return reloc_type == 6; /* R_D10V_32. */ - case EM_CYGNUS_D30V: - case EM_D30V: - return reloc_type == 12; /* R_D30V_32_NORMAL. */ - case EM_DLX: - return reloc_type == 3; /* R_DLX_RELOC_32. */ - case EM_CYGNUS_FR30: - case EM_FR30: - return reloc_type == 3; /* R_FR30_32. */ - case EM_H8S: - case EM_H8_300: - case EM_H8_300H: - return reloc_type == 1; /* R_H8_DIR32. */ - case EM_IA_64: - return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */ - case EM_IP2K_OLD: - case EM_IP2K: - return reloc_type == 2; /* R_IP2K_32. */ - case EM_IQ2000: - return reloc_type == 2; /* R_IQ2000_32. */ - case EM_LATTICEMICO32: - return reloc_type == 3; /* R_LM32_32. */ - case EM_M32C_OLD: - case EM_M32C: - return reloc_type == 3; /* R_M32C_32. */ - case EM_M32R: - return reloc_type == 34; /* R_M32R_32_RELA. */ - case EM_MCORE: - return reloc_type == 1; /* R_MCORE_ADDR32. */ - case EM_CYGNUS_MEP: - return reloc_type == 4; /* R_MEP_32. */ - case EM_MICROBLAZE: - return reloc_type == 1; /* R_MICROBLAZE_32. */ - case EM_MIPS: - return reloc_type == 2; /* R_MIPS_32. */ - case EM_MMIX: - return reloc_type == 4; /* R_MMIX_32. */ - case EM_CYGNUS_MN10200: - case EM_MN10200: - return reloc_type == 1; /* R_MN10200_32. */ - case EM_CYGNUS_MN10300: - case EM_MN10300: - return reloc_type == 1; /* R_MN10300_32. */ - case EM_MOXIE: - return reloc_type == 1; /* R_MOXIE_32. */ - case EM_MSP430_OLD: - case EM_MSP430: - return reloc_type == 1; /* R_MSP43_32. */ - case EM_MT: - return reloc_type == 2; /* R_MT_32. */ - case EM_ALTERA_NIOS2: - case EM_NIOS32: - return reloc_type == 1; /* R_NIOS_32. */ - case EM_OPENRISC: - case EM_OR32: - return reloc_type == 1; /* R_OR32_32. */ - case EM_PARISC: - return (reloc_type == 1 /* R_PARISC_DIR32. */ - || reloc_type == 41); /* R_PARISC_SECREL32. */ - case EM_PJ: - case EM_PJ_OLD: - return reloc_type == 1; /* R_PJ_DATA_DIR32. */ - case EM_PPC64: - return reloc_type == 1; /* R_PPC64_ADDR32. */ - case EM_PPC: - return reloc_type == 1; /* R_PPC_ADDR32. */ - case EM_RX: - return reloc_type == 1; /* R_RX_DIR32. */ - case EM_S370: - return reloc_type == 1; /* R_I370_ADDR31. */ - case EM_S390_OLD: - case EM_S390: - return reloc_type == 4; /* R_S390_32. */ - case EM_SCORE: - return reloc_type == 8; /* R_SCORE_ABS32. */ - case EM_SH: - return reloc_type == 1; /* R_SH_DIR32. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - return reloc_type == 3 /* R_SPARC_32. */ - || reloc_type == 23; /* R_SPARC_UA32. */ - case EM_SPU: - return reloc_type == 6; /* R_SPU_ADDR32 */ - case EM_TI_C6000: - return reloc_type == 1; /* R_C6000_ABS32. */ - case EM_TILEGX: - return reloc_type == 2; /* R_TILEGX_32. */ - case EM_TILEPRO: - return reloc_type == 1; /* R_TILEPRO_32. */ - case EM_CYGNUS_V850: - case EM_V850: - return reloc_type == 6; /* R_V850_ABS32. */ - case EM_VAX: - return reloc_type == 1; /* R_VAX_32. */ - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - return reloc_type == 10; /* R_X86_64_32. */ - case EM_XC16X: - case EM_C166: - return reloc_type == 3; /* R_XC16C_ABS_32. */ - case EM_XSTORMY16: - return reloc_type == 1; /* R_XSTROMY16_32. */ - case EM_XTENSA_OLD: - case EM_XTENSA: - return reloc_type == 1; /* R_XTENSA_32. */ - default: - error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"), - elf_header.e_machine); - abort (); - } -} - -/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is - a 32-bit pc-relative RELA relocation used in DWARF debug sections. */ - -static bfd_boolean -is_32bit_pcrel_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_386: - case EM_486: - return reloc_type == 2; /* R_386_PC32. */ - case EM_68K: - return reloc_type == 4; /* R_68K_PC32. */ - case EM_ALPHA: - return reloc_type == 10; /* R_ALPHA_SREL32. */ - case EM_ARM: - return reloc_type == 3; /* R_ARM_REL32 */ - case EM_MICROBLAZE: - return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */ - case EM_PARISC: - return reloc_type == 9; /* R_PARISC_PCREL32. */ - case EM_PPC: - return reloc_type == 26; /* R_PPC_REL32. */ - case EM_PPC64: - return reloc_type == 26; /* R_PPC64_REL32. */ - case EM_S390_OLD: - case EM_S390: - return reloc_type == 5; /* R_390_PC32. */ - case EM_SH: - return reloc_type == 2; /* R_SH_REL32. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - return reloc_type == 6; /* R_SPARC_DISP32. */ - case EM_SPU: - return reloc_type == 13; /* R_SPU_REL32. */ - case EM_TILEGX: - return reloc_type == 6; /* R_TILEGX_32_PCREL. */ - case EM_TILEPRO: - return reloc_type == 4; /* R_TILEPRO_32_PCREL. */ - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - return reloc_type == 2; /* R_X86_64_PC32. */ - case EM_XTENSA_OLD: - case EM_XTENSA: - return reloc_type == 14; /* R_XTENSA_32_PCREL. */ - default: - /* Do not abort or issue an error message here. Not all targets use - pc-relative 32-bit relocs in their DWARF debug information and we - have already tested for target coverage in is_32bit_abs_reloc. A - more helpful warning message will be generated by apply_relocations - anyway, so just return. */ - return FALSE; - } -} - -/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is - a 64-bit absolute RELA relocation used in DWARF debug sections. */ - -static bfd_boolean -is_64bit_abs_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_ALPHA: - return reloc_type == 2; /* R_ALPHA_REFQUAD. */ - case EM_IA_64: - return reloc_type == 0x27; /* R_IA64_DIR64LSB. */ - case EM_PARISC: - return reloc_type == 80; /* R_PARISC_DIR64. */ - case EM_PPC64: - return reloc_type == 38; /* R_PPC64_ADDR64. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - return reloc_type == 54; /* R_SPARC_UA64. */ - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - return reloc_type == 1; /* R_X86_64_64. */ - case EM_S390_OLD: - case EM_S390: - return reloc_type == 22; /* R_S390_64. */ - case EM_TILEGX: - return reloc_type == 1; /* R_TILEGX_64. */ - case EM_MIPS: - return reloc_type == 18; /* R_MIPS_64. */ - default: - return FALSE; - } -} - -/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is - a 64-bit pc-relative RELA relocation used in DWARF debug sections. */ - -static bfd_boolean -is_64bit_pcrel_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_ALPHA: - return reloc_type == 11; /* R_ALPHA_SREL64. */ - case EM_IA_64: - return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */ - case EM_PARISC: - return reloc_type == 72; /* R_PARISC_PCREL64. */ - case EM_PPC64: - return reloc_type == 44; /* R_PPC64_REL64. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: - return reloc_type == 46; /* R_SPARC_DISP64. */ - case EM_X86_64: - case EM_L1OM: - case EM_K1OM: - return reloc_type == 24; /* R_X86_64_PC64. */ - case EM_S390_OLD: - case EM_S390: - return reloc_type == 23; /* R_S390_PC64. */ - case EM_TILEGX: - return reloc_type == 5; /* R_TILEGX_64_PCREL. */ - default: - return FALSE; - } -} - -/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is - a 24-bit absolute RELA relocation used in DWARF debug sections. */ - -static bfd_boolean -is_24bit_abs_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_CYGNUS_MN10200: - case EM_MN10200: - return reloc_type == 4; /* R_MN10200_24. */ - default: - return FALSE; - } -} - -/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is - a 16-bit absolute RELA relocation used in DWARF debug sections. */ - -static bfd_boolean -is_16bit_abs_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_AVR_OLD: - case EM_AVR: - return reloc_type == 4; /* R_AVR_16. */ - case EM_CYGNUS_D10V: - case EM_D10V: - return reloc_type == 3; /* R_D10V_16. */ - case EM_H8S: - case EM_H8_300: - case EM_H8_300H: - return reloc_type == R_H8_DIR16; - case EM_IP2K_OLD: - case EM_IP2K: - return reloc_type == 1; /* R_IP2K_16. */ - case EM_M32C_OLD: - case EM_M32C: - return reloc_type == 1; /* R_M32C_16 */ - case EM_MSP430_OLD: - case EM_MSP430: - return reloc_type == 5; /* R_MSP430_16_BYTE. */ - case EM_ALTERA_NIOS2: - case EM_NIOS32: - return reloc_type == 9; /* R_NIOS_16. */ - case EM_TI_C6000: - return reloc_type == 2; /* R_C6000_ABS16. */ - case EM_XC16X: - case EM_C166: - return reloc_type == 2; /* R_XC16C_ABS_16. */ - default: - return FALSE; - } -} - -/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded - relocation entries (possibly formerly used for SHT_GROUP sections). */ - -static bfd_boolean -is_none_reloc (unsigned int reloc_type) -{ - switch (elf_header.e_machine) - { - case EM_68K: /* R_68K_NONE. */ - case EM_386: /* R_386_NONE. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: /* R_SPARC_NONE. */ - case EM_MIPS: /* R_MIPS_NONE. */ - case EM_PARISC: /* R_PARISC_NONE. */ - case EM_ALPHA: /* R_ALPHA_NONE. */ - case EM_PPC: /* R_PPC_NONE. */ - case EM_PPC64: /* R_PPC64_NONE. */ - case EM_ARM: /* R_ARM_NONE. */ - case EM_IA_64: /* R_IA64_NONE. */ - case EM_SH: /* R_SH_NONE. */ - case EM_S390_OLD: - case EM_S390: /* R_390_NONE. */ - case EM_CRIS: /* R_CRIS_NONE. */ - case EM_X86_64: /* R_X86_64_NONE. */ - case EM_L1OM: /* R_X86_64_NONE. */ - case EM_K1OM: /* R_X86_64_NONE. */ - case EM_MN10300: /* R_MN10300_NONE. */ - case EM_MOXIE: /* R_MOXIE_NONE. */ - case EM_M32R: /* R_M32R_NONE. */ - case EM_TI_C6000:/* R_C6000_NONE. */ - case EM_TILEGX: /* R_TILEGX_NONE. */ - case EM_TILEPRO: /* R_TILEPRO_NONE. */ - case EM_XC16X: - case EM_C166: /* R_XC16X_NONE. */ - return reloc_type == 0; - case EM_XTENSA_OLD: - case EM_XTENSA: - return (reloc_type == 0 /* R_XTENSA_NONE. */ - || reloc_type == 17 /* R_XTENSA_DIFF8. */ - || reloc_type == 18 /* R_XTENSA_DIFF16. */ - || reloc_type == 19 /* R_XTENSA_DIFF32. */); - } - return FALSE; -} - -/* Apply relocations to a section. - Note: So far support has been added only for those relocations - which can be found in debug sections. - FIXME: Add support for more relocations ? */ - -static void -apply_relocations (void * file, - Elf_Internal_Shdr * section, - unsigned char * start) -{ - Elf_Internal_Shdr * relsec; - unsigned char * end = start + section->sh_size; - - if (elf_header.e_type != ET_REL) - return; - - /* Find the reloc section associated with the section. */ - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - bfd_boolean is_rela; - unsigned long num_relocs; - Elf_Internal_Rela * relocs; - Elf_Internal_Rela * rp; - Elf_Internal_Shdr * symsec; - Elf_Internal_Sym * symtab; - Elf_Internal_Sym * sym; - - if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != section - || relsec->sh_size == 0 - || relsec->sh_link >= elf_header.e_shnum) - continue; - - is_rela = relsec->sh_type == SHT_RELA; - - if (is_rela) - { - if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset, - relsec->sh_size, & relocs, & num_relocs)) - return; - } - else - { - if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset, - relsec->sh_size, & relocs, & num_relocs)) - return; - } - - /* SH uses RELA but uses in place value instead of the addend field. */ - if (elf_header.e_machine == EM_SH) - is_rela = FALSE; - - symsec = section_headers + relsec->sh_link; - symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec); - - for (rp = relocs; rp < relocs + num_relocs; ++rp) - { - bfd_vma addend; - unsigned int reloc_type; - unsigned int reloc_size; - unsigned char * rloc; - - reloc_type = get_reloc_type (rp->r_info); - - if (target_specific_reloc_handling (rp, start, symtab)) - continue; - else if (is_none_reloc (reloc_type)) - continue; - else if (is_32bit_abs_reloc (reloc_type) - || is_32bit_pcrel_reloc (reloc_type)) - reloc_size = 4; - else if (is_64bit_abs_reloc (reloc_type) - || is_64bit_pcrel_reloc (reloc_type)) - reloc_size = 8; - else if (is_24bit_abs_reloc (reloc_type)) - reloc_size = 3; - else if (is_16bit_abs_reloc (reloc_type)) - reloc_size = 2; - else - { - warn (_("unable to apply unsupported reloc type %d to section %s\n"), - reloc_type, SECTION_NAME (section)); - continue; - } - - rloc = start + rp->r_offset; - if ((rloc + reloc_size) > end) - { - warn (_("skipping invalid relocation offset 0x%lx in section %s\n"), - (unsigned long) rp->r_offset, - SECTION_NAME (section)); - continue; - } - - sym = symtab + get_reloc_symindex (rp->r_info); - - /* If the reloc has a symbol associated with it, - make sure that it is of an appropriate type. - - Relocations against symbols without type can happen. - Gcc -feliminate-dwarf2-dups may generate symbols - without type for debug info. - - Icc generates relocations against function symbols - instead of local labels. - - Relocations against object symbols can happen, eg when - referencing a global array. For an example of this see - the _clz.o binary in libgcc.a. */ - if (sym != symtab - && ELF_ST_TYPE (sym->st_info) > STT_SECTION) - { - warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"), - get_symbol_type (ELF_ST_TYPE (sym->st_info)), - (long int)(rp - relocs), - SECTION_NAME (relsec)); - continue; - } - - addend = 0; - if (is_rela) - addend += rp->r_addend; - /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are - partial_inplace. */ - if (!is_rela - || (elf_header.e_machine == EM_XTENSA - && reloc_type == 1) - || ((elf_header.e_machine == EM_PJ - || elf_header.e_machine == EM_PJ_OLD) - && reloc_type == 1) - || ((elf_header.e_machine == EM_D30V - || elf_header.e_machine == EM_CYGNUS_D30V) - && reloc_type == 12)) - addend += byte_get (rloc, reloc_size); - - if (is_32bit_pcrel_reloc (reloc_type) - || is_64bit_pcrel_reloc (reloc_type)) - { - /* On HPPA, all pc-relative relocations are biased by 8. */ - if (elf_header.e_machine == EM_PARISC) - addend -= 8; - byte_put (rloc, (addend + sym->st_value) - rp->r_offset, - reloc_size); - } - else - byte_put (rloc, addend + sym->st_value, reloc_size); - } - - free (symtab); - free (relocs); - break; - } -} - -#ifdef SUPPORT_DISASSEMBLY -static int -disassemble_section (Elf_Internal_Shdr * section, FILE * file) -{ - printf (_("\nAssembly dump of section %s\n"), - SECTION_NAME (section)); - - /* XXX -- to be done --- XXX */ - - return 1; -} -#endif - -/* Reads in the contents of SECTION from FILE, returning a pointer - to a malloc'ed buffer or NULL if something went wrong. */ - -static char * -get_section_contents (Elf_Internal_Shdr * section, FILE * file) -{ - bfd_size_type num_bytes; - - num_bytes = section->sh_size; - - if (num_bytes == 0 || section->sh_type == SHT_NOBITS) - { - printf (_("\nSection '%s' has no data to dump.\n"), - SECTION_NAME (section)); - return NULL; - } - - return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes, - _("section contents")); -} - - -static void -dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file) -{ - Elf_Internal_Shdr * relsec; - bfd_size_type num_bytes; - char * data; - char * end; - char * start; - char * name = SECTION_NAME (section); - bfd_boolean some_strings_shown; - - start = get_section_contents (section, file); - if (start == NULL) - return; - - printf (_("\nString dump of section '%s':\n"), name); - - /* If the section being dumped has relocations against it the user might - be expecting these relocations to have been applied. Check for this - case and issue a warning message in order to avoid confusion. - FIXME: Maybe we ought to have an option that dumps a section with - relocs applied ? */ - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != section - || relsec->sh_size == 0 - || relsec->sh_link >= elf_header.e_shnum) - continue; - - printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n")); - break; - } - - num_bytes = section->sh_size; - data = start; - end = start + num_bytes; - some_strings_shown = FALSE; - - while (data < end) - { - while (!ISPRINT (* data)) - if (++ data >= end) - break; - - if (data < end) - { -#ifndef __MSVCRT__ - /* PR 11128: Use two separate invocations in order to work - around bugs in the Solaris 8 implementation of printf. */ - printf (" [%6tx] ", data - start); - printf ("%s\n", data); -#else - printf (" [%6Ix] %s\n", (size_t) (data - start), data); -#endif - data += strlen (data); - some_strings_shown = TRUE; - } - } - - if (! some_strings_shown) - printf (_(" No strings found in this section.")); - - free (start); - - putchar ('\n'); -} - -static void -dump_section_as_bytes (Elf_Internal_Shdr * section, - FILE * file, - bfd_boolean relocate) -{ - Elf_Internal_Shdr * relsec; - bfd_size_type bytes; - bfd_vma addr; - unsigned char * data; - unsigned char * start; - - start = (unsigned char *) get_section_contents (section, file); - if (start == NULL) - return; - - printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section)); - - if (relocate) - { - apply_relocations (file, section, start); - } - else - { - /* If the section being dumped has relocations against it the user might - be expecting these relocations to have been applied. Check for this - case and issue a warning message in order to avoid confusion. - FIXME: Maybe we ought to have an option that dumps a section with - relocs applied ? */ - for (relsec = section_headers; - relsec < section_headers + elf_header.e_shnum; - ++relsec) - { - if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) - || relsec->sh_info >= elf_header.e_shnum - || section_headers + relsec->sh_info != section - || relsec->sh_size == 0 - || relsec->sh_link >= elf_header.e_shnum) - continue; - - printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n")); - break; - } - } - - addr = section->sh_addr; - bytes = section->sh_size; - data = start; - - while (bytes) - { - int j; - int k; - int lbytes; - - lbytes = (bytes > 16 ? 16 : bytes); - - printf (" 0x%8.8lx ", (unsigned long) addr); - - for (j = 0; j < 16; j++) - { - if (j < lbytes) - printf ("%2.2x", data[j]); - else - printf (" "); - - if ((j & 3) == 3) - printf (" "); - } - - for (j = 0; j < lbytes; j++) - { - k = data[j]; - if (k >= ' ' && k < 0x7f) - printf ("%c", k); - else - printf ("."); - } - - putchar ('\n'); - - data += lbytes; - addr += lbytes; - bytes -= lbytes; - } - - free (start); - - putchar ('\n'); -} - -/* Uncompresses a section that was compressed using zlib, in place. */ - -static int -uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED, - dwarf_size_type *size ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - return FALSE; -#else - dwarf_size_type compressed_size = *size; - unsigned char * compressed_buffer = *buffer; - dwarf_size_type uncompressed_size; - unsigned char * uncompressed_buffer; - z_stream strm; - int rc; - dwarf_size_type header_size = 12; - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (compressed_size < header_size - || ! streq ((char *) compressed_buffer, "ZLIB")) - return 0; - - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; - - /* It is possible the section consists of several compressed - buffers concatenated together, so we uncompress in a loop. */ - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - strm.avail_in = compressed_size - header_size; - strm.next_in = (Bytef *) compressed_buffer + header_size; - strm.avail_out = uncompressed_size; - uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size); - - rc = inflateInit (& strm); - while (strm.avail_in > 0) - { - if (rc != Z_OK) - goto fail; - strm.next_out = ((Bytef *) uncompressed_buffer - + (uncompressed_size - strm.avail_out)); - rc = inflate (&strm, Z_FINISH); - if (rc != Z_STREAM_END) - goto fail; - rc = inflateReset (& strm); - } - rc = inflateEnd (& strm); - if (rc != Z_OK - || strm.avail_out != 0) - goto fail; - - free (compressed_buffer); - *buffer = uncompressed_buffer; - *size = uncompressed_size; - return 1; - - fail: - free (uncompressed_buffer); - /* Indicate decompression failure. */ - *buffer = NULL; - return 0; -#endif /* HAVE_ZLIB_H */ -} - -static int -load_specific_debug_section (enum dwarf_section_display_enum debug, - Elf_Internal_Shdr * sec, void * file) -{ - struct dwarf_section * section = &debug_displays [debug].section; - char buf [64]; - - /* If it is already loaded, do nothing. */ - if (section->start != NULL) - return 1; - - snprintf (buf, sizeof (buf), _("%s section data"), section->name); - section->address = sec->sh_addr; - section->start = (unsigned char *) get_data (NULL, (FILE *) file, - sec->sh_offset, 1, - sec->sh_size, buf); - if (section->start == NULL) - section->size = 0; - else - { - section->size = sec->sh_size; - if (uncompress_section_contents (§ion->start, §ion->size)) - sec->sh_size = section->size; - } - - if (section->start == NULL) - return 0; - - if (debug_displays [debug].relocate) - apply_relocations ((FILE *) file, sec, section->start); - - return 1; -} - -int -load_debug_section (enum dwarf_section_display_enum debug, void * file) -{ - struct dwarf_section * section = &debug_displays [debug].section; - Elf_Internal_Shdr * sec; - - /* Locate the debug section. */ - sec = find_section (section->uncompressed_name); - if (sec != NULL) - section->name = section->uncompressed_name; - else - { - sec = find_section (section->compressed_name); - if (sec != NULL) - section->name = section->compressed_name; - } - if (sec == NULL) - return 0; - - return load_specific_debug_section (debug, sec, (FILE *) file); -} - -void -free_debug_section (enum dwarf_section_display_enum debug) -{ - struct dwarf_section * section = &debug_displays [debug].section; - - if (section->start == NULL) - return; - - free ((char *) section->start); - section->start = NULL; - section->address = 0; - section->size = 0; -} - -static int -display_debug_section (Elf_Internal_Shdr * section, FILE * file) -{ - char * name = SECTION_NAME (section); - bfd_size_type length; - int result = 1; - int i; - - length = section->sh_size; - if (length == 0) - { - printf (_("\nSection '%s' has no debugging data.\n"), name); - return 0; - } - if (section->sh_type == SHT_NOBITS) - { - /* There is no point in dumping the contents of a debugging section - which has the NOBITS type - the bits in the file will be random. - This can happen when a file containing a .eh_frame section is - stripped with the --only-keep-debug command line option. */ - printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name); - return 0; - } - - if (const_strneq (name, ".gnu.linkonce.wi.")) - name = ".debug_info"; - - /* See if we know how to display the contents of this section. */ - for (i = 0; i < max; i++) - if (streq (debug_displays[i].section.uncompressed_name, name) - || streq (debug_displays[i].section.compressed_name, name)) - { - struct dwarf_section * sec = &debug_displays [i].section; - int secondary = (section != find_section (name)); - - if (secondary) - free_debug_section ((enum dwarf_section_display_enum) i); - - if (streq (sec->uncompressed_name, name)) - sec->name = sec->uncompressed_name; - else - sec->name = sec->compressed_name; - if (load_specific_debug_section ((enum dwarf_section_display_enum) i, - section, file)) - { - result &= debug_displays[i].display (sec, file); - - if (secondary || (i != info && i != abbrev)) - free_debug_section ((enum dwarf_section_display_enum) i); - } - - break; - } - - if (i == max) - { - printf (_("Unrecognized debug section: %s\n"), name); - result = 0; - } - - return result; -} - -/* Set DUMP_SECTS for all sections where dumps were requested - based on section name. */ - -static void -initialise_dumps_byname (void) -{ - struct dump_list_entry * cur; - - for (cur = dump_sects_byname; cur; cur = cur->next) - { - unsigned int i; - int any; - - for (i = 0, any = 0; i < elf_header.e_shnum; i++) - if (streq (SECTION_NAME (section_headers + i), cur->name)) - { - request_dump_bynumber (i, cur->type); - any = 1; - } - - if (!any) - warn (_("Section '%s' was not dumped because it does not exist!\n"), - cur->name); - } -} - -static void -process_section_contents (FILE * file) -{ - Elf_Internal_Shdr * section; - unsigned int i; - - if (! do_dump) - return; - - initialise_dumps_byname (); - - for (i = 0, section = section_headers; - i < elf_header.e_shnum && i < num_dump_sects; - i++, section++) - { -#ifdef SUPPORT_DISASSEMBLY - if (dump_sects[i] & DISASS_DUMP) - disassemble_section (section, file); -#endif - if (dump_sects[i] & HEX_DUMP) - dump_section_as_bytes (section, file, FALSE); - - if (dump_sects[i] & RELOC_DUMP) - dump_section_as_bytes (section, file, TRUE); - - if (dump_sects[i] & STRING_DUMP) - dump_section_as_strings (section, file); - - if (dump_sects[i] & DEBUG_DUMP) - display_debug_section (section, file); - } - - /* Check to see if the user requested a - dump of a section that does not exist. */ - while (i++ < num_dump_sects) - if (dump_sects[i]) - warn (_("Section %d was not dumped because it does not exist!\n"), i); -} - -static void -process_mips_fpe_exception (int mask) -{ - if (mask) - { - int first = 1; - if (mask & OEX_FPU_INEX) - fputs ("INEX", stdout), first = 0; - if (mask & OEX_FPU_UFLO) - printf ("%sUFLO", first ? "" : "|"), first = 0; - if (mask & OEX_FPU_OFLO) - printf ("%sOFLO", first ? "" : "|"), first = 0; - if (mask & OEX_FPU_DIV0) - printf ("%sDIV0", first ? "" : "|"), first = 0; - if (mask & OEX_FPU_INVAL) - printf ("%sINVAL", first ? "" : "|"); - } - else - fputs ("0", stdout); -} - -/* ARM EABI attributes section. */ -typedef struct -{ - int tag; - const char * name; - /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */ - int type; - const char ** table; -} arm_attr_public_tag; - -static const char * arm_attr_tag_CPU_arch[] = - {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2", - "v6K", "v7", "v6-M", "v6S-M", "v7E-M"}; -static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"}; -static const char * arm_attr_tag_THUMB_ISA_use[] = - {"No", "Thumb-1", "Thumb-2"}; -static const char * arm_attr_tag_FP_arch[] = - {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"}; -static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"}; -static const char * arm_attr_tag_Advanced_SIMD_arch[] = - {"No", "NEONv1", "NEONv1 with Fused-MAC"}; -static const char * arm_attr_tag_PCS_config[] = - {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004", - "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"}; -static const char * arm_attr_tag_ABI_PCS_R9_use[] = - {"V6", "SB", "TLS", "Unused"}; -static const char * arm_attr_tag_ABI_PCS_RW_data[] = - {"Absolute", "PC-relative", "SB-relative", "None"}; -static const char * arm_attr_tag_ABI_PCS_RO_data[] = - {"Absolute", "PC-relative", "None"}; -static const char * arm_attr_tag_ABI_PCS_GOT_use[] = - {"None", "direct", "GOT-indirect"}; -static const char * arm_attr_tag_ABI_PCS_wchar_t[] = - {"None", "??? 1", "2", "??? 3", "4"}; -static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"}; -static const char * arm_attr_tag_ABI_FP_denormal[] = - {"Unused", "Needed", "Sign only"}; -static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"}; -static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"}; -static const char * arm_attr_tag_ABI_FP_number_model[] = - {"Unused", "Finite", "RTABI", "IEEE 754"}; -static const char * arm_attr_tag_ABI_enum_size[] = - {"Unused", "small", "int", "forced to int"}; -static const char * arm_attr_tag_ABI_HardFP_use[] = - {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"}; -static const char * arm_attr_tag_ABI_VFP_args[] = - {"AAPCS", "VFP registers", "custom"}; -static const char * arm_attr_tag_ABI_WMMX_args[] = - {"AAPCS", "WMMX registers", "custom"}; -static const char * arm_attr_tag_ABI_optimization_goals[] = - {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size", - "Aggressive Size", "Prefer Debug", "Aggressive Debug"}; -static const char * arm_attr_tag_ABI_FP_optimization_goals[] = - {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size", - "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"}; -static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"}; -static const char * arm_attr_tag_FP_HP_extension[] = - {"Not Allowed", "Allowed"}; -static const char * arm_attr_tag_ABI_FP_16bit_format[] = - {"None", "IEEE 754", "Alternative Format"}; -static const char * arm_attr_tag_MPextension_use[] = - {"Not Allowed", "Allowed"}; -static const char * arm_attr_tag_DIV_use[] = - {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed", - "Allowed in v7-A with integer division extension"}; -static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"}; -static const char * arm_attr_tag_Virtualization_use[] = - {"Not Allowed", "TrustZone", "Virtualization Extensions", - "TrustZone and Virtualization Extensions"}; -static const char * arm_attr_tag_MPextension_use_legacy[] = - {"Not Allowed", "Allowed"}; - -#define LOOKUP(id, name) \ - {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name} -static arm_attr_public_tag arm_attr_public_tags[] = -{ - {4, "CPU_raw_name", 1, NULL}, - {5, "CPU_name", 1, NULL}, - LOOKUP(6, CPU_arch), - {7, "CPU_arch_profile", 0, NULL}, - LOOKUP(8, ARM_ISA_use), - LOOKUP(9, THUMB_ISA_use), - LOOKUP(10, FP_arch), - LOOKUP(11, WMMX_arch), - LOOKUP(12, Advanced_SIMD_arch), - LOOKUP(13, PCS_config), - LOOKUP(14, ABI_PCS_R9_use), - LOOKUP(15, ABI_PCS_RW_data), - LOOKUP(16, ABI_PCS_RO_data), - LOOKUP(17, ABI_PCS_GOT_use), - LOOKUP(18, ABI_PCS_wchar_t), - LOOKUP(19, ABI_FP_rounding), - LOOKUP(20, ABI_FP_denormal), - LOOKUP(21, ABI_FP_exceptions), - LOOKUP(22, ABI_FP_user_exceptions), - LOOKUP(23, ABI_FP_number_model), - {24, "ABI_align_needed", 0, NULL}, - {25, "ABI_align_preserved", 0, NULL}, - LOOKUP(26, ABI_enum_size), - LOOKUP(27, ABI_HardFP_use), - LOOKUP(28, ABI_VFP_args), - LOOKUP(29, ABI_WMMX_args), - LOOKUP(30, ABI_optimization_goals), - LOOKUP(31, ABI_FP_optimization_goals), - {32, "compatibility", 0, NULL}, - LOOKUP(34, CPU_unaligned_access), - LOOKUP(36, FP_HP_extension), - LOOKUP(38, ABI_FP_16bit_format), - LOOKUP(42, MPextension_use), - LOOKUP(44, DIV_use), - {64, "nodefaults", 0, NULL}, - {65, "also_compatible_with", 0, NULL}, - LOOKUP(66, T2EE_use), - {67, "conformance", 1, NULL}, - LOOKUP(68, Virtualization_use), - LOOKUP(70, MPextension_use_legacy) -}; -#undef LOOKUP - -static unsigned char * -display_arm_attribute (unsigned char * p) -{ - int tag; - unsigned int len; - int val; - arm_attr_public_tag * attr; - unsigned i; - int type; - - tag = read_uleb128 (p, &len); - p += len; - attr = NULL; - for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++) - { - if (arm_attr_public_tags[i].tag == tag) - { - attr = &arm_attr_public_tags[i]; - break; - } - } - - if (attr) - { - printf (" Tag_%s: ", attr->name); - switch (attr->type) - { - case 0: - switch (tag) - { - case 7: /* Tag_CPU_arch_profile. */ - val = read_uleb128 (p, &len); - p += len; - switch (val) - { - case 0: printf (_("None\n")); break; - case 'A': printf (_("Application\n")); break; - case 'R': printf (_("Realtime\n")); break; - case 'M': printf (_("Microcontroller\n")); break; - case 'S': printf (_("Application or Realtime\n")); break; - default: printf ("??? (%d)\n", val); break; - } - break; - - case 24: /* Tag_align_needed. */ - val = read_uleb128 (p, &len); - p += len; - switch (val) - { - case 0: printf (_("None\n")); break; - case 1: printf (_("8-byte\n")); break; - case 2: printf (_("4-byte\n")); break; - case 3: printf ("??? 3\n"); break; - default: - if (val <= 12) - printf (_("8-byte and up to %d-byte extended\n"), - 1 << val); - else - printf ("??? (%d)\n", val); - break; - } - break; - - case 25: /* Tag_align_preserved. */ - val = read_uleb128 (p, &len); - p += len; - switch (val) - { - case 0: printf (_("None\n")); break; - case 1: printf (_("8-byte, except leaf SP\n")); break; - case 2: printf (_("8-byte\n")); break; - case 3: printf ("??? 3\n"); break; - default: - if (val <= 12) - printf (_("8-byte and up to %d-byte extended\n"), - 1 << val); - else - printf ("??? (%d)\n", val); - break; - } - break; - - case 32: /* Tag_compatibility. */ - val = read_uleb128 (p, &len); - p += len; - printf (_("flag = %d, vendor = %s\n"), val, p); - p += strlen ((char *) p) + 1; - break; - - case 64: /* Tag_nodefaults. */ - p++; - printf (_("True\n")); - break; - - case 65: /* Tag_also_compatible_with. */ - val = read_uleb128 (p, &len); - p += len; - if (val == 6 /* Tag_CPU_arch. */) - { - val = read_uleb128 (p, &len); - p += len; - if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch)) - printf ("??? (%d)\n", val); - else - printf ("%s\n", arm_attr_tag_CPU_arch[val]); - } - else - printf ("???\n"); - while (*(p++) != '\0' /* NUL terminator. */); - break; - - default: - abort (); - } - return p; - - case 1: - case 2: - type = attr->type; - break; - - default: - assert (attr->type & 0x80); - val = read_uleb128 (p, &len); - p += len; - type = attr->type & 0x7f; - if (val >= type) - printf ("??? (%d)\n", val); - else - printf ("%s\n", attr->table[val]); - return p; - } - } - else - { - if (tag & 1) - type = 1; /* String. */ - else - type = 2; /* uleb128. */ - printf (" Tag_unknown_%d: ", tag); - } - - if (type == 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static unsigned char * -display_gnu_attribute (unsigned char * p, - unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int)) -{ - int tag; - unsigned int len; - int val; - int type; - - tag = read_uleb128 (p, &len); - p += len; - - /* Tag_compatibility is the only generic GNU attribute defined at - present. */ - if (tag == 32) - { - val = read_uleb128 (p, &len); - p += len; - printf (_("flag = %d, vendor = %s\n"), val, p); - p += strlen ((char *) p) + 1; - return p; - } - - if ((tag & 2) == 0 && display_proc_gnu_attribute) - return display_proc_gnu_attribute (p, tag); - - if (tag & 1) - type = 1; /* String. */ - else - type = 2; /* uleb128. */ - printf (" Tag_unknown_%d: ", tag); - - if (type == 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static unsigned char * -display_power_gnu_attribute (unsigned char * p, int tag) -{ - int type; - unsigned int len; - int val; - - if (tag == Tag_GNU_Power_ABI_FP) - { - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_GNU_Power_ABI_FP: "); - - switch (val) - { - case 0: - printf (_("Hard or soft float\n")); - break; - case 1: - printf (_("Hard float\n")); - break; - case 2: - printf (_("Soft float\n")); - break; - case 3: - printf (_("Single-precision hard float\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - } - - if (tag == Tag_GNU_Power_ABI_Vector) - { - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_GNU_Power_ABI_Vector: "); - switch (val) - { - case 0: - printf (_("Any\n")); - break; - case 1: - printf (_("Generic\n")); - break; - case 2: - printf ("AltiVec\n"); - break; - case 3: - printf ("SPE\n"); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - } - - if (tag == Tag_GNU_Power_ABI_Struct_Return) - { - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_GNU_Power_ABI_Struct_Return: "); - switch (val) - { - case 0: - printf (_("Any\n")); - break; - case 1: - printf ("r3/r4\n"); - break; - case 2: - printf (_("Memory\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - } - - if (tag & 1) - type = 1; /* String. */ - else - type = 2; /* uleb128. */ - printf (" Tag_unknown_%d: ", tag); - - if (type == 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static void -display_sparc_hwcaps (int mask) -{ - if (mask) - { - int first = 1; - if (mask & ELF_SPARC_HWCAP_MUL32) - fputs ("mul32", stdout), first = 0; - if (mask & ELF_SPARC_HWCAP_DIV32) - printf ("%sdiv32", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_FSMULD) - printf ("%sfsmuld", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_V8PLUS) - printf ("%sv8plus", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_POPC) - printf ("%spopc", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_VIS) - printf ("%svis", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_VIS2) - printf ("%svis2", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT) - printf ("%sASIBlkInit", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_FMAF) - printf ("%sfmaf", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_VIS3) - printf ("%svis3", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_HPC) - printf ("%shpc", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_RANDOM) - printf ("%srandom", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_TRANS) - printf ("%strans", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_FJFMAU) - printf ("%sfjfmau", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_IMA) - printf ("%sima", first ? "" : "|"), first = 0; - if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING) - printf ("%scspare", first ? "" : "|"), first = 0; - } - else - fputc('0', stdout); - fputc('\n', stdout); -} - -static unsigned char * -display_sparc_gnu_attribute (unsigned char * p, int tag) -{ - int type; - unsigned int len; - int val; - - if (tag == Tag_GNU_Sparc_HWCAPS) - { - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_GNU_Sparc_HWCAPS: "); - - display_sparc_hwcaps (val); - return p; - } - - if (tag & 1) - type = 1; /* String. */ - else - type = 2; /* uleb128. */ - printf (" Tag_unknown_%d: ", tag); - - if (type == 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static unsigned char * -display_mips_gnu_attribute (unsigned char * p, int tag) -{ - int type; - unsigned int len; - int val; - - if (tag == Tag_GNU_MIPS_ABI_FP) - { - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_GNU_MIPS_ABI_FP: "); - - switch (val) - { - case 0: - printf (_("Hard or soft float\n")); - break; - case 1: - printf (_("Hard float (double precision)\n")); - break; - case 2: - printf (_("Hard float (single precision)\n")); - break; - case 3: - printf (_("Soft float\n")); - break; - case 4: - printf (_("Hard float (MIPS32r2 64-bit FPU)\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - } - - if (tag & 1) - type = 1; /* String. */ - else - type = 2; /* uleb128. */ - printf (" Tag_unknown_%d: ", tag); - - if (type == 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static unsigned char * -display_tic6x_attribute (unsigned char * p) -{ - int tag; - unsigned int len; - int val; - - tag = read_uleb128 (p, &len); - p += len; - - switch (tag) - { - case Tag_ISA: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ISA: "); - - switch (val) - { - case C6XABI_Tag_ISA_none: - printf (_("None\n")); - break; - case C6XABI_Tag_ISA_C62X: - printf ("C62x\n"); - break; - case C6XABI_Tag_ISA_C67X: - printf ("C67x\n"); - break; - case C6XABI_Tag_ISA_C67XP: - printf ("C67x+\n"); - break; - case C6XABI_Tag_ISA_C64X: - printf ("C64x\n"); - break; - case C6XABI_Tag_ISA_C64XP: - printf ("C64x+\n"); - break; - case C6XABI_Tag_ISA_C674X: - printf ("C674x\n"); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_wchar_t: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_wchar_t: "); - switch (val) - { - case 0: - printf (_("Not used\n")); - break; - case 1: - printf (_("2 bytes\n")); - break; - case 2: - printf (_("4 bytes\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_stack_align_needed: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_stack_align_needed: "); - switch (val) - { - case 0: - printf (_("8-byte\n")); - break; - case 1: - printf (_("16-byte\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_stack_align_preserved: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_stack_align_preserved: "); - switch (val) - { - case 0: - printf (_("8-byte\n")); - break; - case 1: - printf (_("16-byte\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_DSBT: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_DSBT: "); - switch (val) - { - case 0: - printf (_("DSBT addressing not used\n")); - break; - case 1: - printf (_("DSBT addressing used\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_PID: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_PID: "); - switch (val) - { - case 0: - printf (_("Data addressing position-dependent\n")); - break; - case 1: - printf (_("Data addressing position-independent, GOT near DP\n")); - break; - case 2: - printf (_("Data addressing position-independent, GOT far from DP\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_PIC: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_PIC: "); - switch (val) - { - case 0: - printf (_("Code addressing position-dependent\n")); - break; - case 1: - printf (_("Code addressing position-independent\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_array_object_alignment: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_array_object_alignment: "); - switch (val) - { - case 0: - printf (_("8-byte\n")); - break; - case 1: - printf (_("4-byte\n")); - break; - case 2: - printf (_("16-byte\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_array_object_align_expected: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_array_object_align_expected: "); - switch (val) - { - case 0: - printf (_("8-byte\n")); - break; - case 1: - printf (_("4-byte\n")); - break; - case 2: - printf (_("16-byte\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } - return p; - - case Tag_ABI_compatibility: - val = read_uleb128 (p, &len); - p += len; - printf (" Tag_ABI_compatibility: "); - printf (_("flag = %d, vendor = %s\n"), val, p); - p += strlen ((char *) p) + 1; - return p; - - case Tag_ABI_conformance: - printf (" Tag_ABI_conformance: "); - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - return p; - } - - printf (" Tag_unknown_%d: ", tag); - - if (tag & 1) - { - printf ("\"%s\"\n", p); - p += strlen ((char *) p) + 1; - } - else - { - val = read_uleb128 (p, &len); - p += len; - printf ("%d (0x%x)\n", val, val); - } - - return p; -} - -static int -process_attributes (FILE * file, - const char * public_name, - unsigned int proc_type, - unsigned char * (* display_pub_attribute) (unsigned char *), - unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int)) -{ - Elf_Internal_Shdr * sect; - unsigned char * contents; - unsigned char * p; - unsigned char * end; - bfd_vma section_len; - bfd_vma len; - unsigned i; - - /* Find the section header so that we get the size. */ - for (i = 0, sect = section_headers; - i < elf_header.e_shnum; - i++, sect++) - { - if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES) - continue; - - contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1, - sect->sh_size, _("attributes")); - if (contents == NULL) - continue; - - p = contents; - if (*p == 'A') - { - len = sect->sh_size - 1; - p++; - - while (len > 0) - { - int namelen; - bfd_boolean public_section; - bfd_boolean gnu_section; - - section_len = byte_get (p, 4); - p += 4; - - if (section_len > len) - { - printf (_("ERROR: Bad section length (%d > %d)\n"), - (int) section_len, (int) len); - section_len = len; - } - - len -= section_len; - printf (_("Attribute Section: %s\n"), p); - - if (public_name && streq ((char *) p, public_name)) - public_section = TRUE; - else - public_section = FALSE; - - if (streq ((char *) p, "gnu")) - gnu_section = TRUE; - else - gnu_section = FALSE; - - namelen = strlen ((char *) p) + 1; - p += namelen; - section_len -= namelen + 4; - - while (section_len > 0) - { - int tag = *(p++); - int val; - bfd_vma size; - - size = byte_get (p, 4); - if (size > section_len) - { - printf (_("ERROR: Bad subsection length (%d > %d)\n"), - (int) size, (int) section_len); - size = section_len; - } - - section_len -= size; - end = p + size - 1; - p += 4; - - switch (tag) - { - case 1: - printf (_("File Attributes\n")); - break; - case 2: - printf (_("Section Attributes:")); - goto do_numlist; - case 3: - printf (_("Symbol Attributes:")); - do_numlist: - for (;;) - { - unsigned int j; - - val = read_uleb128 (p, &j); - p += j; - if (val == 0) - break; - printf (" %d", val); - } - printf ("\n"); - break; - default: - printf (_("Unknown tag: %d\n"), tag); - public_section = FALSE; - break; - } - - if (public_section) - { - while (p < end) - p = display_pub_attribute (p); - } - else if (gnu_section) - { - while (p < end) - p = display_gnu_attribute (p, - display_proc_gnu_attribute); - } - else - { - /* ??? Do something sensible, like dump hex. */ - printf (_(" Unknown section contexts\n")); - p = end; - } - } - } - } - else - printf (_("Unknown format '%c'\n"), *p); - - free (contents); - } - return 1; -} - -static int -process_arm_specific (FILE * file) -{ - return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES, - display_arm_attribute, NULL); -} - -static int -process_power_specific (FILE * file) -{ - return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL, - display_power_gnu_attribute); -} - -static int -process_sparc_specific (FILE * file) -{ - return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL, - display_sparc_gnu_attribute); -} - -static int -process_tic6x_specific (FILE * file) -{ - return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES, - display_tic6x_attribute, NULL); -} - -/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT. - Print the Address, Access and Initial fields of an entry at VMA ADDR - and return the VMA of the next entry. */ - -static bfd_vma -print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr) -{ - printf (" "); - print_vma (addr, LONG_HEX); - printf (" "); - if (addr < pltgot + 0xfff0) - printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0)); - else - printf ("%10s", ""); - printf (" "); - if (data == NULL) - printf ("%*s", is_32bit_elf ? 8 : 16, _("")); - else - { - bfd_vma entry; - - entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8); - print_vma (entry, LONG_HEX); - } - return addr + (is_32bit_elf ? 4 : 8); -} - -/* DATA points to the contents of a MIPS PLT GOT that starts at VMA - PLTGOT. Print the Address and Initial fields of an entry at VMA - ADDR and return the VMA of the next entry. */ - -static bfd_vma -print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr) -{ - printf (" "); - print_vma (addr, LONG_HEX); - printf (" "); - if (data == NULL) - printf ("%*s", is_32bit_elf ? 8 : 16, _("")); - else - { - bfd_vma entry; - - entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8); - print_vma (entry, LONG_HEX); - } - return addr + (is_32bit_elf ? 4 : 8); -} - -static int -process_mips_specific (FILE * file) -{ - Elf_Internal_Dyn * entry; - size_t liblist_offset = 0; - size_t liblistno = 0; - size_t conflictsno = 0; - size_t options_offset = 0; - size_t conflicts_offset = 0; - size_t pltrelsz = 0; - size_t pltrel = 0; - bfd_vma pltgot = 0; - bfd_vma mips_pltgot = 0; - bfd_vma jmprel = 0; - bfd_vma local_gotno = 0; - bfd_vma gotsym = 0; - bfd_vma symtabno = 0; - - process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL, - display_mips_gnu_attribute); - - /* We have a lot of special sections. Thanks SGI! */ - if (dynamic_section == NULL) - /* No information available. */ - return 0; - - for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry) - switch (entry->d_tag) - { - case DT_MIPS_LIBLIST: - liblist_offset - = offset_from_vma (file, entry->d_un.d_val, - liblistno * sizeof (Elf32_External_Lib)); - break; - case DT_MIPS_LIBLISTNO: - liblistno = entry->d_un.d_val; - break; - case DT_MIPS_OPTIONS: - options_offset = offset_from_vma (file, entry->d_un.d_val, 0); - break; - case DT_MIPS_CONFLICT: - conflicts_offset - = offset_from_vma (file, entry->d_un.d_val, - conflictsno * sizeof (Elf32_External_Conflict)); - break; - case DT_MIPS_CONFLICTNO: - conflictsno = entry->d_un.d_val; - break; - case DT_PLTGOT: - pltgot = entry->d_un.d_ptr; - break; - case DT_MIPS_LOCAL_GOTNO: - local_gotno = entry->d_un.d_val; - break; - case DT_MIPS_GOTSYM: - gotsym = entry->d_un.d_val; - break; - case DT_MIPS_SYMTABNO: - symtabno = entry->d_un.d_val; - break; - case DT_MIPS_PLTGOT: - mips_pltgot = entry->d_un.d_ptr; - break; - case DT_PLTREL: - pltrel = entry->d_un.d_val; - break; - case DT_PLTRELSZ: - pltrelsz = entry->d_un.d_val; - break; - case DT_JMPREL: - jmprel = entry->d_un.d_ptr; - break; - default: - break; - } - - if (liblist_offset != 0 && liblistno != 0 && do_dynamic) - { - Elf32_External_Lib * elib; - size_t cnt; - - elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset, - liblistno, - sizeof (Elf32_External_Lib), - _("liblist")); - if (elib) - { - printf (_("\nSection '.liblist' contains %lu entries:\n"), - (unsigned long) liblistno); - fputs (_(" Library Time Stamp Checksum Version Flags\n"), - stdout); - - for (cnt = 0; cnt < liblistno; ++cnt) - { - Elf32_Lib liblist; - time_t atime; - char timebuf[20]; - struct tm * tmp; - - liblist.l_name = BYTE_GET (elib[cnt].l_name); - atime = BYTE_GET (elib[cnt].l_time_stamp); - liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum); - liblist.l_version = BYTE_GET (elib[cnt].l_version); - liblist.l_flags = BYTE_GET (elib[cnt].l_flags); - - tmp = gmtime (&atime); - snprintf (timebuf, sizeof (timebuf), - "%04u-%02u-%02uT%02u:%02u:%02u", - tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - - printf ("%3lu: ", (unsigned long) cnt); - if (VALID_DYNAMIC_NAME (liblist.l_name)) - print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name)); - else - printf (_(""), liblist.l_name); - printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum, - liblist.l_version); - - if (liblist.l_flags == 0) - puts (_(" NONE")); - else - { - static const struct - { - const char * name; - int bit; - } - l_flags_vals[] = - { - { " EXACT_MATCH", LL_EXACT_MATCH }, - { " IGNORE_INT_VER", LL_IGNORE_INT_VER }, - { " REQUIRE_MINOR", LL_REQUIRE_MINOR }, - { " EXPORTS", LL_EXPORTS }, - { " DELAY_LOAD", LL_DELAY_LOAD }, - { " DELTA", LL_DELTA } - }; - int flags = liblist.l_flags; - size_t fcnt; - - for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt) - if ((flags & l_flags_vals[fcnt].bit) != 0) - { - fputs (l_flags_vals[fcnt].name, stdout); - flags ^= l_flags_vals[fcnt].bit; - } - if (flags != 0) - printf (" %#x", (unsigned int) flags); - - puts (""); - } - } - - free (elib); - } - } - - if (options_offset != 0) - { - Elf_External_Options * eopt; - Elf_Internal_Shdr * sect = section_headers; - Elf_Internal_Options * iopt; - Elf_Internal_Options * option; - size_t offset; - int cnt; - - /* Find the section header so that we get the size. */ - while (sect->sh_type != SHT_MIPS_OPTIONS) - ++sect; - - eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1, - sect->sh_size, _("options")); - if (eopt) - { - iopt = (Elf_Internal_Options *) - cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt)); - if (iopt == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - offset = cnt = 0; - option = iopt; - - while (offset < sect->sh_size) - { - Elf_External_Options * eoption; - - eoption = (Elf_External_Options *) ((char *) eopt + offset); - - option->kind = BYTE_GET (eoption->kind); - option->size = BYTE_GET (eoption->size); - option->section = BYTE_GET (eoption->section); - option->info = BYTE_GET (eoption->info); - - offset += option->size; - - ++option; - ++cnt; - } - - printf (_("\nSection '%s' contains %d entries:\n"), - SECTION_NAME (sect), cnt); - - option = iopt; - - while (cnt-- > 0) - { - size_t len; - - switch (option->kind) - { - case ODK_NULL: - /* This shouldn't happen. */ - printf (" NULL %d %lx", option->section, option->info); - break; - case ODK_REGINFO: - printf (" REGINFO "); - if (elf_header.e_machine == EM_MIPS) - { - /* 32bit form. */ - Elf32_External_RegInfo * ereg; - Elf32_RegInfo reginfo; - - ereg = (Elf32_External_RegInfo *) (option + 1); - reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask); - reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]); - reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]); - reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]); - reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]); - reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value); - - printf ("GPR %08lx GP 0x%lx\n", - reginfo.ri_gprmask, - (unsigned long) reginfo.ri_gp_value); - printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n", - reginfo.ri_cprmask[0], reginfo.ri_cprmask[1], - reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]); - } - else - { - /* 64 bit form. */ - Elf64_External_RegInfo * ereg; - Elf64_Internal_RegInfo reginfo; - - ereg = (Elf64_External_RegInfo *) (option + 1); - reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask); - reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]); - reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]); - reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]); - reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]); - reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value); - - printf ("GPR %08lx GP 0x", - reginfo.ri_gprmask); - printf_vma (reginfo.ri_gp_value); - printf ("\n"); - - printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n", - reginfo.ri_cprmask[0], reginfo.ri_cprmask[1], - reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]); - } - ++option; - continue; - case ODK_EXCEPTIONS: - fputs (" EXCEPTIONS fpe_min(", stdout); - process_mips_fpe_exception (option->info & OEX_FPU_MIN); - fputs (") fpe_max(", stdout); - process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8); - fputs (")", stdout); - - if (option->info & OEX_PAGE0) - fputs (" PAGE0", stdout); - if (option->info & OEX_SMM) - fputs (" SMM", stdout); - if (option->info & OEX_FPDBUG) - fputs (" FPDBUG", stdout); - if (option->info & OEX_DISMISS) - fputs (" DISMISS", stdout); - break; - case ODK_PAD: - fputs (" PAD ", stdout); - if (option->info & OPAD_PREFIX) - fputs (" PREFIX", stdout); - if (option->info & OPAD_POSTFIX) - fputs (" POSTFIX", stdout); - if (option->info & OPAD_SYMBOL) - fputs (" SYMBOL", stdout); - break; - case ODK_HWPATCH: - fputs (" HWPATCH ", stdout); - if (option->info & OHW_R4KEOP) - fputs (" R4KEOP", stdout); - if (option->info & OHW_R8KPFETCH) - fputs (" R8KPFETCH", stdout); - if (option->info & OHW_R5KEOP) - fputs (" R5KEOP", stdout); - if (option->info & OHW_R5KCVTL) - fputs (" R5KCVTL", stdout); - break; - case ODK_FILL: - fputs (" FILL ", stdout); - /* XXX Print content of info word? */ - break; - case ODK_TAGS: - fputs (" TAGS ", stdout); - /* XXX Print content of info word? */ - break; - case ODK_HWAND: - fputs (" HWAND ", stdout); - if (option->info & OHWA0_R4KEOP_CHECKED) - fputs (" R4KEOP_CHECKED", stdout); - if (option->info & OHWA0_R4KEOP_CLEAN) - fputs (" R4KEOP_CLEAN", stdout); - break; - case ODK_HWOR: - fputs (" HWOR ", stdout); - if (option->info & OHWA0_R4KEOP_CHECKED) - fputs (" R4KEOP_CHECKED", stdout); - if (option->info & OHWA0_R4KEOP_CLEAN) - fputs (" R4KEOP_CLEAN", stdout); - break; - case ODK_GP_GROUP: - printf (" GP_GROUP %#06lx self-contained %#06lx", - option->info & OGP_GROUP, - (option->info & OGP_SELF) >> 16); - break; - case ODK_IDENT: - printf (" IDENT %#06lx self-contained %#06lx", - option->info & OGP_GROUP, - (option->info & OGP_SELF) >> 16); - break; - default: - /* This shouldn't happen. */ - printf (" %3d ??? %d %lx", - option->kind, option->section, option->info); - break; - } - - len = sizeof (* eopt); - while (len < option->size) - if (((char *) option)[len] >= ' ' - && ((char *) option)[len] < 0x7f) - printf ("%c", ((char *) option)[len++]); - else - printf ("\\%03o", ((char *) option)[len++]); - - fputs ("\n", stdout); - ++option; - } - - free (eopt); - } - } - - if (conflicts_offset != 0 && conflictsno != 0) - { - Elf32_Conflict * iconf; - size_t cnt; - - if (dynamic_symbols == NULL) - { - error (_("conflict list found without a dynamic symbol table\n")); - return 0; - } - - iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf)); - if (iconf == NULL) - { - error (_("Out of memory\n")); - return 0; - } - - if (is_32bit_elf) - { - Elf32_External_Conflict * econf32; - - econf32 = (Elf32_External_Conflict *) - get_data (NULL, file, conflicts_offset, conflictsno, - sizeof (* econf32), _("conflict")); - if (!econf32) - return 0; - - for (cnt = 0; cnt < conflictsno; ++cnt) - iconf[cnt] = BYTE_GET (econf32[cnt]); - - free (econf32); - } - else - { - Elf64_External_Conflict * econf64; - - econf64 = (Elf64_External_Conflict *) - get_data (NULL, file, conflicts_offset, conflictsno, - sizeof (* econf64), _("conflict")); - if (!econf64) - return 0; - - for (cnt = 0; cnt < conflictsno; ++cnt) - iconf[cnt] = BYTE_GET (econf64[cnt]); - - free (econf64); - } - - printf (_("\nSection '.conflict' contains %lu entries:\n"), - (unsigned long) conflictsno); - puts (_(" Num: Index Value Name")); - - for (cnt = 0; cnt < conflictsno; ++cnt) - { - Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]]; - - printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]); - print_vma (psym->st_value, FULL_HEX); - putchar (' '); - if (VALID_DYNAMIC_NAME (psym->st_name)) - print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); - else - printf (_(""), psym->st_name); - putchar ('\n'); - } - - free (iconf); - } - - if (pltgot != 0 && local_gotno != 0) - { - bfd_vma ent, local_end, global_end; - size_t i, offset; - unsigned char * data; - int addr_size; - - ent = pltgot; - addr_size = (is_32bit_elf ? 4 : 8); - local_end = pltgot + local_gotno * addr_size; - global_end = local_end + (symtabno - gotsym) * addr_size; - - offset = offset_from_vma (file, pltgot, global_end - pltgot); - data = (unsigned char *) get_data (NULL, file, offset, - global_end - pltgot, 1, _("GOT")); - if (data == NULL) - return 0; - - printf (_("\nPrimary GOT:\n")); - printf (_(" Canonical gp value: ")); - print_vma (pltgot + 0x7ff0, LONG_HEX); - printf ("\n\n"); - - printf (_(" Reserved entries:\n")); - printf (_(" %*s %10s %*s Purpose\n"), - addr_size * 2, _("Address"), _("Access"), - addr_size * 2, _("Initial")); - ent = print_mips_got_entry (data, pltgot, ent); - printf (_(" Lazy resolver\n")); - if (data - && (byte_get (data + ent - pltgot, addr_size) - >> (addr_size * 8 - 1)) != 0) - { - ent = print_mips_got_entry (data, pltgot, ent); - printf (_(" Module pointer (GNU extension)\n")); - } - printf ("\n"); - - if (ent < local_end) - { - printf (_(" Local entries:\n")); - printf (" %*s %10s %*s\n", - addr_size * 2, _("Address"), _("Access"), - addr_size * 2, _("Initial")); - while (ent < local_end) - { - ent = print_mips_got_entry (data, pltgot, ent); - printf ("\n"); - } - printf ("\n"); - } - - if (gotsym < symtabno) - { - int sym_width; - - printf (_(" Global entries:\n")); - printf (" %*s %10s %*s %*s %-7s %3s %s\n", - addr_size * 2, _("Address"), _("Access"), - addr_size * 2, _("Initial"), - addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name")); - sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1; - for (i = gotsym; i < symtabno; i++) - { - Elf_Internal_Sym * psym; - - psym = dynamic_symbols + i; - ent = print_mips_got_entry (data, pltgot, ent); - printf (" "); - print_vma (psym->st_value, LONG_HEX); - printf (" %-7s %3s ", - get_symbol_type (ELF_ST_TYPE (psym->st_info)), - get_symbol_index_type (psym->st_shndx)); - if (VALID_DYNAMIC_NAME (psym->st_name)) - print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name)); - else - printf (_(""), psym->st_name); - printf ("\n"); - } - printf ("\n"); - } - - if (data) - free (data); - } - - if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0) - { - bfd_vma ent, end; - size_t offset, rel_offset; - unsigned long count, i; - unsigned char * data; - int addr_size, sym_width; - Elf_Internal_Rela * rels; - - rel_offset = offset_from_vma (file, jmprel, pltrelsz); - if (pltrel == DT_RELA) - { - if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count)) - return 0; - } - else - { - if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count)) - return 0; - } - - ent = mips_pltgot; - addr_size = (is_32bit_elf ? 4 : 8); - end = mips_pltgot + (2 + count) * addr_size; - - offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot); - data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot, - 1, _("PLT GOT")); - if (data == NULL) - return 0; - - printf (_("\nPLT GOT:\n\n")); - printf (_(" Reserved entries:\n")); - printf (_(" %*s %*s Purpose\n"), - addr_size * 2, _("Address"), addr_size * 2, _("Initial")); - ent = print_mips_pltgot_entry (data, mips_pltgot, ent); - printf (_(" PLT lazy resolver\n")); - ent = print_mips_pltgot_entry (data, mips_pltgot, ent); - printf (_(" Module pointer\n")); - printf ("\n"); - - printf (_(" Entries:\n")); - printf (" %*s %*s %*s %-7s %3s %s\n", - addr_size * 2, _("Address"), - addr_size * 2, _("Initial"), - addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name")); - sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1; - for (i = 0; i < count; i++) - { - Elf_Internal_Sym * psym; - - psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info); - ent = print_mips_pltgot_entry (data, mips_pltgot, ent); - printf (" "); - print_vma (psym->st_value, LONG_HEX); - printf (" %-7s %3s ", - get_symbol_type (ELF_ST_TYPE (psym->st_info)), - get_symbol_index_type (psym->st_shndx)); - if (VALID_DYNAMIC_NAME (psym->st_name)) - print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name)); - else - printf (_(""), psym->st_name); - printf ("\n"); - } - printf ("\n"); - - if (data) - free (data); - free (rels); - } - - return 1; -} - -static int -process_gnu_liblist (FILE * file) -{ - Elf_Internal_Shdr * section; - Elf_Internal_Shdr * string_sec; - Elf32_External_Lib * elib; - char * strtab; - size_t strtab_size; - size_t cnt; - unsigned i; - - if (! do_arch) - return 0; - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - { - switch (section->sh_type) - { - case SHT_GNU_LIBLIST: - if (section->sh_link >= elf_header.e_shnum) - break; - - elib = (Elf32_External_Lib *) - get_data (NULL, file, section->sh_offset, 1, section->sh_size, - _("liblist")); - - if (elib == NULL) - break; - string_sec = section_headers + section->sh_link; - - strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1, - string_sec->sh_size, - _("liblist string table")); - if (strtab == NULL - || section->sh_entsize != sizeof (Elf32_External_Lib)) - { - free (elib); - free (strtab); - break; - } - strtab_size = string_sec->sh_size; - - printf (_("\nLibrary list section '%s' contains %lu entries:\n"), - SECTION_NAME (section), - (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib))); - - puts (_(" Library Time Stamp Checksum Version Flags")); - - for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib); - ++cnt) - { - Elf32_Lib liblist; - time_t atime; - char timebuf[20]; - struct tm * tmp; - - liblist.l_name = BYTE_GET (elib[cnt].l_name); - atime = BYTE_GET (elib[cnt].l_time_stamp); - liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum); - liblist.l_version = BYTE_GET (elib[cnt].l_version); - liblist.l_flags = BYTE_GET (elib[cnt].l_flags); - - tmp = gmtime (&atime); - snprintf (timebuf, sizeof (timebuf), - "%04u-%02u-%02uT%02u:%02u:%02u", - tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); - - printf ("%3lu: ", (unsigned long) cnt); - if (do_wide) - printf ("%-20s", liblist.l_name < strtab_size - ? strtab + liblist.l_name : _("")); - else - printf ("%-20.20s", liblist.l_name < strtab_size - ? strtab + liblist.l_name : _("")); - printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum, - liblist.l_version, liblist.l_flags); - } - - free (elib); - free (strtab); - } - } - - return 1; -} - -static const char * -get_note_type (unsigned e_type) -{ - static char buff[64]; - - if (elf_header.e_type == ET_CORE) - switch (e_type) - { - case NT_AUXV: - return _("NT_AUXV (auxiliary vector)"); - case NT_PRSTATUS: - return _("NT_PRSTATUS (prstatus structure)"); - case NT_FPREGSET: - return _("NT_FPREGSET (floating point registers)"); - case NT_PRPSINFO: - return _("NT_PRPSINFO (prpsinfo structure)"); - case NT_TASKSTRUCT: - return _("NT_TASKSTRUCT (task structure)"); - case NT_PRXFPREG: - return _("NT_PRXFPREG (user_xfpregs structure)"); - case NT_PPC_VMX: - return _("NT_PPC_VMX (ppc Altivec registers)"); - case NT_PPC_VSX: - return _("NT_PPC_VSX (ppc VSX registers)"); - case NT_X86_XSTATE: - return _("NT_X86_XSTATE (x86 XSAVE extended state)"); - case NT_S390_HIGH_GPRS: - return _("NT_S390_HIGH_GPRS (s390 upper register halves)"); - case NT_S390_TIMER: - return _("NT_S390_TIMER (s390 timer register)"); - case NT_S390_TODCMP: - return _("NT_S390_TODCMP (s390 TOD comparator register)"); - case NT_S390_TODPREG: - return _("NT_S390_TODPREG (s390 TOD programmable register)"); - case NT_S390_CTRS: - return _("NT_S390_CTRS (s390 control registers)"); - case NT_S390_PREFIX: - return _("NT_S390_PREFIX (s390 prefix register)"); - case NT_ARM_VFP: - return _("NT_ARM_VFP (arm VFP registers)"); - case NT_PSTATUS: - return _("NT_PSTATUS (pstatus structure)"); - case NT_FPREGS: - return _("NT_FPREGS (floating point registers)"); - case NT_PSINFO: - return _("NT_PSINFO (psinfo structure)"); - case NT_LWPSTATUS: - return _("NT_LWPSTATUS (lwpstatus_t structure)"); - case NT_LWPSINFO: - return _("NT_LWPSINFO (lwpsinfo_t structure)"); - case NT_WIN32PSTATUS: - return _("NT_WIN32PSTATUS (win32_pstatus structure)"); - default: - break; - } - else - switch (e_type) - { - case NT_VERSION: - return _("NT_VERSION (version)"); - case NT_ARCH: - return _("NT_ARCH (architecture)"); - default: - break; - } - - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; -} - -static const char * -get_gnu_elf_note_type (unsigned e_type) -{ - static char buff[64]; - - switch (e_type) - { - case NT_GNU_ABI_TAG: - return _("NT_GNU_ABI_TAG (ABI version tag)"); - case NT_GNU_HWCAP: - return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)"); - case NT_GNU_BUILD_ID: - return _("NT_GNU_BUILD_ID (unique build ID bitstring)"); - case NT_GNU_GOLD_VERSION: - return _("NT_GNU_GOLD_VERSION (gold version)"); - default: - break; - } - - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; -} - -static int -print_gnu_note (Elf_Internal_Note *pnote) -{ - switch (pnote->type) - { - case NT_GNU_BUILD_ID: - { - unsigned long i; - - printf (_(" Build ID: ")); - for (i = 0; i < pnote->descsz; ++i) - printf ("%02x", pnote->descdata[i] & 0xff); - printf (_("\n")); - } - break; - - case NT_GNU_ABI_TAG: - { - unsigned long os, major, minor, subminor; - const char *osname; - - os = byte_get ((unsigned char *) pnote->descdata, 4); - major = byte_get ((unsigned char *) pnote->descdata + 4, 4); - minor = byte_get ((unsigned char *) pnote->descdata + 8, 4); - subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4); - - switch (os) - { - case GNU_ABI_TAG_LINUX: - osname = "Linux"; - break; - case GNU_ABI_TAG_HURD: - osname = "Hurd"; - break; - case GNU_ABI_TAG_SOLARIS: - osname = "Solaris"; - break; - case GNU_ABI_TAG_FREEBSD: - osname = "FreeBSD"; - break; - case GNU_ABI_TAG_NETBSD: - osname = "NetBSD"; - break; - default: - osname = "Unknown"; - break; - } - - printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname, - major, minor, subminor); - } - break; - } - - return 1; -} - -static const char * -get_netbsd_elfcore_note_type (unsigned e_type) -{ - static char buff[64]; - - if (e_type == NT_NETBSDCORE_PROCINFO) - { - /* NetBSD core "procinfo" structure. */ - return _("NetBSD procinfo structure"); - } - - /* As of Jan 2002 there are no other machine-independent notes - defined for NetBSD core files. If the note type is less - than the start of the machine-dependent note types, we don't - understand it. */ - - if (e_type < NT_NETBSDCORE_FIRSTMACH) - { - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; - } - - switch (elf_header.e_machine) - { - /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 - and PT_GETFPREGS == mach+2. */ - - case EM_OLD_ALPHA: - case EM_ALPHA: - case EM_SPARC: - case EM_SPARC32PLUS: - case EM_SPARCV9: - switch (e_type) - { - case NT_NETBSDCORE_FIRSTMACH + 0: - return _("PT_GETREGS (reg structure)"); - case NT_NETBSDCORE_FIRSTMACH + 2: - return _("PT_GETFPREGS (fpreg structure)"); - default: - break; - } - break; - - /* On all other arch's, PT_GETREGS == mach+1 and - PT_GETFPREGS == mach+3. */ - default: - switch (e_type) - { - case NT_NETBSDCORE_FIRSTMACH + 1: - return _("PT_GETREGS (reg structure)"); - case NT_NETBSDCORE_FIRSTMACH + 3: - return _("PT_GETFPREGS (fpreg structure)"); - default: - break; - } - } - - snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"), - e_type - NT_NETBSDCORE_FIRSTMACH); - return buff; -} - -static const char * -get_stapsdt_note_type (unsigned e_type) -{ - static char buff[64]; - - switch (e_type) - { - case NT_STAPSDT: - return _("NT_STAPSDT (SystemTap probe descriptors)"); - - default: - break; - } - - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; -} - -static int -print_stapsdt_note (Elf_Internal_Note *pnote) -{ - int addr_size = is_32bit_elf ? 4 : 8; - char *data = pnote->descdata; - char *data_end = pnote->descdata + pnote->descsz; - bfd_vma pc, base_addr, semaphore; - char *provider, *probe, *arg_fmt; - - pc = byte_get ((unsigned char *) data, addr_size); - data += addr_size; - base_addr = byte_get ((unsigned char *) data, addr_size); - data += addr_size; - semaphore = byte_get ((unsigned char *) data, addr_size); - data += addr_size; - - provider = data; - data += strlen (data) + 1; - probe = data; - data += strlen (data) + 1; - arg_fmt = data; - data += strlen (data) + 1; - - printf (_(" Provider: %s\n"), provider); - printf (_(" Name: %s\n"), probe); - printf (_(" Location: ")); - print_vma (pc, FULL_HEX); - printf (_(", Base: ")); - print_vma (base_addr, FULL_HEX); - printf (_(", Semaphore: ")); - print_vma (semaphore, FULL_HEX); - printf (_("\n")); - printf (_(" Arguments: %s\n"), arg_fmt); - - return data == data_end; -} - -static const char * -get_ia64_vms_note_type (unsigned e_type) -{ - static char buff[64]; - - switch (e_type) - { - case NT_VMS_MHD: - return _("NT_VMS_MHD (module header)"); - case NT_VMS_LNM: - return _("NT_VMS_LNM (language name)"); - case NT_VMS_SRC: - return _("NT_VMS_SRC (source files)"); - case NT_VMS_TITLE: - return _("NT_VMS_TITLE"); - case NT_VMS_EIDC: - return _("NT_VMS_EIDC (consistency check)"); - case NT_VMS_FPMODE: - return _("NT_VMS_FPMODE (FP mode)"); - case NT_VMS_LINKTIME: - return _("NT_VMS_LINKTIME"); - case NT_VMS_IMGNAM: - return _("NT_VMS_IMGNAM (image name)"); - case NT_VMS_IMGID: - return _("NT_VMS_IMGID (image id)"); - case NT_VMS_LINKID: - return _("NT_VMS_LINKID (link id)"); - case NT_VMS_IMGBID: - return _("NT_VMS_IMGBID (build id)"); - case NT_VMS_GSTNAM: - return _("NT_VMS_GSTNAM (sym table name)"); - case NT_VMS_ORIG_DYN: - return _("NT_VMS_ORIG_DYN"); - case NT_VMS_PATCHTIME: - return _("NT_VMS_PATCHTIME"); - default: - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; - } -} - -static int -print_ia64_vms_note (Elf_Internal_Note * pnote) -{ - switch (pnote->type) - { - case NT_VMS_MHD: - if (pnote->descsz > 36) - { - size_t l = strlen (pnote->descdata + 34); - printf (_(" Creation date : %.17s\n"), pnote->descdata); - printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17); - printf (_(" Module name : %s\n"), pnote->descdata + 34); - printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1); - } - else - printf (_(" Invalid size\n")); - break; - case NT_VMS_LNM: - printf (_(" Language: %s\n"), pnote->descdata); - break; -#ifdef BFD64 - case NT_VMS_FPMODE: - printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"), - (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8)); - break; - case NT_VMS_LINKTIME: - printf (_(" Link time: ")); - print_vms_time - ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8)); - printf ("\n"); - break; - case NT_VMS_PATCHTIME: - printf (_(" Patch time: ")); - print_vms_time - ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8)); - printf ("\n"); - break; - case NT_VMS_ORIG_DYN: - printf (_(" Major id: %u, minor id: %u\n"), - (unsigned) byte_get ((unsigned char *)pnote->descdata, 4), - (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4)); - printf (_(" Manip date : ")); - print_vms_time - ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8)); - printf (_("\n" - " Link flags : 0x%016" BFD_VMA_FMT "x\n"), - (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8)); - printf (_(" Header flags: 0x%08x\n"), - (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4)); - printf (_(" Image id : %s\n"), pnote->descdata + 32); - break; -#endif - case NT_VMS_IMGNAM: - printf (_(" Image name: %s\n"), pnote->descdata); - break; - case NT_VMS_GSTNAM: - printf (_(" Global symbol table name: %s\n"), pnote->descdata); - break; - case NT_VMS_IMGID: - printf (_(" Image id: %s\n"), pnote->descdata); - break; - case NT_VMS_LINKID: - printf (_(" Linker id: %s\n"), pnote->descdata); - break; - default: - break; - } - return 1; -} - -/* Note that by the ELF standard, the name field is already null byte - terminated, and namesz includes the terminating null byte. - I.E. the value of namesz for the name "FSF" is 4. - - If the value of namesz is zero, there is no name present. */ -static int -process_note (Elf_Internal_Note * pnote) -{ - const char * name = pnote->namesz ? pnote->namedata : "(NONE)"; - const char * nt; - - if (pnote->namesz == 0) - /* If there is no note name, then use the default set of - note type strings. */ - nt = get_note_type (pnote->type); - - else if (const_strneq (pnote->namedata, "GNU")) - /* GNU-specific object file notes. */ - nt = get_gnu_elf_note_type (pnote->type); - - else if (const_strneq (pnote->namedata, "NetBSD-CORE")) - /* NetBSD-specific core file notes. */ - nt = get_netbsd_elfcore_note_type (pnote->type); - - else if (strneq (pnote->namedata, "SPU/", 4)) - { - /* SPU-specific core file notes. */ - nt = pnote->namedata + 4; - name = "SPU"; - } - - else if (const_strneq (pnote->namedata, "IPF/VMS")) - /* VMS/ia64-specific file notes. */ - nt = get_ia64_vms_note_type (pnote->type); - - else if (const_strneq (pnote->namedata, "stapsdt")) - nt = get_stapsdt_note_type (pnote->type); - - else - /* Don't recognize this note name; just use the default set of - note type strings. */ - nt = get_note_type (pnote->type); - - printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt); - - if (const_strneq (pnote->namedata, "IPF/VMS")) - return print_ia64_vms_note (pnote); - else if (const_strneq (pnote->namedata, "GNU")) - return print_gnu_note (pnote); - else if (const_strneq (pnote->namedata, "stapsdt")) - return print_stapsdt_note (pnote); - else - return 1; -} - - -static int -process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) -{ - Elf_External_Note * pnotes; - Elf_External_Note * external; - int res = 1; - - if (length <= 0) - return 0; - - pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length, - _("notes")); - if (pnotes == NULL) - return 0; - - external = pnotes; - - printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), - (unsigned long) offset, (unsigned long) length); - printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size")); - - while (external < (Elf_External_Note *) ((char *) pnotes + length)) - { - Elf_External_Note * next; - Elf_Internal_Note inote; - char * temp = NULL; - - if (!is_ia64_vms ()) - { - inote.type = BYTE_GET (external->type); - inote.namesz = BYTE_GET (external->namesz); - inote.namedata = external->name; - inote.descsz = BYTE_GET (external->descsz); - inote.descdata = inote.namedata + align_power (inote.namesz, 2); - inote.descpos = offset + (inote.descdata - (char *) pnotes); - - next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2)); - } - else - { - Elf64_External_VMS_Note *vms_external; - - vms_external = (Elf64_External_VMS_Note *)external; - inote.type = BYTE_GET (vms_external->type); - inote.namesz = BYTE_GET (vms_external->namesz); - inote.namedata = vms_external->name; - inote.descsz = BYTE_GET (vms_external->descsz); - inote.descdata = inote.namedata + align_power (inote.namesz, 3); - inote.descpos = offset + (inote.descdata - (char *) pnotes); - - next = (Elf_External_Note *) - (inote.descdata + align_power (inote.descsz, 3)); - } - - if ( ((char *) next > ((char *) pnotes) + length) - || ((char *) next < (char *) pnotes)) - { - warn (_("corrupt note found at offset %lx into core notes\n"), - (unsigned long) ((char *) external - (char *) pnotes)); - warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"), - inote.type, inote.namesz, inote.descsz); - break; - } - - external = next; - - /* Prevent out-of-bounds indexing. */ - if (inote.namedata + inote.namesz >= (char *) pnotes + length - || inote.namedata + inote.namesz < inote.namedata) - { - warn (_("corrupt note found at offset %lx into core notes\n"), - (unsigned long) ((char *) external - (char *) pnotes)); - warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"), - inote.type, inote.namesz, inote.descsz); - break; - } - - /* Verify that name is null terminated. It appears that at least - one version of Linux (RedHat 6.0) generates corefiles that don't - comply with the ELF spec by failing to include the null byte in - namesz. */ - if (inote.namedata[inote.namesz] != '\0') - { - temp = (char *) malloc (inote.namesz + 1); - - if (temp == NULL) - { - error (_("Out of memory\n")); - res = 0; - break; - } - - strncpy (temp, inote.namedata, inote.namesz); - temp[inote.namesz] = 0; - - /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */ - inote.namedata = temp; - } - - res &= process_note (& inote); - - if (temp != NULL) - { - free (temp); - temp = NULL; - } - } - - free (pnotes); - - return res; -} - -static int -process_corefile_note_segments (FILE * file) -{ - Elf_Internal_Phdr * segment; - unsigned int i; - int res = 1; - - if (! get_program_headers (file)) - return 0; - - for (i = 0, segment = program_headers; - i < elf_header.e_phnum; - i++, segment++) - { - if (segment->p_type == PT_NOTE) - res &= process_corefile_note_segment (file, - (bfd_vma) segment->p_offset, - (bfd_vma) segment->p_filesz); - } - - return res; -} - -static int -process_note_sections (FILE * file) -{ - Elf_Internal_Shdr * section; - unsigned long i; - int res = 1; - - for (i = 0, section = section_headers; - i < elf_header.e_shnum; - i++, section++) - if (section->sh_type == SHT_NOTE) - res &= process_corefile_note_segment (file, - (bfd_vma) section->sh_offset, - (bfd_vma) section->sh_size); - - return res; -} - -static int -process_notes (FILE * file) -{ - /* If we have not been asked to display the notes then do nothing. */ - if (! do_notes) - return 1; - - if (elf_header.e_type != ET_CORE) - return process_note_sections (file); - - /* No program headers means no NOTE segment. */ - if (elf_header.e_phnum > 0) - return process_corefile_note_segments (file); - - printf (_("No note segments present in the core file.\n")); - return 1; -} - -static int -process_arch_specific (FILE * file) -{ - if (! do_arch) - return 1; - - switch (elf_header.e_machine) - { - case EM_ARM: - return process_arm_specific (file); - case EM_MIPS: - case EM_MIPS_RS3_LE: - return process_mips_specific (file); - break; - case EM_PPC: - return process_power_specific (file); - break; - case EM_SPARC: - case EM_SPARC32PLUS: - case EM_SPARCV9: - return process_sparc_specific (file); - break; - case EM_TI_C6000: - return process_tic6x_specific (file); - break; - default: - break; - } - return 1; -} - -static int -get_file_header (FILE * file) -{ - /* Read in the identity array. */ - if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1) - return 0; - - /* Determine how to read the rest of the header. */ - switch (elf_header.e_ident[EI_DATA]) - { - default: /* fall through */ - case ELFDATANONE: /* fall through */ - case ELFDATA2LSB: - byte_get = byte_get_little_endian; - byte_put = byte_put_little_endian; - break; - case ELFDATA2MSB: - byte_get = byte_get_big_endian; - byte_put = byte_put_big_endian; - break; - } - - /* For now we only support 32 bit and 64 bit ELF files. */ - is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64); - - /* Read in the rest of the header. */ - if (is_32bit_elf) - { - Elf32_External_Ehdr ehdr32; - - if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1) - return 0; - - elf_header.e_type = BYTE_GET (ehdr32.e_type); - elf_header.e_machine = BYTE_GET (ehdr32.e_machine); - elf_header.e_version = BYTE_GET (ehdr32.e_version); - elf_header.e_entry = BYTE_GET (ehdr32.e_entry); - elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff); - elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff); - elf_header.e_flags = BYTE_GET (ehdr32.e_flags); - elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize); - elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize); - elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum); - elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize); - elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum); - elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx); - } - else - { - Elf64_External_Ehdr ehdr64; - - /* If we have been compiled with sizeof (bfd_vma) == 4, then - we will not be able to cope with the 64bit data found in - 64 ELF files. Detect this now and abort before we start - overwriting things. */ - if (sizeof (bfd_vma) < 8) - { - error (_("This instance of readelf has been built without support for a\n\ -64 bit data type and so it cannot read 64 bit ELF files.\n")); - return 0; - } - - if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1) - return 0; - - elf_header.e_type = BYTE_GET (ehdr64.e_type); - elf_header.e_machine = BYTE_GET (ehdr64.e_machine); - elf_header.e_version = BYTE_GET (ehdr64.e_version); - elf_header.e_entry = BYTE_GET (ehdr64.e_entry); - elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff); - elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff); - elf_header.e_flags = BYTE_GET (ehdr64.e_flags); - elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize); - elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize); - elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum); - elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize); - elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum); - elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx); - } - - if (elf_header.e_shoff) - { - /* There may be some extensions in the first section header. Don't - bomb if we can't read it. */ - if (is_32bit_elf) - get_32bit_section_headers (file, 1); - else - get_64bit_section_headers (file, 1); - } - - return 1; -} - -/* Process one ELF object file according to the command line options. - This file may actually be stored in an archive. The file is - positioned at the start of the ELF object. */ - -static int -process_object (char * file_name, FILE * file) -{ - unsigned int i; - - if (! get_file_header (file)) - { - error (_("%s: Failed to read file header\n"), file_name); - return 1; - } - - /* Initialise per file variables. */ - for (i = ARRAY_SIZE (version_info); i--;) - version_info[i] = 0; - - for (i = ARRAY_SIZE (dynamic_info); i--;) - dynamic_info[i] = 0; - dynamic_info_DT_GNU_HASH = 0; - - /* Process the file. */ - if (show_name) - printf (_("\nFile: %s\n"), file_name); - - /* Initialise the dump_sects array from the cmdline_dump_sects array. - Note we do this even if cmdline_dump_sects is empty because we - must make sure that the dump_sets array is zeroed out before each - object file is processed. */ - if (num_dump_sects > num_cmdline_dump_sects) - memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects)); - - if (num_cmdline_dump_sects > 0) - { - if (num_dump_sects == 0) - /* A sneaky way of allocating the dump_sects array. */ - request_dump_bynumber (num_cmdline_dump_sects, 0); - - assert (num_dump_sects >= num_cmdline_dump_sects); - memcpy (dump_sects, cmdline_dump_sects, - num_cmdline_dump_sects * sizeof (* dump_sects)); - } - - if (! process_file_header ()) - return 1; - - if (! process_section_headers (file)) - { - /* Without loaded section headers we cannot process lots of - things. */ - do_unwind = do_version = do_dump = do_arch = 0; - - if (! do_using_dynamic) - do_syms = do_dyn_syms = do_reloc = 0; - } - - if (! process_section_groups (file)) - { - /* Without loaded section groups we cannot process unwind. */ - do_unwind = 0; - } - - if (process_program_headers (file)) - process_dynamic_section (file); - - process_relocs (file); - - process_unwind (file); - - process_symbol_table (file); - - process_syminfo (file); - - process_version_sections (file); - - process_section_contents (file); - - process_notes (file); - - process_gnu_liblist (file); - - process_arch_specific (file); - - if (program_headers) - { - free (program_headers); - program_headers = NULL; - } - - if (section_headers) - { - free (section_headers); - section_headers = NULL; - } - - if (string_table) - { - free (string_table); - string_table = NULL; - string_table_length = 0; - } - - if (dynamic_strings) - { - free (dynamic_strings); - dynamic_strings = NULL; - dynamic_strings_length = 0; - } - - if (dynamic_symbols) - { - free (dynamic_symbols); - dynamic_symbols = NULL; - num_dynamic_syms = 0; - } - - if (dynamic_syminfo) - { - free (dynamic_syminfo); - dynamic_syminfo = NULL; - } - - if (dynamic_section) - { - free (dynamic_section); - dynamic_section = NULL; - } - - if (section_headers_groups) - { - free (section_headers_groups); - section_headers_groups = NULL; - } - - if (section_groups) - { - struct group_list * g; - struct group_list * next; - - for (i = 0; i < group_count; i++) - { - for (g = section_groups [i].root; g != NULL; g = next) - { - next = g->next; - free (g); - } - } - - free (section_groups); - section_groups = NULL; - } - - free_debug_memory (); - - return 0; -} - -/* Process an ELF archive. - On entry the file is positioned just after the ARMAG string. */ - -static int -process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) -{ - struct archive_info arch; - struct archive_info nested_arch; - size_t got; - int ret; - - show_name = 1; - - /* The ARCH structure is used to hold information about this archive. */ - arch.file_name = NULL; - arch.file = NULL; - arch.index_array = NULL; - arch.sym_table = NULL; - arch.longnames = NULL; - - /* The NESTED_ARCH structure is used as a single-item cache of information - about a nested archive (when members of a thin archive reside within - another regular archive file). */ - nested_arch.file_name = NULL; - nested_arch.file = NULL; - nested_arch.index_array = NULL; - nested_arch.sym_table = NULL; - nested_arch.longnames = NULL; - - if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0) - { - ret = 1; - goto out; - } - - if (do_archive_index) - { - if (arch.sym_table == NULL) - error (_("%s: unable to dump the index as none was found\n"), file_name); - else - { - unsigned int i, l; - unsigned long current_pos; - - printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"), - file_name, arch.index_num, arch.sym_size); - current_pos = ftell (file); - - for (i = l = 0; i < arch.index_num; i++) - { - if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1]))) - { - char * member_name; - - member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch); - - if (member_name != NULL) - { - char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name); - - if (qualified_name != NULL) - { - printf (_("Binary %s contains:\n"), qualified_name); - free (qualified_name); - } - } - } - - if (l >= arch.sym_size) - { - error (_("%s: end of the symbol table reached before the end of the index\n"), - file_name); - break; - } - printf ("\t%s\n", arch.sym_table + l); - l += strlen (arch.sym_table + l) + 1; - } - - if (l & 01) - ++l; - if (l < arch.sym_size) - error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"), - file_name); - - if (fseek (file, current_pos, SEEK_SET) != 0) - { - error (_("%s: failed to seek back to start of object files in the archive\n"), file_name); - ret = 1; - goto out; - } - } - - if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections - && !do_segments && !do_header && !do_dump && !do_version - && !do_histogram && !do_debugging && !do_arch && !do_notes - && !do_section_groups && !do_dyn_syms) - { - ret = 0; /* Archive index only. */ - goto out; - } - } - - ret = 0; - - while (1) - { - char * name; - size_t namelen; - char * qualified_name; - - /* Read the next archive header. */ - if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0) - { - error (_("%s: failed to seek to next archive header\n"), file_name); - return 1; - } - got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file); - if (got != sizeof arch.arhdr) - { - if (got == 0) - break; - error (_("%s: failed to read archive header\n"), file_name); - ret = 1; - break; - } - if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0) - { - error (_("%s: did not find a valid archive header\n"), arch.file_name); - ret = 1; - break; - } - - arch.next_arhdr_offset += sizeof arch.arhdr; - - archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10); - if (archive_file_size & 01) - ++archive_file_size; - - name = get_archive_member_name (&arch, &nested_arch); - if (name == NULL) - { - error (_("%s: bad archive file name\n"), file_name); - ret = 1; - break; - } - namelen = strlen (name); - - qualified_name = make_qualified_name (&arch, &nested_arch, name); - if (qualified_name == NULL) - { - error (_("%s: bad archive file name\n"), file_name); - ret = 1; - break; - } - - if (is_thin_archive && arch.nested_member_origin == 0) - { - /* This is a proxy for an external member of a thin archive. */ - FILE * member_file; - char * member_file_name = adjust_relative_path (file_name, name, namelen); - if (member_file_name == NULL) - { - ret = 1; - break; - } - - member_file = fopen (member_file_name, "rb"); - if (member_file == NULL) - { - error (_("Input file '%s' is not readable.\n"), member_file_name); - free (member_file_name); - ret = 1; - break; - } - - archive_file_offset = arch.nested_member_origin; - - ret |= process_object (qualified_name, member_file); - - fclose (member_file); - free (member_file_name); - } - else if (is_thin_archive) - { - /* This is a proxy for a member of a nested archive. */ - archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr; - - /* The nested archive file will have been opened and setup by - get_archive_member_name. */ - if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0) - { - error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name); - ret = 1; - break; - } - - ret |= process_object (qualified_name, nested_arch.file); - } - else - { - archive_file_offset = arch.next_arhdr_offset; - arch.next_arhdr_offset += archive_file_size; - - ret |= process_object (qualified_name, file); - } - - if (dump_sects != NULL) - { - free (dump_sects); - dump_sects = NULL; - num_dump_sects = 0; - } - - free (qualified_name); - } - - out: - if (nested_arch.file != NULL) - fclose (nested_arch.file); - release_archive (&nested_arch); - release_archive (&arch); - - return ret; -} - -static int -process_file (char * file_name) -{ - FILE * file; - struct stat statbuf; - char armag[SARMAG]; - int ret; - - if (stat (file_name, &statbuf) < 0) - { - if (errno == ENOENT) - error (_("'%s': No such file\n"), file_name); - else - error (_("Could not locate '%s'. System error message: %s\n"), - file_name, strerror (errno)); - return 1; - } - - if (! S_ISREG (statbuf.st_mode)) - { - error (_("'%s' is not an ordinary file\n"), file_name); - return 1; - } - - file = fopen (file_name, "rb"); - if (file == NULL) - { - error (_("Input file '%s' is not readable.\n"), file_name); - return 1; - } - - if (fread (armag, SARMAG, 1, file) != 1) - { - error (_("%s: Failed to read file's magic number\n"), file_name); - fclose (file); - return 1; - } - - if (memcmp (armag, ARMAG, SARMAG) == 0) - ret = process_archive (file_name, file, FALSE); - else if (memcmp (armag, ARMAGT, SARMAG) == 0) - ret = process_archive (file_name, file, TRUE); - else - { - if (do_archive_index) - error (_("File %s is not an archive so its index cannot be displayed.\n"), - file_name); - - rewind (file); - archive_file_size = archive_file_offset = 0; - ret = process_object (file_name, file); - } - - fclose (file); - - return ret; -} - -#ifdef SUPPORT_DISASSEMBLY -/* Needed by the i386 disassembler. For extra credit, someone could - fix this so that we insert symbolic addresses here, esp for GOT/PLT - symbols. */ - -void -print_address (unsigned int addr, FILE * outfile) -{ - fprintf (outfile,"0x%8.8x", addr); -} - -/* Needed by the i386 disassembler. */ -void -db_task_printsym (unsigned int addr) -{ - print_address (addr, stderr); -} -#endif - -int -main (int argc, char ** argv) -{ - int err; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - expandargv (&argc, &argv); - - parse_args (argc, argv); - - if (num_dump_sects > 0) - { - /* Make a copy of the dump_sects array. */ - cmdline_dump_sects = (dump_type *) - malloc (num_dump_sects * sizeof (* dump_sects)); - if (cmdline_dump_sects == NULL) - error (_("Out of memory allocating dump request table.\n")); - else - { - memcpy (cmdline_dump_sects, dump_sects, - num_dump_sects * sizeof (* dump_sects)); - num_cmdline_dump_sects = num_dump_sects; - } - } - - if (optind < (argc - 1)) - show_name = 1; - - err = 0; - while (optind < argc) - err |= process_file (argv[optind++]); - - if (dump_sects != NULL) - free (dump_sects); - if (cmdline_dump_sects != NULL) - free (cmdline_dump_sects); - - return err; -} diff --git a/contrib/binutils-2.22/binutils/rename.c b/contrib/binutils-2.22/binutils/rename.c deleted file mode 100644 index c07150c955..0000000000 --- a/contrib/binutils-2.22/binutils/rename.c +++ /dev/null @@ -1,214 +0,0 @@ -/* rename.c -- rename a file, preserving symlinks. - Copyright 1999, 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bucomm.h" - -#include - -#ifdef HAVE_GOOD_UTIME_H -#include -#else /* ! HAVE_GOOD_UTIME_H */ -#ifdef HAVE_UTIMES -#include -#endif /* HAVE_UTIMES */ -#endif /* ! HAVE_GOOD_UTIME_H */ - -#if ! defined (_WIN32) || defined (__CYGWIN32__) -static int simple_copy (const char *, const char *); - -/* The number of bytes to copy at once. */ -#define COPY_BUF 8192 - -/* Copy file FROM to file TO, performing no translations. - Return 0 if ok, -1 if error. */ - -static int -simple_copy (const char *from, const char *to) -{ - int fromfd, tofd, nread; - int saved; - char buf[COPY_BUF]; - - fromfd = open (from, O_RDONLY | O_BINARY); - if (fromfd < 0) - return -1; -#ifdef O_CREAT - tofd = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0777); -#else - tofd = creat (to, 0777); -#endif - if (tofd < 0) - { - saved = errno; - close (fromfd); - errno = saved; - return -1; - } - while ((nread = read (fromfd, buf, sizeof buf)) > 0) - { - if (write (tofd, buf, nread) != nread) - { - saved = errno; - close (fromfd); - close (tofd); - errno = saved; - return -1; - } - } - saved = errno; - close (fromfd); - close (tofd); - if (nread < 0) - { - errno = saved; - return -1; - } - return 0; -} -#endif /* __CYGWIN32__ or not _WIN32 */ - -/* Set the times of the file DESTINATION to be the same as those in - STATBUF. */ - -void -set_times (const char *destination, const struct stat *statbuf) -{ - int result; - - { -#ifdef HAVE_GOOD_UTIME_H - struct utimbuf tb; - - tb.actime = statbuf->st_atime; - tb.modtime = statbuf->st_mtime; - result = utime (destination, &tb); -#else /* ! HAVE_GOOD_UTIME_H */ -#ifndef HAVE_UTIMES - long tb[2]; - - tb[0] = statbuf->st_atime; - tb[1] = statbuf->st_mtime; - result = utime (destination, tb); -#else /* HAVE_UTIMES */ - struct timeval tv[2]; - - tv[0].tv_sec = statbuf->st_atime; - tv[0].tv_usec = 0; - tv[1].tv_sec = statbuf->st_mtime; - tv[1].tv_usec = 0; - result = utimes (destination, tv); -#endif /* HAVE_UTIMES */ -#endif /* ! HAVE_GOOD_UTIME_H */ - } - - if (result != 0) - non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno)); -} - -#ifndef S_ISLNK -#ifdef S_IFLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#else -#define S_ISLNK(m) 0 -#define lstat stat -#endif -#endif - -/* Rename FROM to TO, copying if TO is a link. - Return 0 if ok, -1 if error. */ - -int -smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED) -{ - bfd_boolean exists; - struct stat s; - int ret = 0; - - exists = lstat (to, &s) == 0; - -#if defined (_WIN32) && !defined (__CYGWIN32__) - /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but - fail instead. Also, chown is not present. */ - - if (exists) - remove (to); - - ret = rename (from, to); - if (ret != 0) - { - /* We have to clean up here. */ - non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno)); - unlink (from); - } -#else - /* Use rename only if TO is not a symbolic link and has - only one hard link, and we have permission to write to it. */ - if (! exists - || (!S_ISLNK (s.st_mode) - && S_ISREG (s.st_mode) - && (s.st_mode & S_IWUSR) - && s.st_nlink == 1) - ) - { - ret = rename (from, to); - if (ret == 0) - { - if (exists) - { - /* Try to preserve the permission bits and ownership of - TO. First get the mode right except for the setuid - bit. Then change the ownership. Then fix the setuid - bit. We do the chmod before the chown because if the - chown succeeds, and we are a normal user, we won't be - able to do the chmod afterward. We don't bother to - fix the setuid bit first because that might introduce - a fleeting security problem, and because the chown - will clear the setuid bit anyhow. We only fix the - setuid bit if the chown succeeds, because we don't - want to introduce an unexpected setuid file owned by - the user running objcopy. */ - chmod (to, s.st_mode & 0777); - if (chown (to, s.st_uid, s.st_gid) >= 0) - chmod (to, s.st_mode & 07777); - } - } - else - { - /* We have to clean up here. */ - non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno)); - unlink (from); - } - } - else - { - ret = simple_copy (from, to); - if (ret != 0) - non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno)); - - if (preserve_dates) - set_times (to, &s); - unlink (from); - } -#endif /* _WIN32 && !__CYGWIN32__ */ - - return ret; -} diff --git a/contrib/binutils-2.22/binutils/size.c b/contrib/binutils-2.22/binutils/size.c deleted file mode 100644 index 0937de514e..0000000000 --- a/contrib/binutils-2.22/binutils/size.c +++ /dev/null @@ -1,611 +0,0 @@ -/* size.c -- report size of various sections of an executable file. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -/* Extensions/incompatibilities: - o - BSD output has filenames at the end. - o - BSD output can appear in different radicies. - o - SysV output has less redundant whitespace. Filename comes at end. - o - SysV output doesn't show VMA which is always the same as the PMA. - o - We also handle core files. - o - We also handle archives. - If you write shell scripts which manipulate this info then you may be - out of luck; there's no --compatibility or --pedantic option. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "getopt.h" -#include "bucomm.h" - -#ifndef BSD_DEFAULT -#define BSD_DEFAULT 1 -#endif - -/* Program options. */ - -static enum - { - decimal, octal, hex - } -radix = decimal; - -/* 0 means use AT&T-style output. */ -static int berkeley_format = BSD_DEFAULT; - -static int show_version = 0; -static int show_help = 0; -static int show_totals = 0; -static int show_common = 0; - -static bfd_size_type common_size; -static bfd_size_type total_bsssize; -static bfd_size_type total_datasize; -static bfd_size_type total_textsize; - -/* Program exit status. */ -static int return_code = 0; - -static char *target = NULL; - -/* Forward declarations. */ - -static void display_file (char *); -static void rprint_number (int, bfd_size_type); -static void print_sizes (bfd * file); - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name); - fprintf (stream, _(" Displays the sizes of sections inside binary files\n")); - fprintf (stream, _(" If no input file(s) are specified, a.out is assumed\n")); - fprintf (stream, _(" The options are:\n\ - -A|-B --format={sysv|berkeley} Select output style (default is %s)\n\ - -o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex\n\ - -t --totals Display the total sizes (Berkeley only)\n\ - --common Display total size for *COM* syms\n\ - --target= Set the binary file format\n\ - @ Read options from \n\ - -h --help Display this information\n\ - -v --version Display the program's version\n\ -\n"), -#if BSD_DEFAULT - "berkeley" -#else - "sysv" -#endif -); - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (status); -} - -#define OPTION_FORMAT (200) -#define OPTION_RADIX (OPTION_FORMAT + 1) -#define OPTION_TARGET (OPTION_RADIX + 1) - -static struct option long_options[] = -{ - {"common", no_argument, &show_common, 1}, - {"format", required_argument, 0, OPTION_FORMAT}, - {"radix", required_argument, 0, OPTION_RADIX}, - {"target", required_argument, 0, OPTION_TARGET}, - {"totals", no_argument, &show_totals, 1}, - {"version", no_argument, &show_version, 1}, - {"help", no_argument, &show_help, 1}, - {0, no_argument, 0, 0} -}; - -int main (int, char **); - -int -main (int argc, char **argv) -{ - int temp; - int c; - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = *argv; - xmalloc_set_program_name (program_name); - - expandargv (&argc, &argv); - - bfd_init (); - set_default_bfd_target (); - - while ((c = getopt_long (argc, argv, "ABHhVvdfotx", long_options, - (int *) 0)) != EOF) - switch (c) - { - case OPTION_FORMAT: - switch (*optarg) - { - case 'B': - case 'b': - berkeley_format = 1; - break; - case 'S': - case 's': - berkeley_format = 0; - break; - default: - non_fatal (_("invalid argument to --format: %s"), optarg); - usage (stderr, 1); - } - break; - - case OPTION_TARGET: - target = optarg; - break; - - case OPTION_RADIX: -#ifdef ANSI_LIBRARIES - temp = strtol (optarg, NULL, 10); -#else - temp = atol (optarg); -#endif - switch (temp) - { - case 10: - radix = decimal; - break; - case 8: - radix = octal; - break; - case 16: - radix = hex; - break; - default: - non_fatal (_("Invalid radix: %s\n"), optarg); - usage (stderr, 1); - } - break; - - case 'A': - berkeley_format = 0; - break; - case 'B': - berkeley_format = 1; - break; - case 'v': - case 'V': - show_version = 1; - break; - case 'd': - radix = decimal; - break; - case 'x': - radix = hex; - break; - case 'o': - radix = octal; - break; - case 't': - show_totals = 1; - break; - case 'f': /* FIXME : For sysv68, `-f' means `full format', i.e. - `[fname:] M(.text) + N(.data) + O(.bss) + P(.comment) = Q' - where `fname: ' appears only if there are >= 2 input files, - and M, N, O, P, Q are expressed in decimal by default, - hexa or octal if requested by `-x' or `-o'. - Just to make things interesting, Solaris also accepts -f, - which prints out the size of each allocatable section, the - name of the section, and the total of the section sizes. */ - /* For the moment, accept `-f' silently, and ignore it. */ - break; - case 0: - break; - case 'h': - case 'H': - case '?': - usage (stderr, 1); - } - - if (show_version) - print_version ("size"); - if (show_help) - usage (stdout, 0); - - if (optind == argc) - display_file ("a.out"); - else - for (; optind < argc;) - display_file (argv[optind++]); - - if (show_totals && berkeley_format) - { - bfd_size_type total = total_textsize + total_datasize + total_bsssize; - - rprint_number (7, total_textsize); - putchar('\t'); - rprint_number (7, total_datasize); - putchar('\t'); - rprint_number (7, total_bsssize); - printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"), - (unsigned long) total, (unsigned long) total); - fputs ("(TOTALS)\n", stdout); - } - - return return_code; -} - -/* Total size required for common symbols in ABFD. */ - -static void -calculate_common_size (bfd *abfd) -{ - asymbol **syms = NULL; - long storage, symcount; - - common_size = 0; - if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC | HAS_SYMS)) != HAS_SYMS) - return; - - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - bfd_fatal (bfd_get_filename (abfd)); - if (storage) - syms = (asymbol **) xmalloc (storage); - - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - bfd_fatal (bfd_get_filename (abfd)); - - while (--symcount >= 0) - { - asymbol *sym = syms[symcount]; - - if (bfd_is_com_section (sym->section) - && (sym->flags & BSF_SECTION_SYM) == 0) - common_size += sym->value; - } - free (syms); -} - -/* Display stats on file or archive member ABFD. */ - -static void -display_bfd (bfd *abfd) -{ - char **matching; - - if (bfd_check_format (abfd, bfd_archive)) - /* An archive within an archive. */ - return; - - if (bfd_check_format_matches (abfd, bfd_object, &matching)) - { - print_sizes (abfd); - printf ("\n"); - return; - } - - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - bfd_nonfatal (bfd_get_filename (abfd)); - list_matching_formats (matching); - free (matching); - return_code = 3; - return; - } - - if (bfd_check_format_matches (abfd, bfd_core, &matching)) - { - const char *core_cmd; - - print_sizes (abfd); - fputs (" (core file", stdout); - - core_cmd = bfd_core_file_failing_command (abfd); - if (core_cmd) - printf (" invoked as %s", core_cmd); - - puts (")\n"); - return; - } - - bfd_nonfatal (bfd_get_filename (abfd)); - - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - - return_code = 3; -} - -static void -display_archive (bfd *file) -{ - bfd *arfile = (bfd *) NULL; - bfd *last_arfile = (bfd *) NULL; - - for (;;) - { - bfd_set_error (bfd_error_no_error); - - arfile = bfd_openr_next_archived_file (file, arfile); - if (arfile == NULL) - { - if (bfd_get_error () != bfd_error_no_more_archived_files) - { - bfd_nonfatal (bfd_get_filename (file)); - return_code = 2; - } - break; - } - - display_bfd (arfile); - - if (last_arfile != NULL) - bfd_close (last_arfile); - last_arfile = arfile; - } - - if (last_arfile != NULL) - bfd_close (last_arfile); -} - -static void -display_file (char *filename) -{ - bfd *file; - - if (get_file_size (filename) < 1) - { - return_code = 1; - return; - } - - file = bfd_openr (filename, target); - if (file == NULL) - { - bfd_nonfatal (filename); - return_code = 1; - return; - } - - if (bfd_check_format (file, bfd_archive)) - display_archive (file); - else - display_bfd (file); - - if (!bfd_close (file)) - { - bfd_nonfatal (filename); - return_code = 1; - return; - } -} - -static int -size_number (bfd_size_type num) -{ - char buffer[40]; - - sprintf (buffer, - (radix == decimal ? "%" BFD_VMA_FMT "u" : - ((radix == octal) ? "0%" BFD_VMA_FMT "o" : "0x%" BFD_VMA_FMT "x")), - num); - - return strlen (buffer); -} - -static void -rprint_number (int width, bfd_size_type num) -{ - char buffer[40]; - - sprintf (buffer, - (radix == decimal ? "%" BFD_VMA_FMT "u" : - ((radix == octal) ? "0%" BFD_VMA_FMT "o" : "0x%" BFD_VMA_FMT "x")), - num); - - printf ("%*s", width, buffer); -} - -static bfd_size_type bsssize; -static bfd_size_type datasize; -static bfd_size_type textsize; - -static void -berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, - void *ignore ATTRIBUTE_UNUSED) -{ - flagword flags; - bfd_size_type size; - - flags = bfd_get_section_flags (abfd, sec); - if ((flags & SEC_ALLOC) == 0) - return; - - size = bfd_get_section_size (sec); - if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0) - textsize += size; - else if ((flags & SEC_HAS_CONTENTS) != 0) - datasize += size; - else - bsssize += size; -} - -static void -print_berkeley_format (bfd *abfd) -{ - static int files_seen = 0; - bfd_size_type total; - - bsssize = 0; - datasize = 0; - textsize = 0; - - bfd_map_over_sections (abfd, berkeley_sum, NULL); - - bsssize += common_size; - if (files_seen++ == 0) - puts ((radix == octal) ? " text\t data\t bss\t oct\t hex\tfilename" : - " text\t data\t bss\t dec\t hex\tfilename"); - - total = textsize + datasize + bsssize; - - if (show_totals) - { - total_textsize += textsize; - total_datasize += datasize; - total_bsssize += bsssize; - } - - rprint_number (7, textsize); - putchar ('\t'); - rprint_number (7, datasize); - putchar ('\t'); - rprint_number (7, bsssize); - printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"), - (unsigned long) total, (unsigned long) total); - - fputs (bfd_get_filename (abfd), stdout); - - if (bfd_my_archive (abfd)) - printf (" (ex %s)", bfd_get_filename (bfd_my_archive (abfd))); -} - -/* I REALLY miss lexical functions! */ -bfd_size_type svi_total = 0; -bfd_vma svi_maxvma = 0; -int svi_namelen = 0; -int svi_vmalen = 0; -int svi_sizelen = 0; - -static void -sysv_internal_sizer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec, - void *ignore ATTRIBUTE_UNUSED) -{ - bfd_size_type size = bfd_section_size (file, sec); - - if ( ! bfd_is_abs_section (sec) - && ! bfd_is_com_section (sec) - && ! bfd_is_und_section (sec)) - { - int namelen = strlen (bfd_section_name (file, sec)); - - if (namelen > svi_namelen) - svi_namelen = namelen; - - svi_total += size; - - if (bfd_section_vma (file, sec) > svi_maxvma) - svi_maxvma = bfd_section_vma (file, sec); - } -} - -static void -sysv_one_line (const char *name, bfd_size_type size, bfd_vma vma) -{ - printf ("%-*s ", svi_namelen, name); - rprint_number (svi_sizelen, size); - printf (" "); - rprint_number (svi_vmalen, vma); - printf ("\n"); -} - -static void -sysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec, - void *ignore ATTRIBUTE_UNUSED) -{ - bfd_size_type size = bfd_section_size (file, sec); - - if ( ! bfd_is_abs_section (sec) - && ! bfd_is_com_section (sec) - && ! bfd_is_und_section (sec)) - { - svi_total += size; - - sysv_one_line (bfd_section_name (file, sec), - size, - bfd_section_vma (file, sec)); - } -} - -static void -print_sysv_format (bfd *file) -{ - /* Size all of the columns. */ - svi_total = 0; - svi_maxvma = 0; - svi_namelen = 0; - bfd_map_over_sections (file, sysv_internal_sizer, NULL); - if (show_common) - { - if (svi_namelen < (int) sizeof ("*COM*") - 1) - svi_namelen = sizeof ("*COM*") - 1; - svi_total += common_size; - } - - svi_vmalen = size_number ((bfd_size_type)svi_maxvma); - - if ((size_t) svi_vmalen < sizeof ("addr") - 1) - svi_vmalen = sizeof ("addr")-1; - - svi_sizelen = size_number (svi_total); - if ((size_t) svi_sizelen < sizeof ("size") - 1) - svi_sizelen = sizeof ("size")-1; - - svi_total = 0; - printf ("%s ", bfd_get_filename (file)); - - if (bfd_my_archive (file)) - printf (" (ex %s)", bfd_get_filename (bfd_my_archive (file))); - - printf (":\n%-*s %*s %*s\n", svi_namelen, "section", - svi_sizelen, "size", svi_vmalen, "addr"); - - bfd_map_over_sections (file, sysv_internal_printer, NULL); - if (show_common) - { - svi_total += common_size; - sysv_one_line ("*COM*", common_size, 0); - } - - printf ("%-*s ", svi_namelen, "Total"); - rprint_number (svi_sizelen, svi_total); - printf ("\n\n"); -} - -static void -print_sizes (bfd *file) -{ - if (show_common) - calculate_common_size (file); - if (berkeley_format) - print_berkeley_format (file); - else - print_sysv_format (file); -} diff --git a/contrib/binutils-2.22/binutils/stabs.c b/contrib/binutils-2.22/binutils/stabs.c deleted file mode 100644 index 9534d6616a..0000000000 --- a/contrib/binutils-2.22/binutils/stabs.c +++ /dev/null @@ -1,5431 +0,0 @@ -/* stabs.c -- Parse stabs debugging information - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This file contains code which parses stabs debugging information. - The organization of this code is based on the gdb stabs reading - code. The job it does is somewhat different, because it is not - trying to identify the correct address for anything. */ - -#include "sysdep.h" -#include "bfd.h" -#include "libiberty.h" -#include "safe-ctype.h" -#include "demangle.h" -#include "debug.h" -#include "budbg.h" -#include "filenames.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" - -/* The number of predefined XCOFF types. */ - -#define XCOFF_TYPE_COUNT 34 - -/* This structure is used as a handle so that the stab parsing doesn't - need to use any static variables. */ - -struct stab_handle -{ - /* The BFD. */ - bfd *abfd; - /* TRUE if this is stabs in sections. */ - bfd_boolean sections; - /* The symbol table. */ - asymbol **syms; - /* The number of symbols. */ - long symcount; - /* The accumulated file name string. */ - char *so_string; - /* The value of the last N_SO symbol. */ - bfd_vma so_value; - /* The value of the start of the file, so that we can handle file - relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma file_start_offset; - /* The offset of the start of the function, so that we can handle - function relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma function_start_offset; - /* The version number of gcc which compiled the current compilation - unit, 0 if not compiled by gcc. */ - int gcc_compiled; - /* Whether an N_OPT symbol was seen that was not generated by gcc, - so that we can detect the SunPRO compiler. */ - bfd_boolean n_opt_found; - /* The main file name. */ - char *main_filename; - /* A stack of unfinished N_BINCL files. */ - struct bincl_file *bincl_stack; - /* A list of finished N_BINCL files. */ - struct bincl_file *bincl_list; - /* Whether we are inside a function or not. */ - bfd_boolean within_function; - /* The address of the end of the function, used if we have seen an - N_FUN symbol while in a function. This is -1 if we have not seen - an N_FUN (the normal case). */ - bfd_vma function_end; - /* The depth of block nesting. */ - int block_depth; - /* List of pending variable definitions. */ - struct stab_pending_var *pending; - /* Number of files for which we have types. */ - unsigned int files; - /* Lists of types per file. */ - struct stab_types **file_types; - /* Predefined XCOFF types. */ - debug_type xcoff_types[XCOFF_TYPE_COUNT]; - /* Undefined tags. */ - struct stab_tag *tags; - /* Set by parse_stab_type if it sees a structure defined as a cross - reference to itself. Reset by parse_stab_type otherwise. */ - bfd_boolean self_crossref; -}; - -/* A list of these structures is used to hold pending variable - definitions seen before the N_LBRAC of a block. */ - -struct stab_pending_var -{ - /* Next pending variable definition. */ - struct stab_pending_var *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_var_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* A list of these structures is used to hold the types for a single - file. */ - -struct stab_types -{ - /* Next set of slots for this file. */ - struct stab_types *next; - /* Types indexed by type number. */ -#define STAB_TYPES_SLOTS (16) - debug_type types[STAB_TYPES_SLOTS]; -}; - -/* We keep a list of undefined tags that we encounter, so that we can - fill them in if the tag is later defined. */ - -struct stab_tag -{ - /* Next undefined tag. */ - struct stab_tag *next; - /* Tag name. */ - const char *name; - /* Type kind. */ - enum debug_type_kind kind; - /* Slot to hold real type when we discover it. If we don't, we fill - in an undefined tag type. */ - debug_type slot; - /* Indirect type we have created to point at slot. */ - debug_type type; -}; - -static char *savestring (const char *, int); -static bfd_vma parse_number (const char **, bfd_boolean *); -static void bad_stab (const char *); -static void warn_stab (const char *, const char *); -static bfd_boolean parse_stab_string - (void *, struct stab_handle *, int, int, bfd_vma, const char *); -static debug_type parse_stab_type - (void *, struct stab_handle *, const char *, const char **, debug_type **); -static bfd_boolean parse_stab_type_number (const char **, int *); -static debug_type parse_stab_range_type - (void *, struct stab_handle *, const char *, const char **, const int *); -static debug_type parse_stab_sun_builtin_type (void *, const char **); -static debug_type parse_stab_sun_floating_type (void *, const char **); -static debug_type parse_stab_enum_type (void *, const char **); -static debug_type parse_stab_struct_type - (void *, struct stab_handle *, const char *, const char **, - bfd_boolean, const int *); -static bfd_boolean parse_stab_baseclasses - (void *, struct stab_handle *, const char **, debug_baseclass **); -static bfd_boolean parse_stab_struct_fields - (void *, struct stab_handle *, const char **, debug_field **, bfd_boolean *); -static bfd_boolean parse_stab_cpp_abbrev - (void *, struct stab_handle *, const char **, debug_field *); -static bfd_boolean parse_stab_one_struct_field - (void *, struct stab_handle *, const char **, const char *, - debug_field *, bfd_boolean *); -static bfd_boolean parse_stab_members - (void *, struct stab_handle *, const char *, const char **, const int *, - debug_method **); -static debug_type parse_stab_argtypes - (void *, struct stab_handle *, debug_type, const char *, const char *, - debug_type, const char *, bfd_boolean, bfd_boolean, const char **); -static bfd_boolean parse_stab_tilde_field - (void *, struct stab_handle *, const char **, const int *, debug_type *, - bfd_boolean *); -static debug_type parse_stab_array_type - (void *, struct stab_handle *, const char **, bfd_boolean); -static void push_bincl (struct stab_handle *, const char *, bfd_vma); -static const char *pop_bincl (struct stab_handle *); -static bfd_boolean find_excl (struct stab_handle *, const char *, bfd_vma); -static bfd_boolean stab_record_variable - (void *, struct stab_handle *, const char *, debug_type, - enum debug_var_kind, bfd_vma); -static bfd_boolean stab_emit_pending_vars (void *, struct stab_handle *); -static debug_type *stab_find_slot (struct stab_handle *, const int *); -static debug_type stab_find_type (void *, struct stab_handle *, const int *); -static bfd_boolean stab_record_type - (void *, struct stab_handle *, const int *, debug_type); -static debug_type stab_xcoff_builtin_type - (void *, struct stab_handle *, int); -static debug_type stab_find_tagged_type - (void *, struct stab_handle *, const char *, int, enum debug_type_kind); -static debug_type *stab_demangle_argtypes - (void *, struct stab_handle *, const char *, bfd_boolean *, unsigned int); -static debug_type *stab_demangle_v3_argtypes - (void *, struct stab_handle *, const char *, bfd_boolean *); -static debug_type *stab_demangle_v3_arglist - (void *, struct stab_handle *, struct demangle_component *, bfd_boolean *); -static debug_type stab_demangle_v3_arg - (void *, struct stab_handle *, struct demangle_component *, debug_type, - bfd_boolean *); - -/* Save a string in memory. */ - -static char * -savestring (const char *start, int len) -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number from a string. */ - -static bfd_vma -parse_number (const char **pp, bfd_boolean *poverflow) -{ - unsigned long ul; - const char *orig; - - if (poverflow != NULL) - *poverflow = FALSE; - - orig = *pp; - - errno = 0; - ul = strtoul (*pp, (char **) pp, 0); - if (ul + 1 != 0 || errno == 0) - { - /* If bfd_vma is larger than unsigned long, and the number is - meant to be negative, we have to make sure that we sign - extend properly. */ - if (*orig == '-') - return (bfd_vma) (bfd_signed_vma) (long) ul; - return (bfd_vma) ul; - } - - /* Note that even though strtoul overflowed, it should have set *pp - to the end of the number, which is where we want it. */ - if (sizeof (bfd_vma) > sizeof (unsigned long)) - { - const char *p; - bfd_boolean neg; - int base; - bfd_vma over, lastdig; - bfd_boolean overflow; - bfd_vma v; - - /* Our own version of strtoul, for a bfd_vma. */ - p = orig; - - neg = FALSE; - if (*p == '+') - ++p; - else if (*p == '-') - { - neg = TRUE; - ++p; - } - - base = 10; - if (*p == '0') - { - if (p[1] == 'x' || p[1] == 'X') - { - base = 16; - p += 2; - } - else - { - base = 8; - ++p; - } - } - - over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base; - lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base; - - overflow = FALSE; - v = 0; - while (1) - { - int d; - - d = *p++; - if (ISDIGIT (d)) - d -= '0'; - else if (ISUPPER (d)) - d -= 'A'; - else if (ISLOWER (d)) - d -= 'a'; - else - break; - - if (d >= base) - break; - - if (v > over || (v == over && (bfd_vma) d > lastdig)) - { - overflow = TRUE; - break; - } - } - - if (! overflow) - { - if (neg) - v = - v; - return v; - } - } - - /* If we get here, the number is too large to represent in a - bfd_vma. */ - if (poverflow != NULL) - *poverflow = TRUE; - else - warn_stab (orig, _("numeric overflow")); - - return 0; -} - -/* Give an error for a bad stab string. */ - -static void -bad_stab (const char *p) -{ - fprintf (stderr, _("Bad stab: %s\n"), p); -} - -/* Warn about something in a stab string. */ - -static void -warn_stab (const char *p, const char *err) -{ - fprintf (stderr, _("Warning: %s: %s\n"), err, p); -} - -/* Create a handle to parse stabs symbols with. */ - -void * -start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bfd_boolean sections, - asymbol **syms, long symcount) -{ - struct stab_handle *ret; - - ret = (struct stab_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - ret->abfd = abfd; - ret->sections = sections; - ret->syms = syms; - ret->symcount = symcount; - ret->files = 1; - ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types); - ret->file_types[0] = NULL; - ret->function_end = (bfd_vma) -1; - return (void *) ret; -} - -/* When we have processed all the stabs information, we need to go - through and fill in all the undefined tags. */ - -bfd_boolean -finish_stab (void *dhandle, void *handle) -{ - struct stab_handle *info = (struct stab_handle *) handle; - struct stab_tag *st; - - if (info->within_function) - { - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, info->function_end)) - return FALSE; - info->within_function = FALSE; - info->function_end = (bfd_vma) -1; - } - - for (st = info->tags; st != NULL; st = st->next) - { - enum debug_type_kind kind; - - kind = st->kind; - if (kind == DEBUG_KIND_ILLEGAL) - kind = DEBUG_KIND_STRUCT; - st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind); - if (st->slot == DEBUG_TYPE_NULL) - return FALSE; - } - - return TRUE; -} - -/* Handle a single stabs symbol. */ - -bfd_boolean -parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value, - const char *string) -{ - struct stab_handle *info = (struct stab_handle *) handle; - - /* gcc will emit two N_SO strings per compilation unit, one for the - directory name and one for the file name. We just collect N_SO - strings as we see them, and start the new compilation unit when - we see a non N_SO symbol. */ - if (info->so_string != NULL - && (type != N_SO || *string == '\0' || value != info->so_value)) - { - if (! debug_set_filename (dhandle, info->so_string)) - return FALSE; - info->main_filename = info->so_string; - - info->gcc_compiled = 0; - info->n_opt_found = FALSE; - - /* Generally, for stabs in the symbol table, the N_LBRAC and - N_RBRAC symbols are relative to the N_SO symbol value. */ - if (! info->sections) - info->file_start_offset = info->so_value; - - /* We need to reset the mapping from type numbers to types. We - can't free the old mapping, because of the use of - debug_make_indirect_type. */ - info->files = 1; - info->file_types = ((struct stab_types **) - xmalloc (sizeof *info->file_types)); - info->file_types[0] = NULL; - - info->so_string = NULL; - - /* Now process whatever type we just got. */ - } - - switch (type) - { - case N_FN: - case N_FN_SEQ: - break; - - case N_LBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - if (! info->within_function) - { - fprintf (stderr, _("N_LBRAC not within function\n")); - return FALSE; - } - - /* Start an inner lexical block. */ - if (! debug_start_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return FALSE; - - /* Emit any pending variable definitions. */ - if (! stab_emit_pending_vars (dhandle, info)) - return FALSE; - - ++info->block_depth; - break; - - case N_RBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - /* We shouldn't have any pending variable definitions here, but, - if we do, we probably need to emit them before closing the - block. */ - if (! stab_emit_pending_vars (dhandle, info)) - return FALSE; - - /* End an inner lexical block. */ - if (! debug_end_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return FALSE; - - --info->block_depth; - if (info->block_depth < 0) - { - fprintf (stderr, _("Too many N_RBRACs\n")); - return FALSE; - } - break; - - case N_SO: - /* This always ends a function. */ - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (*string != '\0' - && info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return FALSE; - info->within_function = FALSE; - info->function_end = (bfd_vma) -1; - } - - /* An empty string is emitted by gcc at the end of a compilation - unit. */ - if (*string == '\0') - return TRUE; - - /* Just accumulate strings until we see a non N_SO symbol. If - the string starts with a directory separator or some other - form of absolute path specification, we discard the previously - accumulated strings. */ - if (info->so_string == NULL) - info->so_string = xstrdup (string); - else - { - char *f; - - f = info->so_string; - - if (IS_ABSOLUTE_PATH (string)) - info->so_string = xstrdup (string); - else - info->so_string = concat (info->so_string, string, - (const char *) NULL); - free (f); - } - - info->so_value = value; - - break; - - case N_SOL: - /* Start an include file. */ - if (! debug_start_source (dhandle, string)) - return FALSE; - break; - - case N_BINCL: - /* Start an include file which may be replaced. */ - push_bincl (info, string, value); - if (! debug_start_source (dhandle, string)) - return FALSE; - break; - - case N_EINCL: - /* End an N_BINCL include. */ - if (! debug_start_source (dhandle, pop_bincl (info))) - return FALSE; - break; - - case N_EXCL: - /* This is a duplicate of a header file named by N_BINCL which - was eliminated by the linker. */ - if (! find_excl (info, string, value)) - return FALSE; - break; - - case N_SLINE: - if (! debug_record_line (dhandle, desc, - value + (info->within_function - ? info->function_start_offset : 0))) - return FALSE; - break; - - case N_BCOMM: - if (! debug_start_common_block (dhandle, string)) - return FALSE; - break; - - case N_ECOMM: - if (! debug_end_common_block (dhandle, string)) - return FALSE; - break; - - case N_FUN: - if (*string == '\0') - { - if (info->within_function) - { - /* This always marks the end of a function; we don't - need to worry about info->function_end. */ - if (info->sections) - value += info->function_start_offset; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, value)) - return FALSE; - info->within_function = FALSE; - info->function_end = (bfd_vma) -1; - } - break; - } - - /* A const static symbol in the .text section will have an N_FUN - entry. We need to use these to mark the end of the function, - in case we are looking at gcc output before it was changed to - always emit an empty N_FUN. We can't call debug_end_function - here, because it might be a local static symbol. */ - if (info->within_function - && (info->function_end == (bfd_vma) -1 - || value < info->function_end)) - info->function_end = value; - - /* Fall through. */ - /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM - symbols, and if it does not start with :S, gdb relocates the - value to the start of the section. gcc always seems to use - :S, so we don't worry about this. */ - /* Fall through. */ - default: - { - const char *colon; - - colon = strchr (string, ':'); - if (colon != NULL - && (colon[1] == 'f' || colon[1] == 'F')) - { - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return FALSE; - info->function_end = (bfd_vma) -1; - } - /* For stabs in sections, line numbers and block addresses - are offsets from the start of the function. */ - if (info->sections) - info->function_start_offset = value; - info->within_function = TRUE; - } - - if (! parse_stab_string (dhandle, info, type, desc, value, string)) - return FALSE; - } - break; - - case N_OPT: - if (string != NULL && strcmp (string, "gcc2_compiled.") == 0) - info->gcc_compiled = 2; - else if (string != NULL && strcmp (string, "gcc_compiled.") == 0) - info->gcc_compiled = 1; - else - info->n_opt_found = TRUE; - break; - - case N_OBJ: - case N_ENDM: - case N_MAIN: - case N_WARNING: - break; - } - - return TRUE; -} - -/* Parse the stabs string. */ - -static bfd_boolean -parse_stab_string (void *dhandle, struct stab_handle *info, int stabtype, - int desc ATTRIBUTE_UNUSED, bfd_vma value, const char *string) -{ - const char *p; - char *name; - int type; - debug_type dtype; - bfd_boolean synonym; - bfd_boolean self_crossref; - debug_type *slot; - - p = strchr (string, ':'); - if (p == NULL) - return TRUE; - - while (p[1] == ':') - { - p += 2; - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (string); - return FALSE; - } - } - - /* FIXME: Sometimes the special C++ names start with '.'. */ - name = NULL; - if (string[0] == '$') - { - switch (string[1]) - { - case 't': - name = "this"; - break; - case 'v': - /* Was: name = "vptr"; */ - break; - case 'e': - name = "eh_throw"; - break; - case '_': - /* This was an anonymous type that was never fixed up. */ - break; - case 'X': - /* SunPRO (3.0 at least) static variable encoding. */ - break; - default: - warn_stab (string, _("unknown C++ encoded name")); - break; - } - } - - if (name == NULL) - { - if (p == string || (string[0] == ' ' && p == string + 1)) - name = NULL; - else - name = savestring (string, p - string); - } - - ++p; - if (ISDIGIT (*p) || *p == '(' || *p == '-') - type = 'l'; - else - type = *p++; - - switch (type) - { - case 'c': - /* c is a special case, not followed by a type-number. - SYMBOL:c=iVALUE for an integer constant symbol. - SYMBOL:c=rVALUE for a floating constant symbol. - SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - if (*p != '=') - { - bad_stab (string); - return FALSE; - } - ++p; - switch (*p++) - { - case 'r': - /* Floating point constant. */ - if (! debug_record_float_const (dhandle, name, atof (p))) - return FALSE; - break; - case 'i': - /* Integer constant. */ - /* Defining integer constants this way is kind of silly, - since 'e' constants allows the compiler to give not only - the value, but the type as well. C has at least int, - long, unsigned int, and long long as constant types; - other languages probably should have at least unsigned as - well as signed constants. */ - if (! debug_record_int_const (dhandle, name, atoi (p))) - return FALSE; - break; - case 'e': - /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value - can be represented as integral. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (*p != ',') - { - bad_stab (string); - return FALSE; - } - if (! debug_record_typed_const (dhandle, name, dtype, atoi (p))) - return FALSE; - break; - default: - bad_stab (string); - return FALSE; - } - - break; - - case 'C': - /* The name of a caught exception. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_label (dhandle, name, dtype, value)) - return FALSE; - break; - - case 'f': - case 'F': - /* A function definition. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_function (dhandle, name, dtype, type == 'F', value)) - return FALSE; - - /* Sun acc puts declared types of arguments here. We don't care - about their actual types (FIXME -- we should remember the whole - function prototype), but the list may define some new types - that we have to remember, so we must scan it now. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return FALSE; - } - - break; - - case 'G': - { - char leading; - long c; - asymbol **ps; - - /* A global symbol. The value must be extracted from the - symbol table. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - leading = bfd_get_symbol_leading_char (info->abfd); - for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps) - { - const char *n; - - n = bfd_asymbol_name (*ps); - if (leading != '\0' && *n == leading) - ++n; - if (*n == *name && strcmp (n, name) == 0) - break; - } - if (c > 0) - value = bfd_asymbol_value (*ps); - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL, - value)) - return FALSE; - } - break; - - /* This case is faked by a conditional above, when there is no - code letter in the dbx data. Dbx data never actually - contains 'l'. */ - case 'l': - case 's': - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return FALSE; - break; - - case 'p': - /* A function parameter. */ - if (*p != 'F') - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - else - { - /* pF is a two-letter code that means a function parameter in - Fortran. The type-number specifies the type of the return - value. Translate it into a pointer-to-function type. */ - ++p; - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype != DEBUG_TYPE_NULL) - { - debug_type ftype; - - ftype = debug_make_function_type (dhandle, dtype, - (debug_type *) NULL, FALSE); - dtype = debug_make_pointer_type (dhandle, ftype); - } - } - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK, - value)) - return FALSE; - - /* FIXME: At this point gdb considers rearranging the parameter - address on a big endian machine if it is smaller than an int. - We have no way to do that, since we don't really know much - about the target. */ - break; - - case 'P': - if (stabtype == N_FUN) - { - /* Prototype of a function referenced by this file. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return FALSE; - } - break; - } - /* Fall through. */ - case 'R': - /* Parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG, - value)) - return FALSE; - break; - - case 'r': - /* Register variable (either global or local). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER, - value)) - return FALSE; - - /* FIXME: At this point gdb checks to combine pairs of 'p' and - 'r' stabs into a single 'P' stab. */ - break; - - case 'S': - /* Static symbol at top level of file. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC, - value)) - return FALSE; - break; - - case 't': - /* A typedef. */ - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (name == NULL) - { - /* A nameless type. Nothing to do. */ - return TRUE; - } - - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - - if (slot != NULL) - *slot = dtype; - - break; - - case 'T': - /* Struct, union, or enum tag. For GNU C++, this can be be followed - by 't' which means we are typedef'ing it as well. */ - if (*p != 't') - { - synonym = FALSE; - /* FIXME: gdb sets synonym to TRUE if the current language - is C++. */ - } - else - { - synonym = TRUE; - ++p; - } - - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (name == NULL) - return TRUE; - - /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is - a cross reference to itself. These are generated by some - versions of g++. */ - self_crossref = info->self_crossref; - - dtype = debug_tag_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (slot != NULL) - *slot = dtype; - - /* See if we have a cross reference to this tag which we can now - fill in. Avoid filling in a cross reference to ourselves, - because that would lead to circular debugging information. */ - if (! self_crossref) - { - register struct stab_tag **pst; - - for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next) - { - if ((*pst)->name[0] == name[0] - && strcmp ((*pst)->name, name) == 0) - { - (*pst)->slot = dtype; - *pst = (*pst)->next; - break; - } - } - } - - if (synonym) - { - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - - if (slot != NULL) - *slot = dtype; - } - - break; - - case 'V': - /* Static symbol of local scope */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - /* FIXME: gdb checks os9k_stabs here. */ - if (! stab_record_variable (dhandle, info, name, dtype, - DEBUG_LOCAL_STATIC, value)) - return FALSE; - break; - - case 'v': - /* Reference parameter. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE, - value)) - return FALSE; - break; - - case 'a': - /* Reference parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG, - value)) - return FALSE; - break; - - case 'X': - /* This is used by Sun FORTRAN for "function result value". - Sun claims ("dbx and dbxtool interfaces", 2nd ed) - that Pascal uses it too, but when I tried it Pascal used - "x:3" (local symbol) instead. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return FALSE; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return FALSE; - break; - - case 'Y': - /* SUNPro C++ Namespace =Yn0. */ - /* Skip the namespace mapping, as it is not used now. */ - if (*(++p) == 'n' && *(++p) == '0') - { - /* =Yn0name; */ - while (*p != ';') - ++p; - ++p; - return TRUE; - } - /* TODO SUNPro C++ support: - Support default arguments after F,P parameters - Ya = Anonymous unions - YM,YD = Pointers to class members - YT,YI = Templates - YR = Run-time type information (RTTI) */ - - /* Fall through. */ - - default: - bad_stab (string); - return FALSE; - } - - /* FIXME: gdb converts structure values to structure pointers in a - couple of cases, depending upon the target. */ - - return TRUE; -} - -/* Parse a stabs type. The typename argument is non-NULL if this is a - typedef or a tag definition. The pp argument points to the stab - string, and is updated. The slotp argument points to a place to - store the slot used if the type is being defined. */ - -static debug_type -parse_stab_type (void *dhandle, struct stab_handle *info, const char *type_name, const char **pp, debug_type **slotp) -{ - const char *orig; - int typenums[2]; - int size; - bfd_boolean stringp; - int descriptor; - debug_type dtype; - - if (slotp != NULL) - *slotp = NULL; - - orig = *pp; - - size = -1; - stringp = FALSE; - - info->self_crossref = FALSE; - - /* Read type number if present. The type number may be omitted. - for instance in a two-dimensional array declared with type - "ar1;1;10;ar1;1;10;4". */ - if (! ISDIGIT (**pp) && **pp != '(' && **pp != '-') - { - /* 'typenums=' not present, type is anonymous. Read and return - the definition, but don't put it in the type vector. */ - typenums[0] = typenums[1] = -1; - } - else - { - if (! parse_stab_type_number (pp, typenums)) - return DEBUG_TYPE_NULL; - - if (**pp != '=') - /* Type is not being defined here. Either it already - exists, or this is a forward reference to it. */ - return stab_find_type (dhandle, info, typenums); - - /* Only set the slot if the type is being defined. This means - that the mapping from type numbers to types will only record - the name of the typedef which defines a type. If we don't do - this, then something like - typedef int foo; - int i; - will record that i is of type foo. Unfortunately, stabs - information is ambiguous about variable types. For this code, - typedef int foo; - int i; - foo j; - the stabs information records both i and j as having the same - type. This could be fixed by patching the compiler. */ - if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0) - *slotp = stab_find_slot (info, typenums); - - /* Type is being defined here. */ - /* Skip the '='. */ - ++*pp; - - while (**pp == '@') - { - const char *p = *pp + 1; - const char *attr; - - if (ISDIGIT (*p) || *p == '(' || *p == '-') - /* Member type. */ - break; - - /* Type attributes. */ - attr = p; - - for (; *p != ';'; ++p) - { - if (*p == '\0') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - *pp = p + 1; - - switch (*attr) - { - case 's': - size = atoi (attr + 1); - size /= 8; /* Size is in bits. We store it in bytes. */ - if (size <= 0) - size = -1; - break; - - case 'S': - stringp = TRUE; - break; - - default: - /* Ignore unrecognized type attributes, so future - compilers can invent new ones. */ - break; - } - } - } - - descriptor = **pp; - ++*pp; - - switch (descriptor) - { - case 'x': - { - enum debug_type_kind code; - const char *q1, *q2, *p; - - /* A cross reference to another type. */ - switch (**pp) - { - case 's': - code = DEBUG_KIND_STRUCT; - break; - case 'u': - code = DEBUG_KIND_UNION; - break; - case 'e': - code = DEBUG_KIND_ENUM; - break; - default: - /* Complain and keep going, so compilers can invent new - cross-reference types. */ - warn_stab (orig, _("unrecognized cross reference type")); - code = DEBUG_KIND_STRUCT; - break; - } - ++*pp; - - q1 = strchr (*pp, '<'); - p = strchr (*pp, ':'); - if (p == NULL) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - if (q1 != NULL && p > q1 && p[1] == ':') - { - int nest = 0; - - for (q2 = q1; *q2 != '\0'; ++q2) - { - if (*q2 == '<') - ++nest; - else if (*q2 == '>') - --nest; - else if (*q2 == ':' && nest == 0) - break; - } - p = q2; - if (*p != ':') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - - /* Some versions of g++ can emit stabs like - fleep:T20=xsfleep: - which define structures in terms of themselves. We need to - tell the caller to avoid building a circular structure. */ - if (type_name != NULL - && strncmp (type_name, *pp, p - *pp) == 0 - && type_name[p - *pp] == '\0') - info->self_crossref = TRUE; - - dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code); - - *pp = p + 1; - } - break; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '(': - { - const char *hold; - int xtypenums[2]; - - /* This type is defined as another type. */ - (*pp)--; - hold = *pp; - - /* Peek ahead at the number to detect void. */ - if (! parse_stab_type_number (pp, xtypenums)) - return DEBUG_TYPE_NULL; - - if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1]) - { - /* This type is being defined as itself, which means that - it is void. */ - dtype = debug_make_void_type (dhandle); - } - else - { - *pp = hold; - - /* Go back to the number and have parse_stab_type get it. - This means that we can deal with something like - t(1,2)=(3,4)=... which the Lucid compiler uses. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - break; - } - - case '*': - dtype = debug_make_pointer_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case '&': - /* Reference to another type. */ - dtype = (debug_make_reference_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case 'f': - /* Function returning another type. */ - /* FIXME: gdb checks os9k_stabs here. */ - dtype = (debug_make_function_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL), - (debug_type *) NULL, FALSE)); - break; - - case 'k': - /* Const qualifier on some type (Sun). */ - /* FIXME: gdb accepts 'c' here if os9k_stabs. */ - dtype = debug_make_const_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case 'B': - /* Volatile qual on some type (Sun). */ - /* FIXME: gdb accepts 'i' here if os9k_stabs. */ - dtype = (debug_make_volatile_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case '@': - /* Offset (class & variable) type. This is used for a pointer - relative to an object. */ - { - debug_type domain; - debug_type memtype; - - /* Member type. */ - - domain = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (memtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - dtype = debug_make_offset_type (dhandle, domain, memtype); - } - break; - - case '#': - /* Method (class & fn) type. */ - if (**pp == '#') - { - debug_type return_type; - - ++*pp; - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - dtype = debug_make_method_type (dhandle, return_type, - DEBUG_TYPE_NULL, - (debug_type *) NULL, FALSE); - } - else - { - debug_type domain; - debug_type return_type; - debug_type *args; - unsigned int n; - unsigned int alloc; - bfd_boolean varargs; - - domain = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - alloc = 10; - args = (debug_type *) xmalloc (alloc * sizeof *args); - n = 0; - while (**pp != ';') - { - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - args = ((debug_type *) - xrealloc (args, alloc * sizeof *args)); - } - - args[n] = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (args[n] == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - ++n; - } - ++*pp; - - /* If the last type is not void, then this function takes a - variable number of arguments. Otherwise, we must strip - the void type. */ - if (n == 0 - || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID) - varargs = TRUE; - else - { - --n; - varargs = FALSE; - } - - args[n] = DEBUG_TYPE_NULL; - - dtype = debug_make_method_type (dhandle, return_type, domain, args, - varargs); - } - break; - - case 'r': - /* Range type. */ - dtype = parse_stab_range_type (dhandle, info, type_name, pp, typenums); - break; - - case 'b': - /* FIXME: gdb checks os9k_stabs here. */ - /* Sun ACC builtin int type. */ - dtype = parse_stab_sun_builtin_type (dhandle, pp); - break; - - case 'R': - /* Sun ACC builtin float type. */ - dtype = parse_stab_sun_floating_type (dhandle, pp); - break; - - case 'e': - /* Enumeration type. */ - dtype = parse_stab_enum_type (dhandle, pp); - break; - - case 's': - case 'u': - /* Struct or union type. */ - dtype = parse_stab_struct_type (dhandle, info, type_name, pp, - descriptor == 's', typenums); - break; - - case 'a': - /* Array type. */ - if (**pp != 'r') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - dtype = parse_stab_array_type (dhandle, info, pp, stringp); - break; - - case 'S': - dtype = debug_make_set_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL), - stringp); - break; - - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - if (size != -1) - { - if (! debug_record_type_size (dhandle, dtype, (unsigned int) size)) - return DEBUG_TYPE_NULL; - } - - return dtype; -} - -/* Read a number by which a type is referred to in dbx data, or - perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a - single number N is equivalent to (0,N). Return the two numbers by - storing them in the vector TYPENUMS. */ - -static bfd_boolean -parse_stab_type_number (const char **pp, int *typenums) -{ - const char *orig; - - orig = *pp; - - if (**pp != '(') - { - typenums[0] = 0; - typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL); - } - else - { - ++*pp; - typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ')') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - } - - return TRUE; -} - -/* Parse a range type. */ - -static debug_type -parse_stab_range_type (void *dhandle, struct stab_handle *info, const char *type_name, const char **pp, const int *typenums) -{ - const char *orig; - int rangenums[2]; - bfd_boolean self_subrange; - debug_type index_type; - const char *s2, *s3; - bfd_signed_vma n2, n3; - bfd_boolean ov2, ov3; - - orig = *pp; - - index_type = DEBUG_TYPE_NULL; - - /* First comes a type we are a subrange of. - In C it is usually 0, 1 or the type being defined. */ - if (! parse_stab_type_number (pp, rangenums)) - return DEBUG_TYPE_NULL; - - self_subrange = (rangenums[0] == typenums[0] - && rangenums[1] == typenums[1]); - - if (**pp == '=') - { - *pp = orig; - index_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (**pp == ';') - ++*pp; - - /* The remaining two operands are usually lower and upper bounds of - the range. But in some special cases they mean something else. */ - s2 = *pp; - n2 = parse_number (pp, &ov2); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - s3 = *pp; - n3 = parse_number (pp, &ov3); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (ov2 || ov3) - { - /* gcc will emit range stabs for long long types. Handle this - as a special case. FIXME: This needs to be more general. */ -#define LLLOW "01000000000000000000000;" -#define LLHIGH "0777777777777777777777;" -#define ULLHIGH "01777777777777777777777;" - if (index_type == DEBUG_TYPE_NULL) - { - if (CONST_STRNEQ (s2, LLLOW) - && CONST_STRNEQ (s3, LLHIGH)) - return debug_make_int_type (dhandle, 8, FALSE); - if (! ov2 - && n2 == 0 - && CONST_STRNEQ (s3, ULLHIGH)) - return debug_make_int_type (dhandle, 8, TRUE); - } - - warn_stab (orig, _("numeric overflow")); - } - - if (index_type == DEBUG_TYPE_NULL) - { - /* A type defined as a subrange of itself, with both bounds 0, - is void. */ - if (self_subrange && n2 == 0 && n3 == 0) - return debug_make_void_type (dhandle); - - /* A type defined as a subrange of itself, with n2 positive and - n3 zero, is a complex type, and n2 is the number of bytes. */ - if (self_subrange && n3 == 0 && n2 > 0) - return debug_make_complex_type (dhandle, n2); - - /* If n3 is zero and n2 is positive, this is a floating point - type, and n2 is the number of bytes. */ - if (n3 == 0 && n2 > 0) - return debug_make_float_type (dhandle, n2); - - /* If the upper bound is -1, this is an unsigned int. */ - if (n2 == 0 && n3 == -1) - { - /* When gcc is used with -gstabs, but not -gstabs+, it will emit - long long int:t6=r1;0;-1; - long long unsigned int:t7=r1;0;-1; - We hack here to handle this reasonably. */ - if (type_name != NULL) - { - if (strcmp (type_name, "long long int") == 0) - return debug_make_int_type (dhandle, 8, FALSE); - else if (strcmp (type_name, "long long unsigned int") == 0) - return debug_make_int_type (dhandle, 8, TRUE); - } - /* FIXME: The size here really depends upon the target. */ - return debug_make_int_type (dhandle, 4, TRUE); - } - - /* A range of 0 to 127 is char. */ - if (self_subrange && n2 == 0 && n3 == 127) - return debug_make_int_type (dhandle, 1, FALSE); - - /* FIXME: gdb checks for the language CHILL here. */ - - if (n2 == 0) - { - if (n3 < 0) - return debug_make_int_type (dhandle, - n3, TRUE); - else if (n3 == 0xff) - return debug_make_int_type (dhandle, 1, TRUE); - else if (n3 == 0xffff) - return debug_make_int_type (dhandle, 2, TRUE); - else if (n3 == (bfd_signed_vma) 0xffffffff) - return debug_make_int_type (dhandle, 4, TRUE); -#ifdef BFD64 - else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff)) - return debug_make_int_type (dhandle, 8, TRUE); -#endif - } - else if (n3 == 0 - && n2 < 0 - && (self_subrange || n2 == -8)) - return debug_make_int_type (dhandle, - n2, TRUE); - else if (n2 == - n3 - 1 || n2 == n3 + 1) - { - if (n3 == 0x7f) - return debug_make_int_type (dhandle, 1, FALSE); - else if (n3 == 0x7fff) - return debug_make_int_type (dhandle, 2, FALSE); - else if (n3 == 0x7fffffff) - return debug_make_int_type (dhandle, 4, FALSE); -#ifdef BFD64 - else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff)) - return debug_make_int_type (dhandle, 8, FALSE); -#endif - } - } - - /* At this point I don't have the faintest idea how to deal with a - self_subrange type; I'm going to assume that this is used as an - idiom, and that all of them are special cases. So . . . */ - if (self_subrange) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - index_type = stab_find_type (dhandle, info, rangenums); - if (index_type == DEBUG_TYPE_NULL) - { - /* Does this actually ever happen? Is that why we are worrying - about dealing with it rather than just calling error_type? */ - warn_stab (orig, _("missing index type")); - index_type = debug_make_int_type (dhandle, 4, FALSE); - } - - return debug_make_range_type (dhandle, index_type, n2, n3); -} - -/* Sun's ACC uses a somewhat saner method for specifying the builtin - typedefs in every file (for int, long, etc): - - type = b ; ; - signed = u or s. Possible c in addition to u or s (for char?). - offset = offset from high order bit to start bit of type. - width is # bytes in object of this type, nbits is # bits in type. - - The width/offset stuff appears to be for small objects stored in - larger ones (e.g. `shorts' in `int' registers). We ignore it for now, - FIXME. */ - -static debug_type -parse_stab_sun_builtin_type (void *dhandle, const char **pp) -{ - const char *orig; - bfd_boolean unsignedp; - bfd_vma bits; - - orig = *pp; - - switch (**pp) - { - case 's': - unsignedp = FALSE; - break; - case 'u': - unsignedp = TRUE; - break; - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* OpenSolaris source code indicates that one of "cbv" characters - can come next and specify the intrinsic 'iformat' encoding. - 'c' is character encoding, 'b' is boolean encoding, and 'v' is - varargs encoding. This field can be safely ignored because - the type of the field is determined from the bitwidth extracted - below. */ - if (**pp == 'c' || **pp == 'b' || **pp == 'v') - ++*pp; - - /* The first number appears to be the number of bytes occupied - by this type, except that unsigned short is 4 instead of 2. - Since this information is redundant with the third number, - we will ignore it. */ - (void) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The second number is always 0, so ignore it too. */ - (void) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The third number is the number of bits for this type. */ - bits = parse_number (pp, (bfd_boolean *) NULL); - - /* The type *should* end with a semicolon. If it are embedded - in a larger type the semicolon may be the only way to know where - the type ends. If this type is at the end of the stabstring we - can deal with the omitted semicolon (but we don't have to like - it). Don't bother to complain(), Sun's compiler omits the semicolon - for "void". */ - if (**pp == ';') - ++*pp; - - if (bits == 0) - return debug_make_void_type (dhandle); - - return debug_make_int_type (dhandle, bits / 8, unsignedp); -} - -/* Parse a builtin floating type generated by the Sun compiler. */ - -static debug_type -parse_stab_sun_floating_type (void *dhandle, const char **pp) -{ - const char *orig; - bfd_vma details; - bfd_vma bytes; - - orig = *pp; - - /* The first number has more details about the type, for example - FN_COMPLEX. */ - details = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - /* The second number is the number of bytes occupied by this type */ - bytes = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (details == NF_COMPLEX - || details == NF_COMPLEX16 - || details == NF_COMPLEX32) - return debug_make_complex_type (dhandle, bytes); - - return debug_make_float_type (dhandle, bytes); -} - -/* Handle an enum type. */ - -static debug_type -parse_stab_enum_type (void *dhandle, const char **pp) -{ - const char *orig; - const char **names; - bfd_signed_vma *values; - unsigned int n; - unsigned int alloc; - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* The aix4 compiler emits an extra field before the enum members; - my guess is it's a type of some sort. Just ignore it. */ - if (**pp == '-') - { - while (**pp != ':') - ++*pp; - ++*pp; - } - - /* Read the value-names and their values. - The input syntax is NAME:VALUE,NAME:VALUE, and so on. - A semicolon or comma instead of a NAME means the end. */ - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values); - n = 0; - while (**pp != '\0' && **pp != ';' && **pp != ',') - { - const char *p; - char *name; - bfd_signed_vma val; - - p = *pp; - while (*p != ':') - ++p; - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - val = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - free (name); - free (names); - free (values); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - values = ((bfd_signed_vma *) - xrealloc (values, alloc * sizeof *values)); - } - - names[n] = name; - values[n] = val; - ++n; - } - - names[n] = NULL; - values[n] = 0; - - if (**pp == ';') - ++*pp; - - return debug_make_enum_type (dhandle, names, values); -} - -/* Read the description of a structure (or union type) and return an object - describing the type. - - PP points to a character pointer that points to the next unconsumed token - in the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;", - *PP will point to "4a:1,0,32;;". */ - -static debug_type -parse_stab_struct_type (void *dhandle, struct stab_handle *info, - const char *tagname, const char **pp, - bfd_boolean structp, const int *typenums) -{ - bfd_vma size; - debug_baseclass *baseclasses; - debug_field *fields = NULL; - bfd_boolean statics; - debug_method *methods; - debug_type vptrbase; - bfd_boolean ownvptr; - - /* Get the size. */ - size = parse_number (pp, (bfd_boolean *) NULL); - - /* Get the other information. */ - if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses) - || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics) - || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods) - || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase, - &ownvptr)) - { - if (fields != NULL) - free (fields); - return DEBUG_TYPE_NULL; - } - - if (! statics - && baseclasses == NULL - && methods == NULL - && vptrbase == DEBUG_TYPE_NULL - && ! ownvptr) - return debug_make_struct_type (dhandle, structp, size, fields); - - return debug_make_object_type (dhandle, structp, size, fields, baseclasses, - methods, vptrbase, ownvptr); -} - -/* The stabs for C++ derived classes contain baseclass information which - is marked by a '!' character after the total size. This function is - called when we encounter the baseclass marker, and slurps up all the - baseclass information. - - Immediately following the '!' marker is the number of base classes that - the class is derived from, followed by information for each base class. - For each base class, there are two visibility specifiers, a bit offset - to the base class information within the derived class, a reference to - the type for the base class, and a terminating semicolon. - - A typical example, with two base classes, would be "!2,020,19;0264,21;". - ^^ ^ ^ ^ ^ ^ ^ - Baseclass information marker __________________|| | | | | | | - Number of baseclasses __________________________| | | | | | | - Visibility specifiers (2) ________________________| | | | | | - Offset in bits from start of class _________________| | | | | - Type number for base class ___________________________| | | | - Visibility specifiers (2) _______________________________| | | - Offset in bits from start of class ________________________| | - Type number of base class ____________________________________| - - Return TRUE for success, FALSE for failure. */ - -static bfd_boolean -parse_stab_baseclasses (void *dhandle, struct stab_handle *info, - const char **pp, debug_baseclass **retp) -{ - const char *orig; - unsigned int c, i; - debug_baseclass *classes; - - *retp = NULL; - - orig = *pp; - - if (**pp != '!') - { - /* No base classes. */ - return TRUE; - } - ++*pp; - - c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL); - - if (**pp != ',') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - - classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp)); - - for (i = 0; i < c; i++) - { - bfd_boolean is_virtual; - enum debug_visibility visibility; - bfd_vma bitpos; - debug_type type; - - switch (**pp) - { - case '0': - is_virtual = FALSE; - break; - case '1': - is_virtual = TRUE; - break; - default: - warn_stab (orig, _("unknown virtual character for baseclass")); - is_virtual = FALSE; - break; - } - ++*pp; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, _("unknown visibility character for baseclass")); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - /* The remaining value is the bit offset of the portion of the - object corresponding to this baseclass. Always zero in the - absence of multiple inheritance. */ - bitpos = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return FALSE; - - classes[i] = debug_make_baseclass (dhandle, type, bitpos, is_virtual, - visibility); - if (classes[i] == DEBUG_BASECLASS_NULL) - return FALSE; - - if (**pp != ';') - return FALSE; - ++*pp; - } - - classes[i] = DEBUG_BASECLASS_NULL; - - *retp = classes; - - return TRUE; -} - -/* Read struct or class data fields. They have the form: - - NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ; - - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The optional VISIBILITY is one of: - - '/0' (VISIBILITY_PRIVATE) - '/1' (VISIBILITY_PROTECTED) - '/2' (VISIBILITY_PUBLIC) - '/9' (VISIBILITY_IGNORE) - - or nothing, for C style fields with public visibility. - - Returns 1 for success, 0 for failure. */ - -static bfd_boolean -parse_stab_struct_fields (void *dhandle, struct stab_handle *info, - const char **pp, debug_field **retp, - bfd_boolean *staticsp) -{ - const char *orig; - const char *p; - debug_field *fields; - unsigned int c; - unsigned int alloc; - - *retp = NULL; - *staticsp = FALSE; - - orig = *pp; - - c = 0; - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - while (**pp != ';') - { - /* FIXME: gdb checks os9k_stabs here. */ - - p = *pp; - - /* Add 1 to c to leave room for NULL pointer at end. */ - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - /* If it starts with CPLUS_MARKER it is a special abbreviation, - unless the CPLUS_MARKER is followed by an underscore, in - which case it is just the name of an anonymous type, which we - should handle like any other type name. We accept either '$' - or '.', because a field name can never contain one of these - characters except as a CPLUS_MARKER. */ - - if ((*p == '$' || *p == '.') && p[1] != '_') - { - ++*pp; - if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c)) - { - free (fields); - return FALSE; - } - ++c; - continue; - } - - /* Look for the ':' that separates the field name from the field - values. Data members are delimited by a single ':', while member - functions are delimited by a pair of ':'s. When we hit the member - functions (if any), terminate scan loop and return. */ - - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (orig); - free (fields); - return FALSE; - } - - if (p[1] == ':') - break; - - if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c, - staticsp)) - return FALSE; - - ++c; - } - - fields[c] = DEBUG_FIELD_NULL; - - *retp = fields; - - return TRUE; -} - -/* Special GNU C++ name. */ - -static bfd_boolean -parse_stab_cpp_abbrev (void *dhandle, struct stab_handle *info, - const char **pp, debug_field *retp) -{ - const char *orig; - int cpp_abbrev; - debug_type context; - const char *name; - const char *type_name; - debug_type type; - bfd_vma bitpos; - - *retp = DEBUG_FIELD_NULL; - - orig = *pp; - - if (**pp != 'v') - { - bad_stab (*pp); - return FALSE; - } - ++*pp; - - cpp_abbrev = **pp; - ++*pp; - - /* At this point, *pp points to something like "22:23=*22...", where - the type number before the ':' is the "context" and everything - after is a regular type definition. Lookup the type, find it's - name, and construct the field name. */ - - context = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (context == DEBUG_TYPE_NULL) - return FALSE; - - switch (cpp_abbrev) - { - case 'f': - /* $vf -- a virtual function table pointer. */ - name = "_vptr$"; - break; - case 'b': - /* $vb -- a virtual bsomethingorother */ - type_name = debug_get_type_name (dhandle, context); - if (type_name == NULL) - { - warn_stab (orig, _("unnamed $vb type")); - type_name = "FOO"; - } - name = concat ("_vb$", type_name, (const char *) NULL); - break; - default: - warn_stab (orig, _("unrecognized C++ abbreviation")); - name = "INVALID_CPLUSPLUS_ABBREV"; - break; - } - - if (**pp != ':') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (**pp != ',') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - - bitpos = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return FALSE; - } - ++*pp; - - *retp = debug_make_field (dhandle, name, type, bitpos, 0, - DEBUG_VISIBILITY_PRIVATE); - if (*retp == DEBUG_FIELD_NULL) - return FALSE; - - return TRUE; -} - -/* Parse a single field in a struct or union. */ - -static bfd_boolean -parse_stab_one_struct_field (void *dhandle, struct stab_handle *info, - const char **pp, const char *p, - debug_field *retp, bfd_boolean *staticsp) -{ - const char *orig; - char *name; - enum debug_visibility visibility; - debug_type type; - bfd_vma bitpos; - bfd_vma bitsize; - - orig = *pp; - - /* FIXME: gdb checks ARM_DEMANGLING here. */ - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - - if (**pp != '/') - visibility = DEBUG_VISIBILITY_PUBLIC; - else - { - ++*pp; - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, _("unknown visibility character for field")); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - } - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - { - free (name); - return FALSE; - } - - if (**pp == ':') - { - char *varname; - - /* This is a static class member. */ - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - free (name); - return FALSE; - } - - varname = savestring (*pp, p - *pp); - - *pp = p + 1; - - *retp = debug_make_static_member (dhandle, name, type, varname, - visibility); - *staticsp = TRUE; - - return TRUE; - } - - if (**pp != ',') - { - bad_stab (orig); - free (name); - return FALSE; - } - ++*pp; - - bitpos = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - free (name); - return FALSE; - } - ++*pp; - - bitsize = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - free (name); - return FALSE; - } - ++*pp; - - if (bitpos == 0 && bitsize == 0) - { - /* This can happen in two cases: (1) at least for gcc 2.4.5 or - so, it is a field which has been optimized out. The correct - stab for this case is to use VISIBILITY_IGNORE, but that is a - recent invention. (2) It is a 0-size array. For example - union { int num; char str[0]; } foo. Printing "" - for str in "p foo" is OK, since foo.str (and thus foo.str[3]) - will continue to work, and a 0-size array as a whole doesn't - have any contents to print. - - I suspect this probably could also happen with gcc -gstabs - (not -gstabs+) for static fields, and perhaps other C++ - extensions. Hopefully few people use -gstabs with gdb, since - it is intended for dbx compatibility. */ - visibility = DEBUG_VISIBILITY_IGNORE; - } - - /* FIXME: gdb does some stuff here to mark fields as unpacked. */ - - *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility); - - return TRUE; -} - -/* Read member function stabs info for C++ classes. The form of each member - function data is: - - NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ; - - An example with two member functions is: - - afunc1::20=##15;:i;2A.;afunc2::20:i;2A.; - - For the case of overloaded operators, the format is op$::*.funcs, where - $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator - name (such as `+=') and `.' marks the end of the operator name. */ - -static bfd_boolean -parse_stab_members (void *dhandle, struct stab_handle *info, - const char *tagname, const char **pp, - const int *typenums, debug_method **retp) -{ - const char *orig; - debug_method *methods; - unsigned int c; - unsigned int alloc; - char *name = NULL; - debug_method_variant *variants = NULL; - char *argtypes = NULL; - - *retp = NULL; - - orig = *pp; - - alloc = 0; - methods = NULL; - c = 0; - - while (**pp != ';') - { - const char *p; - unsigned int cvars; - unsigned int allocvars; - debug_type look_ahead_type; - - p = strchr (*pp, ':'); - if (p == NULL || p[1] != ':') - break; - - /* FIXME: Some systems use something other than '$' here. */ - if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$') - { - name = savestring (*pp, p - *pp); - *pp = p + 2; - } - else - { - /* This is a completely weird case. In order to stuff in the - names that might contain colons (the usual name delimiter), - Mike Tiemann defined a different name format which is - signalled if the identifier is "op$". In that case, the - format is "op$::XXXX." where XXXX is the name. This is - used for names like "+" or "=". YUUUUUUUK! FIXME! */ - *pp = p + 2; - for (p = *pp; *p != '.' && *p != '\0'; p++) - ; - if (*p != '.') - { - bad_stab (orig); - goto fail; - } - name = savestring (*pp, p - *pp); - *pp = p + 1; - } - - allocvars = 10; - variants = ((debug_method_variant *) - xmalloc (allocvars * sizeof *variants)); - cvars = 0; - - look_ahead_type = DEBUG_TYPE_NULL; - - do - { - debug_type type; - bfd_boolean stub; - enum debug_visibility visibility; - bfd_boolean constp, volatilep, staticp; - bfd_vma voffset; - debug_type context; - const char *physname; - bfd_boolean varargs; - - if (look_ahead_type != DEBUG_TYPE_NULL) - { - /* g++ version 1 kludge */ - type = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - } - else - { - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - goto fail; - - if (**pp != ':') - { - bad_stab (orig); - goto fail; - } - } - - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - goto fail; - } - - stub = FALSE; - if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD - && debug_get_parameter_types (dhandle, type, &varargs) == NULL) - stub = TRUE; - - argtypes = savestring (*pp, p - *pp); - *pp = p + 1; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - default: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - constp = FALSE; - volatilep = FALSE; - switch (**pp) - { - case 'A': - /* Normal function. */ - ++*pp; - break; - case 'B': - /* const member function. */ - constp = TRUE; - ++*pp; - break; - case 'C': - /* volatile member function. */ - volatilep = TRUE; - ++*pp; - break; - case 'D': - /* const volatile member function. */ - constp = TRUE; - volatilep = TRUE; - ++*pp; - break; - case '*': - case '?': - case '.': - /* File compiled with g++ version 1; no information. */ - break; - default: - warn_stab (orig, _("const/volatile indicator missing")); - break; - } - - staticp = FALSE; - switch (**pp) - { - case '*': - /* virtual member function, followed by index. The sign - bit is supposedly set to distinguish - pointers-to-methods from virtual function indicies. */ - ++*pp; - voffset = parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - goto fail; - } - ++*pp; - voffset &= 0x7fffffff; - - if (**pp == ';' || *pp == '\0') - { - /* Must be g++ version 1. */ - context = DEBUG_TYPE_NULL; - } - else - { - /* Figure out from whence this virtual function - came. It may belong to virtual function table of - one of its baseclasses. */ - look_ahead_type = parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL); - if (**pp == ':') - { - /* g++ version 1 overloaded methods. */ - context = DEBUG_TYPE_NULL; - } - else - { - context = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - goto fail; - } - ++*pp; - } - } - break; - - case '?': - /* static member function. */ - ++*pp; - staticp = TRUE; - voffset = 0; - context = DEBUG_TYPE_NULL; - if (strncmp (argtypes, name, strlen (name)) != 0) - stub = TRUE; - break; - - default: - warn_stab (orig, "member function type missing"); - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - - case '.': - ++*pp; - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - } - - /* If the type is not a stub, then the argtypes string is - the physical name of the function. Otherwise the - argtypes string is the mangled form of the argument - types, and the full type and the physical name must be - extracted from them. */ - if (! stub) - physname = argtypes; - else - { - debug_type class_type, return_type; - - class_type = stab_find_type (dhandle, info, typenums); - if (class_type == DEBUG_TYPE_NULL) - goto fail; - return_type = debug_get_return_type (dhandle, type); - if (return_type == DEBUG_TYPE_NULL) - { - bad_stab (orig); - goto fail; - } - type = parse_stab_argtypes (dhandle, info, class_type, name, - tagname, return_type, argtypes, - constp, volatilep, &physname); - if (type == DEBUG_TYPE_NULL) - goto fail; - } - - if (cvars + 1 >= allocvars) - { - allocvars += 10; - variants = ((debug_method_variant *) - xrealloc (variants, - allocvars * sizeof *variants)); - } - - if (! staticp) - variants[cvars] = debug_make_method_variant (dhandle, physname, - type, visibility, - constp, volatilep, - voffset, context); - else - variants[cvars] = debug_make_static_method_variant (dhandle, - physname, - type, - visibility, - constp, - volatilep); - if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL) - goto fail; - - ++cvars; - } - while (**pp != ';' && **pp != '\0'); - - variants[cvars] = DEBUG_METHOD_VARIANT_NULL; - - if (**pp != '\0') - ++*pp; - - if (c + 1 >= alloc) - { - alloc += 10; - methods = ((debug_method *) - xrealloc (methods, alloc * sizeof *methods)); - } - - methods[c] = debug_make_method (dhandle, name, variants); - - ++c; - } - - if (methods != NULL) - methods[c] = DEBUG_METHOD_NULL; - - *retp = methods; - - return TRUE; - - fail: - if (name != NULL) - free (name); - if (variants != NULL) - free (variants); - if (argtypes != NULL) - free (argtypes); - return FALSE; -} - -/* Parse a string representing argument types for a method. Stabs - tries to save space by packing argument types into a mangled - string. This string should give us enough information to extract - both argument types and the physical name of the function, given - the tag name. */ - -static debug_type -parse_stab_argtypes (void *dhandle, struct stab_handle *info, - debug_type class_type, const char *fieldname, - const char *tagname, debug_type return_type, - const char *argtypes, bfd_boolean constp, - bfd_boolean volatilep, const char **pphysname) -{ - bfd_boolean is_full_physname_constructor; - bfd_boolean is_constructor; - bfd_boolean is_destructor; - bfd_boolean is_v3; - debug_type *args; - bfd_boolean varargs; - unsigned int physname_len = 0; - - /* Constructors are sometimes handled specially. */ - is_full_physname_constructor = ((argtypes[0] == '_' - && argtypes[1] == '_' - && (ISDIGIT (argtypes[2]) - || argtypes[2] == 'Q' - || argtypes[2] == 't')) - || CONST_STRNEQ (argtypes, "__ct")); - - is_constructor = (is_full_physname_constructor - || (tagname != NULL - && strcmp (fieldname, tagname) == 0)); - is_destructor = ((argtypes[0] == '_' - && (argtypes[1] == '$' || argtypes[1] == '.') - && argtypes[2] == '_') - || CONST_STRNEQ (argtypes, "__dt")); - is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z'; - - if (is_destructor || is_full_physname_constructor || is_v3) - *pphysname = argtypes; - else - { - unsigned int len; - const char *const_prefix; - const char *volatile_prefix; - char buf[20]; - unsigned int mangled_name_len; - char *physname; - - len = tagname == NULL ? 0 : strlen (tagname); - const_prefix = constp ? "C" : ""; - volatile_prefix = volatilep ? "V" : ""; - - if (len == 0) - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - else if (tagname != NULL && strchr (tagname, '<') != NULL) - { - /* Template methods are fully mangled. */ - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - tagname = NULL; - len = 0; - } - else - sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); - - mangled_name_len = ((is_constructor ? 0 : strlen (fieldname)) - + strlen (buf) - + len - + strlen (argtypes) - + 1); - - if (fieldname[0] == 'o' - && fieldname[1] == 'p' - && (fieldname[2] == '$' || fieldname[2] == '.')) - { - const char *opname; - - opname = cplus_mangle_opname (fieldname + 3, 0); - if (opname == NULL) - { - fprintf (stderr, _("No mangling for \"%s\"\n"), fieldname); - return DEBUG_TYPE_NULL; - } - mangled_name_len += strlen (opname); - physname = (char *) xmalloc (mangled_name_len); - strncpy (physname, fieldname, 3); - strcpy (physname + 3, opname); - } - else - { - physname = (char *) xmalloc (mangled_name_len); - if (is_constructor) - physname[0] = '\0'; - else - strcpy (physname, fieldname); - } - - physname_len = strlen (physname); - strcat (physname, buf); - if (tagname != NULL) - strcat (physname, tagname); - strcat (physname, argtypes); - - *pphysname = physname; - } - - if (*argtypes == '\0' || is_destructor) - { - args = (debug_type *) xmalloc (sizeof *args); - *args = NULL; - return debug_make_method_type (dhandle, return_type, class_type, args, - FALSE); - } - - args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs, physname_len); - if (args == NULL) - return DEBUG_TYPE_NULL; - - return debug_make_method_type (dhandle, return_type, class_type, args, - varargs); -} - -/* The tail end of stabs for C++ classes that contain a virtual function - pointer contains a tilde, a %, and a type number. - The type number refers to the base class (possibly this class itself) which - contains the vtable pointer for the current class. - - This function is called when we have parsed all the method declarations, - so we can look for the vptr base class info. */ - -static bfd_boolean -parse_stab_tilde_field (void *dhandle, struct stab_handle *info, - const char **pp, const int *typenums, - debug_type *retvptrbase, bfd_boolean *retownvptr) -{ - const char *orig; - const char *hold; - int vtypenums[2]; - - *retvptrbase = DEBUG_TYPE_NULL; - *retownvptr = FALSE; - - orig = *pp; - - /* If we are positioned at a ';', then skip it. */ - if (**pp == ';') - ++*pp; - - if (**pp != '~') - return TRUE; - - ++*pp; - - if (**pp == '=' || **pp == '+' || **pp == '-') - { - /* Obsolete flags that used to indicate the presence of - constructors and/or destructors. */ - ++*pp; - } - - if (**pp != '%') - return TRUE; - - ++*pp; - - hold = *pp; - - /* The next number is the type number of the base class (possibly - our own class) which supplies the vtable for this class. */ - if (! parse_stab_type_number (pp, vtypenums)) - return FALSE; - - if (vtypenums[0] == typenums[0] - && vtypenums[1] == typenums[1]) - *retownvptr = TRUE; - else - { - debug_type vtype; - const char *p; - - *pp = hold; - - vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - for (p = *pp; *p != ';' && *p != '\0'; p++) - ; - if (*p != ';') - { - bad_stab (orig); - return FALSE; - } - - *retvptrbase = vtype; - - *pp = p + 1; - } - - return TRUE; -} - -/* Read a definition of an array type. */ - -static debug_type -parse_stab_array_type (void *dhandle, struct stab_handle *info, - const char **pp, bfd_boolean stringp) -{ - const char *orig; - const char *p; - int typenums[2]; - debug_type index_type; - bfd_boolean adjustable; - bfd_signed_vma lower, upper; - debug_type element_type; - - /* Format of an array type: - "ar;lower;upper;". - OS9000: "arlower,upper;". - - Fortran adjustable arrays use Adigits or Tdigits for lower or upper; - for these, produce a type like float[][]. */ - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* If the index type is type 0, we take it as int. */ - p = *pp; - if (! parse_stab_type_number (&p, typenums)) - return DEBUG_TYPE_NULL; - if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=') - { - index_type = debug_find_named_type (dhandle, "int"); - if (index_type == DEBUG_TYPE_NULL) - { - index_type = debug_make_int_type (dhandle, 4, FALSE); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - *pp = p; - } - else - { - index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - } - - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - adjustable = FALSE; - - if (! ISDIGIT (**pp) && **pp != '-') - { - ++*pp; - adjustable = TRUE; - } - - lower = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (! ISDIGIT (**pp) && **pp != '-') - { - ++*pp; - adjustable = TRUE; - } - - upper = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (element_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (adjustable) - { - lower = 0; - upper = -1; - } - - return debug_make_array_type (dhandle, element_type, index_type, lower, - upper, stringp); -} - -/* This struct holds information about files we have seen using - N_BINCL. */ - -struct bincl_file -{ - /* The next N_BINCL file. */ - struct bincl_file *next; - /* The next N_BINCL on the stack. */ - struct bincl_file *next_stack; - /* The file name. */ - const char *name; - /* The hash value. */ - bfd_vma hash; - /* The file index. */ - unsigned int file; - /* The list of types defined in this file. */ - struct stab_types *file_types; -}; - -/* Start a new N_BINCL file, pushing it onto the stack. */ - -static void -push_bincl (struct stab_handle *info, const char *name, bfd_vma hash) -{ - struct bincl_file *n; - - n = (struct bincl_file *) xmalloc (sizeof *n); - n->next = info->bincl_list; - n->next_stack = info->bincl_stack; - n->name = name; - n->hash = hash; - n->file = info->files; - n->file_types = NULL; - info->bincl_list = n; - info->bincl_stack = n; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc (info->file_types, - (info->files - * sizeof *info->file_types))); - info->file_types[n->file] = NULL; -} - -/* Finish an N_BINCL file, at an N_EINCL, popping the name off the - stack. */ - -static const char * -pop_bincl (struct stab_handle *info) -{ - struct bincl_file *o; - - o = info->bincl_stack; - if (o == NULL) - return info->main_filename; - info->bincl_stack = o->next_stack; - - o->file_types = info->file_types[o->file]; - - if (info->bincl_stack == NULL) - return info->main_filename; - return info->bincl_stack->name; -} - -/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */ - -static bfd_boolean -find_excl (struct stab_handle *info, const char *name, bfd_vma hash) -{ - struct bincl_file *l; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc (info->file_types, - (info->files - * sizeof *info->file_types))); - - for (l = info->bincl_list; l != NULL; l = l->next) - if (l->hash == hash && strcmp (l->name, name) == 0) - break; - if (l == NULL) - { - warn_stab (name, _("Undefined N_EXCL")); - info->file_types[info->files - 1] = NULL; - return TRUE; - } - - info->file_types[info->files - 1] = l->file_types; - - return TRUE; -} - -/* Handle a variable definition. gcc emits variable definitions for a - block before the N_LBRAC, so we must hold onto them until we see - it. The SunPRO compiler emits variable definitions after the - N_LBRAC, so we can call debug_record_variable immediately. */ - -static bfd_boolean -stab_record_variable (void *dhandle, struct stab_handle *info, - const char *name, debug_type type, - enum debug_var_kind kind, bfd_vma val) -{ - struct stab_pending_var *v; - - if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - || ! info->within_function - || (info->gcc_compiled == 0 && info->n_opt_found)) - return debug_record_variable (dhandle, name, type, kind, val); - - v = (struct stab_pending_var *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->next = info->pending; - v->name = name; - v->type = type; - v->kind = kind; - v->val = val; - info->pending = v; - - return TRUE; -} - -/* Emit pending variable definitions. This is called after we see the - N_LBRAC that starts the block. */ - -static bfd_boolean -stab_emit_pending_vars (void *dhandle, struct stab_handle *info) -{ - struct stab_pending_var *v; - - v = info->pending; - while (v != NULL) - { - struct stab_pending_var *next; - - if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val)) - return FALSE; - - next = v->next; - free (v); - v = next; - } - - info->pending = NULL; - - return TRUE; -} - -/* Find the slot for a type in the database. */ - -static debug_type * -stab_find_slot (struct stab_handle *info, const int *typenums) -{ - int filenum; - int tindex; - struct stab_types **ps; - - filenum = typenums[0]; - tindex = typenums[1]; - - if (filenum < 0 || (unsigned int) filenum >= info->files) - { - fprintf (stderr, _("Type file number %d out of range\n"), filenum); - return NULL; - } - if (tindex < 0) - { - fprintf (stderr, _("Type index number %d out of range\n"), tindex); - return NULL; - } - - ps = info->file_types + filenum; - - while (tindex >= STAB_TYPES_SLOTS) - { - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - ps = &(*ps)->next; - tindex -= STAB_TYPES_SLOTS; - } - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - - return (*ps)->types + tindex; -} - -/* Find a type given a type number. If the type has not been - allocated yet, create an indirect type. */ - -static debug_type -stab_find_type (void *dhandle, struct stab_handle *info, const int *typenums) -{ - debug_type *slot; - - if (typenums[0] == 0 && typenums[1] < 0) - { - /* A negative type number indicates an XCOFF builtin type. */ - return stab_xcoff_builtin_type (dhandle, info, typenums[1]); - } - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return DEBUG_TYPE_NULL; - - if (*slot == DEBUG_TYPE_NULL) - return debug_make_indirect_type (dhandle, slot, (const char *) NULL); - - return *slot; -} - -/* Record that a given type number refers to a given type. */ - -static bfd_boolean -stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info, - const int *typenums, debug_type type) -{ - debug_type *slot; - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return FALSE; - - /* gdb appears to ignore type redefinitions, so we do as well. */ - - *slot = type; - - return TRUE; -} - -/* Return an XCOFF builtin type. */ - -static debug_type -stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info, - int typenum) -{ - debug_type rettype; - const char *name; - - if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT) - { - fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum); - return DEBUG_TYPE_NULL; - } - if (info->xcoff_types[-typenum] != NULL) - return info->xcoff_types[-typenum]; - - switch (-typenum) - { - case 1: - /* The size of this and all the other types are fixed, defined - by the debugging format. */ - name = "int"; - rettype = debug_make_int_type (dhandle, 4, FALSE); - break; - case 2: - name = "char"; - rettype = debug_make_int_type (dhandle, 1, FALSE); - break; - case 3: - name = "short"; - rettype = debug_make_int_type (dhandle, 2, FALSE); - break; - case 4: - name = "long"; - rettype = debug_make_int_type (dhandle, 4, FALSE); - break; - case 5: - name = "unsigned char"; - rettype = debug_make_int_type (dhandle, 1, TRUE); - break; - case 6: - name = "signed char"; - rettype = debug_make_int_type (dhandle, 1, FALSE); - break; - case 7: - name = "unsigned short"; - rettype = debug_make_int_type (dhandle, 2, TRUE); - break; - case 8: - name = "unsigned int"; - rettype = debug_make_int_type (dhandle, 4, TRUE); - break; - case 9: - name = "unsigned"; - rettype = debug_make_int_type (dhandle, 4, TRUE); - case 10: - name = "unsigned long"; - rettype = debug_make_int_type (dhandle, 4, TRUE); - break; - case 11: - name = "void"; - rettype = debug_make_void_type (dhandle); - break; - case 12: - /* IEEE single precision (32 bit). */ - name = "float"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 13: - /* IEEE double precision (64 bit). */ - name = "double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 14: - /* This is an IEEE double on the RS/6000, and different machines - with different sizes for "long double" should use different - negative type numbers. See stabs.texinfo. */ - name = "long double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 15: - name = "integer"; - rettype = debug_make_int_type (dhandle, 4, FALSE); - break; - case 16: - name = "boolean"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 17: - name = "short real"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 18: - name = "real"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 19: - /* FIXME */ - name = "stringptr"; - rettype = NULL; - break; - case 20: - /* FIXME */ - name = "character"; - rettype = debug_make_int_type (dhandle, 1, TRUE); - break; - case 21: - name = "logical*1"; - rettype = debug_make_bool_type (dhandle, 1); - break; - case 22: - name = "logical*2"; - rettype = debug_make_bool_type (dhandle, 2); - break; - case 23: - name = "logical*4"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 24: - name = "logical"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 25: - /* Complex type consisting of two IEEE single precision values. */ - name = "complex"; - rettype = debug_make_complex_type (dhandle, 8); - break; - case 26: - /* Complex type consisting of two IEEE double precision values. */ - name = "double complex"; - rettype = debug_make_complex_type (dhandle, 16); - break; - case 27: - name = "integer*1"; - rettype = debug_make_int_type (dhandle, 1, FALSE); - break; - case 28: - name = "integer*2"; - rettype = debug_make_int_type (dhandle, 2, FALSE); - break; - case 29: - name = "integer*4"; - rettype = debug_make_int_type (dhandle, 4, FALSE); - break; - case 30: - /* FIXME */ - name = "wchar"; - rettype = debug_make_int_type (dhandle, 2, FALSE); - break; - case 31: - name = "long long"; - rettype = debug_make_int_type (dhandle, 8, FALSE); - break; - case 32: - name = "unsigned long long"; - rettype = debug_make_int_type (dhandle, 8, TRUE); - break; - case 33: - name = "logical*8"; - rettype = debug_make_bool_type (dhandle, 8); - break; - case 34: - name = "integer*8"; - rettype = debug_make_int_type (dhandle, 8, FALSE); - break; - default: - abort (); - } - - rettype = debug_name_type (dhandle, name, rettype); - - info->xcoff_types[-typenum] = rettype; - - return rettype; -} - -/* Find or create a tagged type. */ - -static debug_type -stab_find_tagged_type (void *dhandle, struct stab_handle *info, - const char *p, int len, enum debug_type_kind kind) -{ - char *name; - debug_type dtype; - struct stab_tag *st; - - name = savestring (p, len); - - /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same - namespace. This is right for C, and I don't know how to handle - other languages. FIXME. */ - dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL); - if (dtype != DEBUG_TYPE_NULL) - { - free (name); - return dtype; - } - - /* We need to allocate an entry on the undefined tag list. */ - for (st = info->tags; st != NULL; st = st->next) - { - if (st->name[0] == name[0] - && strcmp (st->name, name) == 0) - { - if (st->kind == DEBUG_KIND_ILLEGAL) - st->kind = kind; - free (name); - break; - } - } - if (st == NULL) - { - st = (struct stab_tag *) xmalloc (sizeof *st); - memset (st, 0, sizeof *st); - - st->next = info->tags; - st->name = name; - st->kind = kind; - st->slot = DEBUG_TYPE_NULL; - st->type = debug_make_indirect_type (dhandle, &st->slot, name); - info->tags = st; - } - - return st->type; -} - -/* In order to get the correct argument types for a stubbed method, we - need to extract the argument types from a C++ mangled string. - Since the argument types can refer back to the return type, this - means that we must demangle the entire physical name. In gdb this - is done by calling cplus_demangle and running the results back - through the C++ expression parser. Since we have no expression - parser, we must duplicate much of the work of cplus_demangle here. - - We assume that GNU style demangling is used, since this is only - done for method stubs, and only g++ should output that form of - debugging information. */ - -/* This structure is used to hold a pointer to type information which - demangling a string. */ - -struct stab_demangle_typestring -{ - /* The start of the type. This is not null terminated. */ - const char *typestring; - /* The length of the type. */ - unsigned int len; -}; - -/* This structure is used to hold information while demangling a - string. */ - -struct stab_demangle_info -{ - /* The debugging information handle. */ - void *dhandle; - /* The stab information handle. */ - struct stab_handle *info; - /* The array of arguments we are building. */ - debug_type *args; - /* Whether the method takes a variable number of arguments. */ - bfd_boolean varargs; - /* The array of types we have remembered. */ - struct stab_demangle_typestring *typestrings; - /* The number of typestrings. */ - unsigned int typestring_count; - /* The number of typestring slots we have allocated. */ - unsigned int typestring_alloc; -}; - -static void stab_bad_demangle (const char *); -static unsigned int stab_demangle_count (const char **); -static bfd_boolean stab_demangle_get_count (const char **, unsigned int *); -static bfd_boolean stab_demangle_prefix - (struct stab_demangle_info *, const char **, unsigned int); -static bfd_boolean stab_demangle_function_name - (struct stab_demangle_info *, const char **, const char *); -static bfd_boolean stab_demangle_signature - (struct stab_demangle_info *, const char **); -static bfd_boolean stab_demangle_qualified - (struct stab_demangle_info *, const char **, debug_type *); -static bfd_boolean stab_demangle_template - (struct stab_demangle_info *, const char **, char **); -static bfd_boolean stab_demangle_class - (struct stab_demangle_info *, const char **, const char **); -static bfd_boolean stab_demangle_args - (struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *); -static bfd_boolean stab_demangle_arg - (struct stab_demangle_info *, const char **, debug_type **, - unsigned int *, unsigned int *); -static bfd_boolean stab_demangle_type - (struct stab_demangle_info *, const char **, debug_type *); -static bfd_boolean stab_demangle_fund_type - (struct stab_demangle_info *, const char **, debug_type *); -static bfd_boolean stab_demangle_remember_type - (struct stab_demangle_info *, const char *, int); - -/* Warn about a bad demangling. */ - -static void -stab_bad_demangle (const char *s) -{ - fprintf (stderr, _("bad mangled name `%s'\n"), s); -} - -/* Get a count from a stab string. */ - -static unsigned int -stab_demangle_count (const char **pp) -{ - unsigned int count; - - count = 0; - while (ISDIGIT (**pp)) - { - count *= 10; - count += **pp - '0'; - ++*pp; - } - return count; -} - -/* Require a count in a string. The count may be multiple digits, in - which case it must end in an underscore. */ - -static bfd_boolean -stab_demangle_get_count (const char **pp, unsigned int *pi) -{ - if (! ISDIGIT (**pp)) - return FALSE; - - *pi = **pp - '0'; - ++*pp; - if (ISDIGIT (**pp)) - { - unsigned int count; - const char *p; - - count = *pi; - p = *pp; - do - { - count *= 10; - count += *p - '0'; - ++p; - } - while (ISDIGIT (*p)); - if (*p == '_') - { - *pp = p + 1; - *pi = count; - } - } - - return TRUE; -} - -/* This function demangles a physical name, returning a NULL - terminated array of argument types. */ - -static debug_type * -stab_demangle_argtypes (void *dhandle, struct stab_handle *info, - const char *physname, bfd_boolean *pvarargs, - unsigned int physname_len) -{ - struct stab_demangle_info minfo; - - /* Check for the g++ V3 ABI. */ - if (physname[0] == '_' && physname[1] == 'Z') - return stab_demangle_v3_argtypes (dhandle, info, physname, pvarargs); - - minfo.dhandle = dhandle; - minfo.info = info; - minfo.args = NULL; - minfo.varargs = FALSE; - minfo.typestring_alloc = 10; - minfo.typestrings = ((struct stab_demangle_typestring *) - xmalloc (minfo.typestring_alloc - * sizeof *minfo.typestrings)); - minfo.typestring_count = 0; - - /* cplus_demangle checks for special GNU mangled forms, but we can't - see any of them in mangled method argument types. */ - - if (! stab_demangle_prefix (&minfo, &physname, physname_len)) - goto error_return; - - if (*physname != '\0') - { - if (! stab_demangle_signature (&minfo, &physname)) - goto error_return; - } - - free (minfo.typestrings); - minfo.typestrings = NULL; - - if (minfo.args == NULL) - fprintf (stderr, _("no argument types in mangled string\n")); - - *pvarargs = minfo.varargs; - return minfo.args; - - error_return: - if (minfo.typestrings != NULL) - free (minfo.typestrings); - return NULL; -} - -/* Demangle the prefix of the mangled name. */ - -static bfd_boolean -stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp, - unsigned int physname_len) -{ - const char *scan; - unsigned int i; - - /* cplus_demangle checks for global constructors and destructors, - but we can't see them in mangled argument types. */ - - if (physname_len) - scan = *pp + physname_len; - else - { - /* Look for `__'. */ - scan = *pp; - do - scan = strchr (scan, '_'); - while (scan != NULL && *++scan != '_'); - - if (scan == NULL) - { - stab_bad_demangle (*pp); - return FALSE; - } - - --scan; - - /* We found `__'; move ahead to the last contiguous `__' pair. */ - i = strspn (scan, "_"); - if (i > 2) - scan += i - 2; - } - - if (scan == *pp - && (ISDIGIT (scan[2]) - || scan[2] == 'Q' - || scan[2] == 't')) - { - /* This is a GNU style constructor name. */ - *pp = scan + 2; - return TRUE; - } - else if (scan == *pp - && ! ISDIGIT (scan[2]) - && scan[2] != 't') - { - /* Look for the `__' that separates the prefix from the - signature. */ - while (*scan == '_') - ++scan; - scan = strstr (scan, "__"); - if (scan == NULL || scan[2] == '\0') - { - stab_bad_demangle (*pp); - return FALSE; - } - - return stab_demangle_function_name (minfo, pp, scan); - } - else if (scan[2] != '\0') - { - /* The name doesn't start with `__', but it does contain `__'. */ - return stab_demangle_function_name (minfo, pp, scan); - } - else - { - stab_bad_demangle (*pp); - return FALSE; - } - /*NOTREACHED*/ -} - -/* Demangle a function name prefix. The scan argument points to the - double underscore which separates the function name from the - signature. */ - -static bfd_boolean -stab_demangle_function_name (struct stab_demangle_info *minfo, - const char **pp, const char *scan) -{ - const char *name; - - /* The string from *pp to scan is the name of the function. We - don't care about the name, since we just looking for argument - types. However, for conversion operators, the name may include a - type which we must remember in order to handle backreferences. */ - - name = *pp; - *pp = scan + 2; - - if (*pp - name >= 5 - && CONST_STRNEQ (name, "type") - && (name[4] == '$' || name[4] == '.')) - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 5; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return FALSE; - } - else if (name[0] == '_' - && name[1] == '_' - && name[2] == 'o' - && name[3] == 'p') - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 4; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return FALSE; - } - - return TRUE; -} - -/* Demangle the signature. This is where the argument types are - found. */ - -static bfd_boolean -stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp) -{ - const char *orig; - bfd_boolean expect_func, func_done; - const char *hold; - - orig = *pp; - - expect_func = FALSE; - func_done = FALSE; - hold = NULL; - - while (**pp != '\0') - { - switch (**pp) - { - case 'Q': - hold = *pp; - if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return FALSE; - expect_func = TRUE; - hold = NULL; - break; - - case 'S': - /* Static member function. FIXME: Can this happen? */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case 'C': - /* Const member function. */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (hold == NULL) - hold = *pp; - if (! stab_demangle_class (minfo, pp, (const char **) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return FALSE; - expect_func = TRUE; - hold = NULL; - break; - - case 'F': - /* Function. I don't know if this actually happens with g++ - output. */ - hold = NULL; - func_done = TRUE; - ++*pp; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return FALSE; - break; - - case 't': - /* Template. */ - if (hold == NULL) - hold = *pp; - if (! stab_demangle_template (minfo, pp, (char **) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return FALSE; - hold = NULL; - expect_func = TRUE; - break; - - case '_': - /* At the outermost level, we cannot have a return type - specified, so if we run into another '_' at this point we - are dealing with a mangled name that is either bogus, or - has been mangled by some algorithm we don't know how to - deal with. So just reject the entire demangling. */ - stab_bad_demangle (orig); - return FALSE; - - default: - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = TRUE; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return FALSE; - break; - } - - if (expect_func) - { - func_done = TRUE; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return FALSE; - } - } - - if (! func_done) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added - to the current declp. */ - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return FALSE; - } - - return TRUE; -} - -/* Demangle a qualified name, such as "Q25Outer5Inner" which is the - mangled form of "Outer::Inner". */ - -static bfd_boolean -stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp, - debug_type *ptype) -{ - const char *orig; - const char *p; - unsigned int qualifiers; - debug_type context; - - orig = *pp; - - switch ((*pp)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is - preceded by an underscore (to distinguish it from the <= 9 - case) and followed by an underscore. */ - p = *pp + 2; - if (! ISDIGIT (*p) || *p == '0') - { - stab_bad_demangle (orig); - return FALSE; - } - qualifiers = atoi (p); - while (ISDIGIT (*p)) - ++p; - if (*p != '_') - { - stab_bad_demangle (orig); - return FALSE; - } - *pp = p + 1; - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - qualifiers = (*pp)[1] - '0'; - /* Skip an optional underscore after the count. */ - if ((*pp)[2] == '_') - ++*pp; - *pp += 2; - break; - - case '0': - default: - stab_bad_demangle (orig); - return FALSE; - } - - context = DEBUG_TYPE_NULL; - - /* Pick off the names. */ - while (qualifiers-- > 0) - { - if (**pp == '_') - ++*pp; - if (**pp == 't') - { - char *name; - - if (! stab_demangle_template (minfo, pp, - ptype != NULL ? &name : NULL)) - return FALSE; - - if (ptype != NULL) - { - context = stab_find_tagged_type (minfo->dhandle, minfo->info, - name, strlen (name), - DEBUG_KIND_CLASS); - free (name); - if (context == DEBUG_TYPE_NULL) - return FALSE; - } - } - else - { - unsigned int len; - - len = stab_demangle_count (pp); - if (strlen (*pp) < len) - { - stab_bad_demangle (orig); - return FALSE; - } - - if (ptype != NULL) - { - const debug_field *fields; - - fields = NULL; - if (context != DEBUG_TYPE_NULL) - fields = debug_get_fields (minfo->dhandle, context); - - context = DEBUG_TYPE_NULL; - - if (fields != NULL) - { - char *name; - - /* Try to find the type by looking through the - fields of context until we find a field with the - same type. This ought to work for a class - defined within a class, but it won't work for, - e.g., an enum defined within a class. stabs does - not give us enough information to figure out the - latter case. */ - - name = savestring (*pp, len); - - for (; *fields != DEBUG_FIELD_NULL; fields++) - { - debug_type ft; - const char *dn; - - ft = debug_get_field_type (minfo->dhandle, *fields); - if (ft == NULL) - { - free (name); - return FALSE; - } - dn = debug_get_type_name (minfo->dhandle, ft); - if (dn != NULL && strcmp (dn, name) == 0) - { - context = ft; - break; - } - } - - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - /* We have to fall back on finding the type by name. - If there are more types to come, then this must - be a class. Otherwise, it could be anything. */ - - if (qualifiers == 0) - { - char *name; - - name = savestring (*pp, len); - context = debug_find_named_type (minfo->dhandle, - name); - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - context = stab_find_tagged_type (minfo->dhandle, - minfo->info, - *pp, len, - (qualifiers == 0 - ? DEBUG_KIND_ILLEGAL - : DEBUG_KIND_CLASS)); - if (context == DEBUG_TYPE_NULL) - return FALSE; - } - } - } - - *pp += len; - } - } - - if (ptype != NULL) - *ptype = context; - - return TRUE; -} - -/* Demangle a template. If PNAME is not NULL, this sets *PNAME to a - string representation of the template. */ - -static bfd_boolean -stab_demangle_template (struct stab_demangle_info *minfo, const char **pp, - char **pname) -{ - const char *orig; - unsigned int r, i; - - orig = *pp; - - ++*pp; - - /* Skip the template name. */ - r = stab_demangle_count (pp); - if (r == 0 || strlen (*pp) < r) - { - stab_bad_demangle (orig); - return FALSE; - } - *pp += r; - - /* Get the size of the parameter list. */ - if (stab_demangle_get_count (pp, &r) == 0) - { - stab_bad_demangle (orig); - return FALSE; - } - - for (i = 0; i < r; i++) - { - if (**pp == 'Z') - { - /* This is a type parameter. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return FALSE; - } - else - { - const char *old_p; - bfd_boolean pointerp, realp, integralp, charp, boolp; - bfd_boolean done; - - old_p = *pp; - pointerp = FALSE; - realp = FALSE; - integralp = FALSE; - charp = FALSE; - boolp = FALSE; - done = FALSE; - - /* This is a value parameter. */ - - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return FALSE; - - while (*old_p != '\0' && ! done) - { - switch (*old_p) - { - case 'P': - case 'p': - case 'R': - pointerp = TRUE; - done = TRUE; - break; - case 'C': /* Const. */ - case 'S': /* Signed. */ - case 'U': /* Unsigned. */ - case 'V': /* Volatile. */ - case 'F': /* Function. */ - case 'M': /* Member function. */ - case 'O': /* ??? */ - ++old_p; - break; - case 'Q': /* Qualified name. */ - integralp = TRUE; - done = TRUE; - break; - case 'T': /* Remembered type. */ - abort (); - case 'v': /* Void. */ - abort (); - case 'x': /* Long long. */ - case 'l': /* Long. */ - case 'i': /* Int. */ - case 's': /* Short. */ - case 'w': /* Wchar_t. */ - integralp = TRUE; - done = TRUE; - break; - case 'b': /* Bool. */ - boolp = TRUE; - done = TRUE; - break; - case 'c': /* Char. */ - charp = TRUE; - done = TRUE; - break; - case 'r': /* Long double. */ - case 'd': /* Double. */ - case 'f': /* Float. */ - realp = TRUE; - done = TRUE; - break; - default: - /* Assume it's a user defined integral type. */ - integralp = TRUE; - done = TRUE; - break; - } - } - - if (integralp) - { - if (**pp == 'm') - ++*pp; - while (ISDIGIT (**pp)) - ++*pp; - } - else if (charp) - { - unsigned int val; - - if (**pp == 'm') - ++*pp; - val = stab_demangle_count (pp); - if (val == 0) - { - stab_bad_demangle (orig); - return FALSE; - } - } - else if (boolp) - { - unsigned int val; - - val = stab_demangle_count (pp); - if (val != 0 && val != 1) - { - stab_bad_demangle (orig); - return FALSE; - } - } - else if (realp) - { - if (**pp == 'm') - ++*pp; - while (ISDIGIT (**pp)) - ++*pp; - if (**pp == '.') - { - ++*pp; - while (ISDIGIT (**pp)) - ++*pp; - } - if (**pp == 'e') - { - ++*pp; - while (ISDIGIT (**pp)) - ++*pp; - } - } - else if (pointerp) - { - unsigned int len; - - len = stab_demangle_count (pp); - if (len == 0) - { - stab_bad_demangle (orig); - return FALSE; - } - *pp += len; - } - } - } - - /* We can translate this to a string fairly easily by invoking the - regular demangling routine. */ - if (pname != NULL) - { - char *s1, *s2, *s3, *s4 = NULL; - char *from, *to; - - s1 = savestring (orig, *pp - orig); - - s2 = concat ("NoSuchStrinG__", s1, (const char *) NULL); - - free (s1); - - s3 = cplus_demangle (s2, DMGL_ANSI); - - free (s2); - - if (s3 != NULL) - s4 = strstr (s3, "::NoSuchStrinG"); - if (s3 == NULL || s4 == NULL) - { - stab_bad_demangle (orig); - if (s3 != NULL) - free (s3); - return FALSE; - } - - /* Eliminating all spaces, except those between > characters, - makes it more likely that the demangled name will match the - name which g++ used as the structure name. */ - for (from = to = s3; from != s4; ++from) - if (*from != ' ' - || (from[1] == '>' && from > s3 && from[-1] == '>')) - *to++ = *from; - - *pname = savestring (s3, to - s3); - - free (s3); - } - - return TRUE; -} - -/* Demangle a class name. */ - -static bfd_boolean -stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED, - const char **pp, const char **pstart) -{ - const char *orig; - unsigned int n; - - orig = *pp; - - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return FALSE; - } - - if (pstart != NULL) - *pstart = *pp; - - *pp += n; - - return TRUE; -} - -/* Demangle function arguments. If the pargs argument is not NULL, it - is set to a NULL terminated array holding the arguments. */ - -static bfd_boolean -stab_demangle_args (struct stab_demangle_info *minfo, const char **pp, - debug_type **pargs, bfd_boolean *pvarargs) -{ - const char *orig; - unsigned int alloc, count; - - orig = *pp; - - alloc = 10; - if (pargs != NULL) - { - *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs); - *pvarargs = FALSE; - } - count = 0; - - while (**pp != '_' && **pp != '\0' && **pp != 'e') - { - if (**pp == 'N' || **pp == 'T') - { - char temptype; - unsigned int r, t; - - temptype = **pp; - ++*pp; - - if (temptype == 'T') - r = 1; - else - { - if (! stab_demangle_get_count (pp, &r)) - { - stab_bad_demangle (orig); - return FALSE; - } - } - - if (! stab_demangle_get_count (pp, &t)) - { - stab_bad_demangle (orig); - return FALSE; - } - - if (t >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return FALSE; - } - while (r-- > 0) - { - const char *tem; - - tem = minfo->typestrings[t].typestring; - if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc)) - return FALSE; - } - } - else - { - if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc)) - return FALSE; - } - } - - if (pargs != NULL) - (*pargs)[count] = DEBUG_TYPE_NULL; - - if (**pp == 'e') - { - if (pargs != NULL) - *pvarargs = TRUE; - ++*pp; - } - - return TRUE; -} - -/* Demangle a single argument. */ - -static bfd_boolean -stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp, - debug_type **pargs, unsigned int *pcount, - unsigned int *palloc) -{ - const char *start; - debug_type type; - - start = *pp; - if (! stab_demangle_type (minfo, pp, - pargs == NULL ? (debug_type *) NULL : &type) - || ! stab_demangle_remember_type (minfo, start, *pp - start)) - return FALSE; - - if (pargs != NULL) - { - if (type == DEBUG_TYPE_NULL) - return FALSE; - - if (*pcount + 1 >= *palloc) - { - *palloc += 10; - *pargs = ((debug_type *) - xrealloc (*pargs, *palloc * sizeof **pargs)); - } - (*pargs)[*pcount] = type; - ++*pcount; - } - - return TRUE; -} - -/* Demangle a type. If the ptype argument is not NULL, *ptype is set - to the newly allocated type. */ - -static bfd_boolean -stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, - debug_type *ptype) -{ - const char *orig; - - orig = *pp; - - switch (**pp) - { - case 'P': - case 'p': - /* A pointer type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - if (ptype != NULL) - *ptype = debug_make_pointer_type (minfo->dhandle, *ptype); - break; - - case 'R': - /* A reference type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - if (ptype != NULL) - *ptype = debug_make_reference_type (minfo->dhandle, *ptype); - break; - - case 'A': - /* An array. */ - { - unsigned long high; - - ++*pp; - high = 0; - while (**pp != '\0' && **pp != '_') - { - if (! ISDIGIT (**pp)) - { - stab_bad_demangle (orig); - return FALSE; - } - high *= 10; - high += **pp - '0'; - ++*pp; - } - if (**pp != '_') - { - stab_bad_demangle (orig); - return FALSE; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - if (ptype != NULL) - { - debug_type int_type; - - int_type = debug_find_named_type (minfo->dhandle, "int"); - if (int_type == NULL) - int_type = debug_make_int_type (minfo->dhandle, 4, FALSE); - *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type, - 0, high, FALSE); - } - } - break; - - case 'T': - /* A back reference to a remembered type. */ - { - unsigned int i; - const char *p; - - ++*pp; - if (! stab_demangle_get_count (pp, &i)) - { - stab_bad_demangle (orig); - return FALSE; - } - if (i >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return FALSE; - } - p = minfo->typestrings[i].typestring; - if (! stab_demangle_type (minfo, &p, ptype)) - return FALSE; - } - break; - - case 'F': - /* A function. */ - { - debug_type *args; - bfd_boolean varargs; - - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (bfd_boolean *) NULL - : &varargs))) - return FALSE; - if (**pp != '_') - { - /* cplus_demangle will accept a function without a return - type, but I don't know when that will happen, or what - to do if it does. */ - stab_bad_demangle (orig); - return FALSE; - } - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - if (ptype != NULL) - *ptype = debug_make_function_type (minfo->dhandle, *ptype, args, - varargs); - - } - break; - - case 'M': - case 'O': - { - bfd_boolean memberp; - debug_type class_type = DEBUG_TYPE_NULL; - debug_type *args; - bfd_boolean varargs; - unsigned int n; - const char *name; - - memberp = **pp == 'M'; - args = NULL; - varargs = FALSE; - - ++*pp; - if (ISDIGIT (**pp)) - { - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return FALSE; - } - name = *pp; - *pp += n; - - if (ptype != NULL) - { - class_type = stab_find_tagged_type (minfo->dhandle, - minfo->info, - name, (int) n, - DEBUG_KIND_CLASS); - if (class_type == DEBUG_TYPE_NULL) - return FALSE; - } - } - else if (**pp == 'Q') - { - if (! stab_demangle_qualified (minfo, pp, - (ptype == NULL - ? (debug_type *) NULL - : &class_type))) - return FALSE; - } - else - { - stab_bad_demangle (orig); - return FALSE; - } - - if (memberp) - { - if (**pp == 'C') - { - ++*pp; - } - else if (**pp == 'V') - { - ++*pp; - } - if (**pp != 'F') - { - stab_bad_demangle (orig); - return FALSE; - } - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (bfd_boolean *) NULL - : &varargs))) - return FALSE; - } - - if (**pp != '_') - { - stab_bad_demangle (orig); - return FALSE; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - - if (ptype != NULL) - { - if (! memberp) - *ptype = debug_make_offset_type (minfo->dhandle, class_type, - *ptype); - else - { - /* FIXME: We have no way to record constp or - volatilep. */ - *ptype = debug_make_method_type (minfo->dhandle, *ptype, - class_type, args, varargs); - } - } - } - break; - - case 'G': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - break; - - case 'C': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return FALSE; - if (ptype != NULL) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - break; - - case 'Q': - { - if (! stab_demangle_qualified (minfo, pp, ptype)) - return FALSE; - } - break; - - default: - if (! stab_demangle_fund_type (minfo, pp, ptype)) - return FALSE; - break; - } - - return TRUE; -} - -/* Demangle a fundamental type. If the ptype argument is not NULL, - *ptype is set to the newly allocated type. */ - -static bfd_boolean -stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp, - debug_type *ptype) -{ - const char *orig; - bfd_boolean constp, volatilep, unsignedp, signedp; - bfd_boolean done; - - orig = *pp; - - constp = FALSE; - volatilep = FALSE; - unsignedp = FALSE; - signedp = FALSE; - - done = FALSE; - while (! done) - { - switch (**pp) - { - case 'C': - constp = TRUE; - ++*pp; - break; - - case 'U': - unsignedp = TRUE; - ++*pp; - break; - - case 'S': - signedp = TRUE; - ++*pp; - break; - - case 'V': - volatilep = TRUE; - ++*pp; - break; - - default: - done = TRUE; - break; - } - } - - switch (**pp) - { - case '\0': - case '_': - /* cplus_demangle permits this, but I don't know what it means. */ - stab_bad_demangle (orig); - break; - - case 'v': /* void */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "void"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_void_type (minfo->dhandle); - } - ++*pp; - break; - - case 'x': /* long long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long long unsigned int" - : "long long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp); - } - ++*pp; - break; - - case 'l': /* long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long unsigned int" - : "long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 'i': /* int */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned int" - : "int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 's': /* short */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "short unsigned int" - : "short int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp); - } - ++*pp; - break; - - case 'b': /* bool */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "bool"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_bool_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'c': /* char */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned char" - : (signedp - ? "signed char" - : "char"))); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp); - } - ++*pp; - break; - - case 'w': /* wchar_t */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, TRUE); - } - ++*pp; - break; - - case 'r': /* long double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "long double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'd': /* double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'f': /* float */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "float"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'G': - ++*pp; - if (! ISDIGIT (**pp)) - { - stab_bad_demangle (orig); - return FALSE; - } - /* Fall through. */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - const char *hold; - - if (! stab_demangle_class (minfo, pp, &hold)) - return FALSE; - if (ptype != NULL) - { - char *name; - - name = savestring (hold, *pp - hold); - *ptype = debug_find_named_type (minfo->dhandle, name); - free (name); - if (*ptype == DEBUG_TYPE_NULL) - { - /* FIXME: It is probably incorrect to assume that - undefined types are tagged types. */ - *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info, - hold, *pp - hold, - DEBUG_KIND_ILLEGAL); - if (*ptype == DEBUG_TYPE_NULL) - return FALSE; - } - } - } - break; - - case 't': - { - char *name; - - if (! stab_demangle_template (minfo, pp, - ptype != NULL ? &name : NULL)) - return FALSE; - if (ptype != NULL) - { - *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info, - name, strlen (name), - DEBUG_KIND_CLASS); - free (name); - if (*ptype == DEBUG_TYPE_NULL) - return FALSE; - } - } - break; - - default: - stab_bad_demangle (orig); - return FALSE; - } - - if (ptype != NULL) - { - if (constp) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - if (volatilep) - *ptype = debug_make_volatile_type (minfo->dhandle, *ptype); - } - - return TRUE; -} - -/* Remember a type string in a demangled string. */ - -static bfd_boolean -stab_demangle_remember_type (struct stab_demangle_info *minfo, - const char *p, int len) -{ - if (minfo->typestring_count >= minfo->typestring_alloc) - { - minfo->typestring_alloc += 10; - minfo->typestrings = ((struct stab_demangle_typestring *) - xrealloc (minfo->typestrings, - (minfo->typestring_alloc - * sizeof *minfo->typestrings))); - } - - minfo->typestrings[minfo->typestring_count].typestring = p; - minfo->typestrings[minfo->typestring_count].len = (unsigned int) len; - ++minfo->typestring_count; - - return TRUE; -} - -/* Demangle names encoded using the g++ V3 ABI. The newer versions of - g++ which use this ABI do not encode ordinary method argument types - in a mangled name; they simply output the argument types. However, - for a static method, g++ simply outputs the return type and the - physical name. So in that case we need to demangle the name here. - Here PHYSNAME is the physical name of the function, and we set the - variable pointed at by PVARARGS to indicate whether this function - is varargs. This returns NULL, or a NULL terminated array of - argument types. */ - -static debug_type * -stab_demangle_v3_argtypes (void *dhandle, struct stab_handle *info, - const char *physname, bfd_boolean *pvarargs) -{ - struct demangle_component *dc; - void *mem; - debug_type *pargs; - - dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | DMGL_ANSI, &mem); - if (dc == NULL) - { - stab_bad_demangle (physname); - return NULL; - } - - /* We expect to see TYPED_NAME, and the right subtree describes the - function type. */ - if (dc->type != DEMANGLE_COMPONENT_TYPED_NAME - || dc->u.s_binary.right->type != DEMANGLE_COMPONENT_FUNCTION_TYPE) - { - fprintf (stderr, _("Demangled name is not a function\n")); - free (mem); - return NULL; - } - - pargs = stab_demangle_v3_arglist (dhandle, info, - dc->u.s_binary.right->u.s_binary.right, - pvarargs); - - free (mem); - - return pargs; -} - -/* Demangle an argument list in a struct demangle_component tree. - Returns a DEBUG_TYPE_NULL terminated array of argument types, and - sets *PVARARGS to indicate whether this is a varargs function. */ - -static debug_type * -stab_demangle_v3_arglist (void *dhandle, struct stab_handle *info, - struct demangle_component *arglist, - bfd_boolean *pvarargs) -{ - struct demangle_component *dc; - unsigned int alloc, count; - debug_type *pargs; - - alloc = 10; - pargs = (debug_type *) xmalloc (alloc * sizeof *pargs); - *pvarargs = FALSE; - - count = 0; - - for (dc = arglist; - dc != NULL; - dc = dc->u.s_binary.right) - { - debug_type arg; - bfd_boolean varargs; - - if (dc->type != DEMANGLE_COMPONENT_ARGLIST) - { - fprintf (stderr, _("Unexpected type in v3 arglist demangling\n")); - free (pargs); - return NULL; - } - - arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, - NULL, &varargs); - if (arg == NULL) - { - if (varargs) - { - *pvarargs = TRUE; - continue; - } - free (pargs); - return NULL; - } - - if (count + 1 >= alloc) - { - alloc += 10; - pargs = (debug_type *) xrealloc (pargs, alloc * sizeof *pargs); - } - - pargs[count] = arg; - ++count; - } - - pargs[count] = DEBUG_TYPE_NULL; - - return pargs; -} - -/* Convert a struct demangle_component tree describing an argument - type into a debug_type. */ - -static debug_type -stab_demangle_v3_arg (void *dhandle, struct stab_handle *info, - struct demangle_component *dc, debug_type context, - bfd_boolean *pvarargs) -{ - debug_type dt; - - if (pvarargs != NULL) - *pvarargs = FALSE; - - switch (dc->type) - { - /* FIXME: These are demangle component types which we probably - need to handle one way or another. */ - case DEMANGLE_COMPONENT_LOCAL_NAME: - case DEMANGLE_COMPONENT_TYPED_NAME: - case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - case DEMANGLE_COMPONENT_CTOR: - case DEMANGLE_COMPONENT_DTOR: - case DEMANGLE_COMPONENT_JAVA_CLASS: - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: - case DEMANGLE_COMPONENT_COMPLEX: - case DEMANGLE_COMPONENT_IMAGINARY: - case DEMANGLE_COMPONENT_VENDOR_TYPE: - case DEMANGLE_COMPONENT_ARRAY_TYPE: - case DEMANGLE_COMPONENT_PTRMEM_TYPE: - case DEMANGLE_COMPONENT_ARGLIST: - default: - fprintf (stderr, _("Unrecognized demangle component %d\n"), - (int) dc->type); - return NULL; - - case DEMANGLE_COMPONENT_NAME: - if (context != NULL) - { - const debug_field *fields; - - fields = debug_get_fields (dhandle, context); - if (fields != NULL) - { - /* Try to find this type by looking through the context - class. */ - for (; *fields != DEBUG_FIELD_NULL; fields++) - { - debug_type ft; - const char *dn; - - ft = debug_get_field_type (dhandle, *fields); - if (ft == NULL) - return NULL; - dn = debug_get_type_name (dhandle, ft); - if (dn != NULL - && (int) strlen (dn) == dc->u.s_name.len - && strncmp (dn, dc->u.s_name.s, dc->u.s_name.len) == 0) - return ft; - } - } - } - return stab_find_tagged_type (dhandle, info, dc->u.s_name.s, - dc->u.s_name.len, DEBUG_KIND_ILLEGAL); - - case DEMANGLE_COMPONENT_QUAL_NAME: - context = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, - context, NULL); - if (context == NULL) - return NULL; - return stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.right, - context, NULL); - - case DEMANGLE_COMPONENT_TEMPLATE: - { - char *p; - size_t alc; - - /* We print this component to get a class name which we can - use. FIXME: This probably won't work if the template uses - template parameters which refer to an outer template. */ - p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc); - if (p == NULL) - { - fprintf (stderr, _("Failed to print demangled template\n")); - return NULL; - } - dt = stab_find_tagged_type (dhandle, info, p, strlen (p), - DEBUG_KIND_CLASS); - free (p); - return dt; - } - - case DEMANGLE_COMPONENT_SUB_STD: - return stab_find_tagged_type (dhandle, info, dc->u.s_string.string, - dc->u.s_string.len, DEBUG_KIND_ILLEGAL); - - case DEMANGLE_COMPONENT_RESTRICT: - case DEMANGLE_COMPONENT_VOLATILE: - case DEMANGLE_COMPONENT_CONST: - case DEMANGLE_COMPONENT_POINTER: - case DEMANGLE_COMPONENT_REFERENCE: - dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL, - NULL); - if (dt == NULL) - return NULL; - - switch (dc->type) - { - default: - abort (); - case DEMANGLE_COMPONENT_RESTRICT: - /* FIXME: We have no way to represent restrict. */ - return dt; - case DEMANGLE_COMPONENT_VOLATILE: - return debug_make_volatile_type (dhandle, dt); - case DEMANGLE_COMPONENT_CONST: - return debug_make_const_type (dhandle, dt); - case DEMANGLE_COMPONENT_POINTER: - return debug_make_pointer_type (dhandle, dt); - case DEMANGLE_COMPONENT_REFERENCE: - return debug_make_reference_type (dhandle, dt); - } - - case DEMANGLE_COMPONENT_FUNCTION_TYPE: - { - debug_type *pargs; - bfd_boolean varargs; - - if (dc->u.s_binary.left == NULL) - { - /* In this case the return type is actually unknown. - However, I'm not sure this will ever arise in practice; - normally an unknown return type would only appear at - the top level, which is handled above. */ - dt = debug_make_void_type (dhandle); - } - else - dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL, - NULL); - if (dt == NULL) - return NULL; - - pargs = stab_demangle_v3_arglist (dhandle, info, - dc->u.s_binary.right, - &varargs); - if (pargs == NULL) - return NULL; - - return debug_make_function_type (dhandle, dt, pargs, varargs); - } - - case DEMANGLE_COMPONENT_BUILTIN_TYPE: - { - char *p; - size_t alc; - debug_type ret; - - /* We print this component in order to find out the type name. - FIXME: Should we instead expose the - demangle_builtin_type_info structure? */ - p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc); - if (p == NULL) - { - fprintf (stderr, _("Couldn't get demangled builtin type\n")); - return NULL; - } - - /* The mangling is based on the type, but does not itself - indicate what the sizes are. So we have to guess. */ - if (strcmp (p, "signed char") == 0) - ret = debug_make_int_type (dhandle, 1, FALSE); - else if (strcmp (p, "bool") == 0) - ret = debug_make_bool_type (dhandle, 1); - else if (strcmp (p, "char") == 0) - ret = debug_make_int_type (dhandle, 1, FALSE); - else if (strcmp (p, "double") == 0) - ret = debug_make_float_type (dhandle, 8); - else if (strcmp (p, "long double") == 0) - ret = debug_make_float_type (dhandle, 8); - else if (strcmp (p, "float") == 0) - ret = debug_make_float_type (dhandle, 4); - else if (strcmp (p, "__float128") == 0) - ret = debug_make_float_type (dhandle, 16); - else if (strcmp (p, "unsigned char") == 0) - ret = debug_make_int_type (dhandle, 1, TRUE); - else if (strcmp (p, "int") == 0) - ret = debug_make_int_type (dhandle, 4, FALSE); - else if (strcmp (p, "unsigned int") == 0) - ret = debug_make_int_type (dhandle, 4, TRUE); - else if (strcmp (p, "long") == 0) - ret = debug_make_int_type (dhandle, 4, FALSE); - else if (strcmp (p, "unsigned long") == 0) - ret = debug_make_int_type (dhandle, 4, TRUE); - else if (strcmp (p, "__int128") == 0) - ret = debug_make_int_type (dhandle, 16, FALSE); - else if (strcmp (p, "unsigned __int128") == 0) - ret = debug_make_int_type (dhandle, 16, TRUE); - else if (strcmp (p, "short") == 0) - ret = debug_make_int_type (dhandle, 2, FALSE); - else if (strcmp (p, "unsigned short") == 0) - ret = debug_make_int_type (dhandle, 2, TRUE); - else if (strcmp (p, "void") == 0) - ret = debug_make_void_type (dhandle); - else if (strcmp (p, "wchar_t") == 0) - ret = debug_make_int_type (dhandle, 4, TRUE); - else if (strcmp (p, "long long") == 0) - ret = debug_make_int_type (dhandle, 8, FALSE); - else if (strcmp (p, "unsigned long long") == 0) - ret = debug_make_int_type (dhandle, 8, TRUE); - else if (strcmp (p, "...") == 0) - { - if (pvarargs == NULL) - fprintf (stderr, _("Unexpected demangled varargs\n")); - else - *pvarargs = TRUE; - ret = NULL; - } - else - { - fprintf (stderr, _("Unrecognized demangled builtin type\n")); - ret = NULL; - } - - free (p); - - return ret; - } - } -} diff --git a/contrib/binutils-2.22/binutils/strings.c b/contrib/binutils-2.22/binutils/strings.c deleted file mode 100644 index 4763512fb7..0000000000 --- a/contrib/binutils-2.22/binutils/strings.c +++ /dev/null @@ -1,669 +0,0 @@ -/* strings -- print the strings of printable characters in files - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 - Free Software Foundation, Inc. - - 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, 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. */ - -/* Usage: strings [options] file... - - Options: - --all - -a - - Do not scan only the initialized data section of object files. - - --print-file-name - -f Print the name of the file before each string. - - --bytes=min-len - -n min-len - -min-len Print graphic char sequences, MIN-LEN or more bytes long, - that are followed by a NUL or a newline. Default is 4. - - --radix={o,x,d} - -t {o,x,d} Print the offset within the file before each string, - in octal/hex/decimal. - - -o Like -to. (Some other implementations have -o like -to, - others like -td. We chose one arbitrarily.) - - --encoding={s,S,b,l,B,L} - -e {s,S,b,l,B,L} - Select character encoding: 7-bit-character, 8-bit-character, - bigendian 16-bit, littleendian 16-bit, bigendian 32-bit, - littleendian 32-bit. - - --target=BFDNAME - -T {bfdname} - Specify a non-default object file format. - - --help - -h Print the usage message on the standard output. - - --version - -V - -v Print the program version number. - - Written by Richard Stallman - and David MacKenzie . */ - -#include "sysdep.h" -#include "bfd.h" -#include "getopt.h" -#include "libiberty.h" -#include "safe-ctype.h" -#include -#include "bucomm.h" - -#define STRING_ISGRAPHIC(c) \ - ( (c) >= 0 \ - && (c) <= 255 \ - && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127))) - -#ifndef errno -extern int errno; -#endif - -/* The BFD section flags that identify an initialized data section. */ -#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS) - -/* Radix for printing addresses (must be 8, 10 or 16). */ -static int address_radix; - -/* Minimum length of sequence of graphic chars to trigger output. */ -static int string_min; - -/* TRUE means print address within file for each string. */ -static bfd_boolean print_addresses; - -/* TRUE means print filename for each string. */ -static bfd_boolean print_filenames; - -/* TRUE means for object files scan only the data section. */ -static bfd_boolean datasection_only; - -/* TRUE if we found an initialized data section in the current file. */ -static bfd_boolean got_a_section; - -/* The BFD object file format. */ -static char *target; - -/* The character encoding format. */ -static char encoding; -static int encoding_bytes; - -static struct option long_options[] = -{ - {"all", no_argument, NULL, 'a'}, - {"print-file-name", no_argument, NULL, 'f'}, - {"bytes", required_argument, NULL, 'n'}, - {"radix", required_argument, NULL, 't'}, - {"encoding", required_argument, NULL, 'e'}, - {"target", required_argument, NULL, 'T'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, 0, NULL, 0} -}; - -/* Records the size of a named file so that we - do not repeatedly run bfd_stat() on it. */ - -typedef struct -{ - const char * filename; - bfd_size_type filesize; -} filename_and_size_t; - -static void strings_a_section (bfd *, asection *, void *); -static bfd_boolean strings_object_file (const char *); -static bfd_boolean strings_file (char *file); -static void print_strings (const char *, FILE *, file_ptr, int, int, char *); -static void usage (FILE *, int); -static long get_char (FILE *, file_ptr *, int *, char **); - -int main (int, char **); - -int -main (int argc, char **argv) -{ - int optc; - int exit_status = 0; - bfd_boolean files_given = FALSE; - char *s; - int numeric_opt = 0; - -#if defined (HAVE_SETLOCALE) - setlocale (LC_ALL, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - program_name = argv[0]; - xmalloc_set_program_name (program_name); - - expandargv (&argc, &argv); - - string_min = 4; - print_addresses = FALSE; - print_filenames = FALSE; - datasection_only = TRUE; - target = NULL; - encoding = 's'; - - while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789", - long_options, (int *) 0)) != EOF) - { - switch (optc) - { - case 'a': - datasection_only = FALSE; - break; - - case 'f': - print_filenames = TRUE; - break; - - case 'H': - case 'h': - usage (stdout, 0); - - case 'n': - string_min = (int) strtoul (optarg, &s, 0); - if (s != NULL && *s != 0) - fatal (_("invalid integer argument %s"), optarg); - break; - - case 'o': - print_addresses = TRUE; - address_radix = 8; - break; - - case 't': - print_addresses = TRUE; - if (optarg[1] != '\0') - usage (stderr, 1); - switch (optarg[0]) - { - case 'o': - address_radix = 8; - break; - - case 'd': - address_radix = 10; - break; - - case 'x': - address_radix = 16; - break; - - default: - usage (stderr, 1); - } - break; - - case 'T': - target = optarg; - break; - - case 'e': - if (optarg[1] != '\0') - usage (stderr, 1); - encoding = optarg[0]; - break; - - case 'V': - case 'v': - print_version ("strings"); - break; - - case '?': - usage (stderr, 1); - - default: - numeric_opt = optind; - break; - } - } - - if (numeric_opt != 0) - { - string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0); - if (s != NULL && *s != 0) - fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1); - } - if (string_min < 1) - fatal (_("invalid minimum string length %d"), string_min); - - switch (encoding) - { - case 'S': - case 's': - encoding_bytes = 1; - break; - case 'b': - case 'l': - encoding_bytes = 2; - break; - case 'B': - case 'L': - encoding_bytes = 4; - break; - default: - usage (stderr, 1); - } - - bfd_init (); - set_default_bfd_target (); - - if (optind >= argc) - { - datasection_only = FALSE; - SET_BINARY (fileno (stdin)); - print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL); - files_given = TRUE; - } - else - { - for (; optind < argc; ++optind) - { - if (strcmp (argv[optind], "-") == 0) - datasection_only = FALSE; - else - { - files_given = TRUE; - exit_status |= strings_file (argv[optind]) == FALSE; - } - } - } - - if (!files_given) - usage (stderr, 1); - - return (exit_status); -} - -/* Scan section SECT of the file ABFD, whose printable name is in - ARG->filename and whose size might be in ARG->filesize. If it - contains initialized data set `got_a_section' and print the - strings in it. - - FIXME: We ought to be able to return error codes/messages for - certain conditions. */ - -static void -strings_a_section (bfd *abfd, asection *sect, void *arg) -{ - filename_and_size_t * filename_and_sizep; - bfd_size_type *filesizep; - bfd_size_type sectsize; - void *mem; - - if ((sect->flags & DATA_FLAGS) != DATA_FLAGS) - return; - - sectsize = bfd_get_section_size (sect); - - if (sectsize <= 0) - return; - - /* Get the size of the file. This might have been cached for us. */ - filename_and_sizep = (filename_and_size_t *) arg; - filesizep = & filename_and_sizep->filesize; - - if (*filesizep == 0) - { - struct stat st; - - if (bfd_stat (abfd, &st)) - return; - - /* Cache the result so that we do not repeatedly stat this file. */ - *filesizep = st.st_size; - } - - /* Compare the size of the section against the size of the file. - If the section is bigger then the file must be corrupt and - we should not try dumping it. */ - if (sectsize >= *filesizep) - return; - - mem = xmalloc (sectsize); - - if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize)) - { - got_a_section = TRUE; - - print_strings (filename_and_sizep->filename, NULL, sect->filepos, - 0, sectsize, (char *) mem); - } - - free (mem); -} - -/* Scan all of the sections in FILE, and print the strings - in the initialized data section(s). - - Return TRUE if successful, - FALSE if not (such as if FILE is not an object file). */ - -static bfd_boolean -strings_object_file (const char *file) -{ - filename_and_size_t filename_and_size; - bfd *abfd; - - abfd = bfd_openr (file, target); - - if (abfd == NULL) - /* Treat the file as a non-object file. */ - return FALSE; - - /* This call is mainly for its side effect of reading in the sections. - We follow the traditional behavior of `strings' in that we don't - complain if we don't recognize a file to be an object file. */ - if (!bfd_check_format (abfd, bfd_object)) - { - bfd_close (abfd); - return FALSE; - } - - got_a_section = FALSE; - filename_and_size.filename = file; - filename_and_size.filesize = 0; - bfd_map_over_sections (abfd, strings_a_section, & filename_and_size); - - if (!bfd_close (abfd)) - { - bfd_nonfatal (file); - return FALSE; - } - - return got_a_section; -} - -/* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */ - -static bfd_boolean -strings_file (char *file) -{ - struct stat st; - - /* get_file_size does not support non-S_ISREG files. */ - - if (stat (file, &st) < 0) - { - if (errno == ENOENT) - non_fatal (_("'%s': No such file"), file); - else - non_fatal (_("Warning: could not locate '%s'. reason: %s"), - file, strerror (errno)); - return FALSE; - } - - /* If we weren't told to scan the whole file, - try to open it as an object file and only look at - initialized data sections. If that fails, fall back to the - whole file. */ - if (!datasection_only || !strings_object_file (file)) - { - FILE *stream; - - stream = fopen (file, FOPEN_RB); - if (stream == NULL) - { - fprintf (stderr, "%s: ", program_name); - perror (file); - return FALSE; - } - - print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0); - - if (fclose (stream) == EOF) - { - fprintf (stderr, "%s: ", program_name); - perror (file); - return FALSE; - } - } - - return TRUE; -} - -/* Read the next character, return EOF if none available. - Assume that STREAM is positioned so that the next byte read - is at address ADDRESS in the file. - - If STREAM is NULL, do not read from it. - The caller can supply a buffer of characters - to be processed before the data in STREAM. - MAGIC is the address of the buffer and - MAGICCOUNT is how many characters are in it. */ - -static long -get_char (FILE *stream, file_ptr *address, int *magiccount, char **magic) -{ - int c, i; - long r = EOF; - unsigned char buf[4]; - - for (i = 0; i < encoding_bytes; i++) - { - if (*magiccount) - { - (*magiccount)--; - c = *(*magic)++; - } - else - { - if (stream == NULL) - return EOF; - - /* Only use getc_unlocked if we found a declaration for it. - Otherwise, libc is not thread safe by default, and we - should not use it. */ - -#if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED - c = getc_unlocked (stream); -#else - c = getc (stream); -#endif - if (c == EOF) - return EOF; - } - - (*address)++; - buf[i] = c; - } - - switch (encoding) - { - case 'S': - case 's': - r = buf[0]; - break; - case 'b': - r = (buf[0] << 8) | buf[1]; - break; - case 'l': - r = buf[0] | (buf[1] << 8); - break; - case 'B': - r = ((long) buf[0] << 24) | ((long) buf[1] << 16) | - ((long) buf[2] << 8) | buf[3]; - break; - case 'L': - r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | - ((long) buf[3] << 24); - break; - } - - if (r == EOF) - return 0; - - return r; -} - -/* Find the strings in file FILENAME, read from STREAM. - Assume that STREAM is positioned so that the next byte read - is at address ADDRESS in the file. - Stop reading at address STOP_POINT in the file, if nonzero. - - If STREAM is NULL, do not read from it. - The caller can supply a buffer of characters - to be processed before the data in STREAM. - MAGIC is the address of the buffer and - MAGICCOUNT is how many characters are in it. - Those characters come at address ADDRESS and the data in STREAM follow. */ - -static void -print_strings (const char *filename, FILE *stream, file_ptr address, - int stop_point, int magiccount, char *magic) -{ - char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1)); - - while (1) - { - file_ptr start; - int i; - long c; - - /* See if the next `string_min' chars are all graphic chars. */ - tryline: - if (stop_point && address >= stop_point) - break; - start = address; - for (i = 0; i < string_min; i++) - { - c = get_char (stream, &address, &magiccount, &magic); - if (c == EOF) - { - free (buf); - return; - } - if (! STRING_ISGRAPHIC (c)) - /* Found a non-graphic. Try again starting with next char. */ - goto tryline; - buf[i] = c; - } - - /* We found a run of `string_min' graphic characters. Print up - to the next non-graphic character. */ - - if (print_filenames) - printf ("%s: ", filename); - if (print_addresses) - switch (address_radix) - { - case 8: -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) - if (sizeof (start) > sizeof (long)) - { -#ifndef __MSVCRT__ - printf ("%7llo ", (unsigned long long) start); -#else - printf ("%7I64o ", (unsigned long long) start); -#endif - } - else -#elif !BFD_HOST_64BIT_LONG - if (start != (unsigned long) start) - printf ("++%7lo ", (unsigned long) start); - else -#endif - printf ("%7lo ", (unsigned long) start); - break; - - case 10: -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) - if (sizeof (start) > sizeof (long)) - { -#ifndef __MSVCRT__ - printf ("%7lld ", (unsigned long long) start); -#else - printf ("%7I64d ", (unsigned long long) start); -#endif - } - else -#elif !BFD_HOST_64BIT_LONG - if (start != (unsigned long) start) - printf ("++%7ld ", (unsigned long) start); - else -#endif - printf ("%7ld ", (long) start); - break; - - case 16: -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) - if (sizeof (start) > sizeof (long)) - { -#ifndef __MSVCRT__ - printf ("%7llx ", (unsigned long long) start); -#else - printf ("%7I64x ", (unsigned long long) start); -#endif - } - else -#elif !BFD_HOST_64BIT_LONG - if (start != (unsigned long) start) - printf ("%lx%8.8lx ", (unsigned long) (start >> 32), - (unsigned long) (start & 0xffffffff)); - else -#endif - printf ("%7lx ", (unsigned long) start); - break; - } - - buf[i] = '\0'; - fputs (buf, stdout); - - while (1) - { - c = get_char (stream, &address, &magiccount, &magic); - if (c == EOF) - break; - if (! STRING_ISGRAPHIC (c)) - break; - putchar (c); - } - - putchar ('\n'); - } - free (buf); -} - -static void -usage (FILE *stream, int status) -{ - fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name); - fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n")); - fprintf (stream, _(" The options are:\n\ - -a - --all Scan the entire file, not just the data section\n\ - -f --print-file-name Print the name of the file before each string\n\ - -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\ - - least [number] characters (default 4).\n\ - -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\ - -o An alias for --radix=o\n\ - -T --target= Specify the binary file format\n\ - -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\ - s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\ - @ Read options from \n\ - -h --help Display this information\n\ - -v -V --version Print the program's version number\n")); - list_supported_targets (program_name, stream); - if (REPORT_BUGS_TO[0] && status == 0) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); - exit (status); -} diff --git a/contrib/binutils-2.22/binutils/sysdep.h b/contrib/binutils-2.22/binutils/sysdep.h deleted file mode 100644 index e573637b8c..0000000000 --- a/contrib/binutils-2.22/binutils/sysdep.h +++ /dev/null @@ -1,179 +0,0 @@ -/* sysdep.h -- handle host dependencies for binutils - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _BIN_SYSDEP_H -#define _BIN_SYSDEP_H - -#include "alloca-conf.h" -#include "ansidecl.h" -#include -#include - -#include "bfdver.h" - -#include - -#ifdef USE_BINARY_FOPEN -#include "fopen-bin.h" -#else -#include "fopen-same.h" -#endif - -#include -#ifndef errno -extern int errno; -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#else -extern char *strchr (); -extern char *strrchr (); -#endif -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#else -#ifdef HAVE_SYS_FILE_H -#include -#endif -#endif - -#include "binary-io.h" - -#if !HAVE_DECL_STPCPY -extern char *stpcpy (char *, const char *); -#endif - -#if !HAVE_DECL_STRSTR -extern char *strstr (); -#endif - -#ifdef HAVE_SBRK -#if !HAVE_DECL_SBRK -extern char *sbrk (); -#endif -#endif - -#if !HAVE_DECL_GETENV -extern char *getenv (); -#endif - -#if !HAVE_DECL_ENVIRON -extern char **environ; -#endif - -#if !HAVE_DECL_FPRINTF -extern int fprintf (FILE *, const char *, ...); -#endif - -#if !HAVE_DECL_SNPRINTF -extern int snprintf(char *, size_t, const char *, ...); -#endif - -#if !HAVE_DECL_VSNPRINTF -extern int vsnprintf(char *, size_t, const char *, va_list); -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifdef HAVE_LOCALE_H -# ifndef ENABLE_NLS - /* The Solaris version of locale.h always includes libintl.h. If we have - been configured with --disable-nls then ENABLE_NLS will not be defined - and the dummy definitions of bindtextdomain (et al) below will conflict - with the defintions in libintl.h. So we define these values to prevent - the bogus inclusion of libintl.h. */ -# define _LIBINTL_H -# define _LIBGETTEXT_H -# endif -# include -#endif - -#ifdef ENABLE_NLS -# include -# define _(String) gettext (String) -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -#else -# define gettext(Msgid) (Msgid) -# define dgettext(Domainname, Msgid) (Msgid) -# define dcgettext(Domainname, Msgid, Category) (Msgid) -# define textdomain(Domainname) while (0) /* nothing */ -# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ -# define _(String) (String) -# define N_(String) (String) -#endif - -/* Used by ar.c and objcopy.c. */ -#define BUFSIZE 8192 - -/* For PATH_MAX. */ -#ifdef HAVE_LIMITS_H -#include -#endif - -#ifndef PATH_MAX -/* For MAXPATHLEN. */ -# ifdef HAVE_SYS_PARAM_H -# include -# endif -# ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif -# endif -#endif - -#endif /* _BIN_SYSDEP_H */ diff --git a/contrib/binutils-2.22/binutils/unwind-ia64.c b/contrib/binutils-2.22/binutils/unwind-ia64.c deleted file mode 100644 index 38382351a8..0000000000 --- a/contrib/binutils-2.22/binutils/unwind-ia64.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf. - Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc. - Contributed by David Mosberger-Tang - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "unwind-ia64.h" -#include -#include - -#if __GNUC__ >= 2 -/* Define BFD64 here, even if our default architecture is 32 bit ELF - as this will allow us to read in and parse 64bit and 32bit ELF files. - Only do this if we believe that the compiler can support a 64 bit - data type. For now we only rely on GCC being able to do this. */ -#define BFD64 -#endif -#include "bfd.h" - -static bfd_vma unw_rlen = 0; - -static void unw_print_brmask (char *, unsigned int); -static void unw_print_grmask (char *, unsigned int); -static void unw_print_frmask (char *, unsigned int); -static void unw_print_abreg (char *, unsigned int); -static void unw_print_xyreg (char *, unsigned int, unsigned int); - -static void -unw_print_brmask (char *cp, unsigned int mask) -{ - int sep = 0; - int i; - - for (i = 0; mask && (i < 5); ++i) - { - if (mask & 1) - { - if (sep) - *cp++ = ','; - *cp++ = 'b'; - *cp++ = i + 1 + '0'; - sep = 1; - } - mask >>= 1; - } - *cp = '\0'; -} - -static void -unw_print_grmask (char *cp, unsigned int mask) -{ - int sep = 0; - int i; - - for (i = 0; i < 4; ++i) - { - if (mask & 1) - { - if (sep) - *cp++ = ','; - *cp++ = 'r'; - *cp++ = i + 4 + '0'; - sep = 1; - } - mask >>= 1; - } - *cp = '\0'; -} - -static void -unw_print_frmask (char *cp, unsigned int mask) -{ - int sep = 0; - int i; - - for (i = 0; i < 20; ++i) - { - if (mask & 1) - { - if (sep) - *cp++ = ','; - *cp++ = 'f'; - if (i < 4) - *cp++ = i + 2 + '0'; - else - { - *cp++ = (i + 2) / 10 + 1 + '0'; - *cp++ = (i + 2) % 10 + '0'; - } - sep = 1; - } - mask >>= 1; - } - *cp = '\0'; -} - -static void -unw_print_abreg (char *cp, unsigned int abreg) -{ - static const char * const special_reg[16] = - { - "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat", - "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc", - "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15" - }; - - switch ((abreg >> 5) & 0x3) - { - case 0: /* gr */ - sprintf (cp, "r%u", (abreg & 0x1f)); - break; - - case 1: /* fr */ - sprintf (cp, "f%u", (abreg & 0x1f)); - break; - - case 2: /* br */ - sprintf (cp, "b%u", (abreg & 0x1f)); - break; - - case 3: /* special */ - strcpy (cp, special_reg[abreg & 0xf]); - break; - } -} - -static void -unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg) -{ - switch ((x << 1) | ((ytreg >> 7) & 1)) - { - case 0: /* gr */ - sprintf (cp, "r%u", (ytreg & 0x1f)); - break; - - case 1: /* fr */ - sprintf (cp, "f%u", (ytreg & 0x1f)); - break; - - case 2: /* br */ - sprintf (cp, "b%u", (ytreg & 0x1f)); - break; - } -} - -#define UNW_REG_BSP "bsp" -#define UNW_REG_BSPSTORE "bspstore" -#define UNW_REG_FPSR "fpsr" -#define UNW_REG_LC "lc" -#define UNW_REG_PFS "pfs" -#define UNW_REG_PR "pr" -#define UNW_REG_PSP "psp" -#define UNW_REG_RNAT "rnat" -#define UNW_REG_RP "rp" -#define UNW_REG_UNAT "unat" - -typedef bfd_vma unw_word; - -#define UNW_DEC_BAD_CODE(code) \ - printf ("Unknown code 0x%02x\n", code) - -#define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \ - do \ - { \ - unw_rlen = rlen; \ - *(int *)arg = body; \ - printf (" %s:%s(rlen=%lu)\n", \ - fmt, body ? "body" : "prologue", (unsigned long) rlen); \ - } \ - while (0) - -#define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \ - do \ - { \ - char regname[16], maskstr[64], *sep; \ - \ - unw_rlen = rlen; \ - *(int *)arg = 0; \ - \ - maskstr[0] = '\0'; \ - sep = ""; \ - if (mask & 0x8) \ - { \ - strcat (maskstr, "rp"); \ - sep = ","; \ - } \ - if (mask & 0x4) \ - { \ - strcat (maskstr, sep); \ - strcat (maskstr, "ar.pfs"); \ - sep = ","; \ - } \ - if (mask & 0x2) \ - { \ - strcat (maskstr, sep); \ - strcat (maskstr, "psp"); \ - sep = ","; \ - } \ - if (mask & 0x1) \ - { \ - strcat (maskstr, sep); \ - strcat (maskstr, "pr"); \ - } \ - sprintf (regname, "r%u", grsave); \ - printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \ - fmt, maskstr, regname, (unsigned long) rlen); \ - } \ - while (0) - -#define UNW_DEC_FR_MEM(fmt, frmask, arg) \ - do \ - { \ - char frstr[200]; \ - \ - unw_print_frmask (frstr, frmask); \ - printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \ - } \ - while (0) - -#define UNW_DEC_GR_MEM(fmt, grmask, arg) \ - do \ - { \ - char grstr[200]; \ - \ - unw_print_grmask (grstr, grmask); \ - printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \ - } \ - while (0) - -#define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \ - do \ - { \ - char frstr[200], grstr[20]; \ - \ - unw_print_grmask (grstr, grmask); \ - unw_print_frmask (frstr, frmask); \ - printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \ - } \ - while (0) - -#define UNW_DEC_BR_MEM(fmt, brmask, arg) \ - do \ - { \ - char brstr[20]; \ - \ - unw_print_brmask (brstr, brmask); \ - printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \ - } \ - while (0) - -#define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \ - do \ - { \ - char brstr[20]; \ - \ - unw_print_brmask (brstr, brmask); \ - printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \ - } \ - while (0) - -#define UNW_DEC_REG_GR(fmt, src, dst, arg) \ - printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst) - -#define UNW_DEC_RP_BR(fmt, dst, arg) \ - printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst) - -#define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \ - printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t) - -#define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \ - printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \ - fmt, reg, 4*(unsigned long)spoff) - -#define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \ - printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \ - fmt, reg, 4*(unsigned long)pspoff) - -#define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \ - do \ - { \ - char grstr[20]; \ - \ - unw_print_grmask (grstr, grmask); \ - printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \ - } \ - while (0) - -#define UNW_DEC_ABI(fmt, abi, context, arg) \ - do \ - { \ - static const char * const abiname[] = \ - { \ - "@svr4", "@hpux", "@nt" \ - }; \ - char buf[20]; \ - const char *abistr = buf; \ - \ - if (abi < 3) \ - abistr = abiname[abi]; \ - else \ - sprintf (buf, "0x%x", abi); \ - printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \ - fmt, abistr, context); \ - } \ - while (0) - -#define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \ - printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r) - -#define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \ - printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t) - -#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \ - printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t) - -#define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \ - printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \ - fmt, 4*(unsigned long)pspoff) - -#define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \ - printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \ - fmt, 4*(unsigned long)spoff) - -#define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \ - printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \ - fmt, (unsigned long) t, 16*(unsigned long)size) - -#define UNW_DEC_MEM_STACK_V(fmt, t, arg) \ - printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t) - -#define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \ - printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \ - fmt, 4*(unsigned long)pspoff) - -#define UNW_DEC_SPILL_MASK(fmt, dp, arg) \ - do \ - { \ - static const char *spill_type = "-frb"; \ - unsigned const char *imaskp = dp; \ - unsigned char mask = 0; \ - bfd_vma insn = 0; \ - \ - printf ("\t%s:spill_mask(imask=[", fmt); \ - for (insn = 0; insn < unw_rlen; ++insn) \ - { \ - if ((insn % 4) == 0) \ - mask = *imaskp++; \ - if (insn > 0 && (insn % 3) == 0) \ - putchar (','); \ - putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \ - } \ - printf ("])\n"); \ - dp = imaskp; \ - } \ - while (0) - -#define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \ - fmt, regname, (unsigned long) t, 4*(unsigned long)off); \ - } \ - while (0) - -#define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \ - fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \ - } \ - while (0) - -#define UNW_DEC_RESTORE(fmt, t, abreg, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:restore(t=%lu,reg=%s)\n", \ - fmt, (unsigned long) t, regname); \ - } \ - while (0) - -#define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \ - do \ - { \ - char abregname[20], tregname[20]; \ - \ - unw_print_abreg (abregname, abreg); \ - unw_print_xyreg (tregname, x, ytreg); \ - printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \ - fmt, (unsigned long) t, abregname, tregname); \ - } \ - while (0) - -#define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \ - fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \ - } \ - while (0) - -#define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\ - fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\ - } \ - while (0) - -#define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \ - do \ - { \ - char regname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \ - fmt, qp, (unsigned long) t, regname); \ - } \ - while (0) - -#define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \ - do \ - { \ - char regname[20], tregname[20]; \ - \ - unw_print_abreg (regname, abreg); \ - unw_print_xyreg (tregname, x, ytreg); \ - printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \ - fmt, qp, (unsigned long) t, regname, tregname); \ - } \ - while (0) - -#define UNW_DEC_LABEL_STATE(fmt, label, arg) \ - printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label) - -#define UNW_DEC_COPY_STATE(fmt, label, arg) \ - printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label) - -#define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \ - printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \ - fmt, (unsigned long) t, (unsigned long) ecount) - -/* - * Generic IA-64 unwind info decoder. - * - * This file is used both by the Linux kernel and objdump. Please - * keep the two copies of this file in sync (modulo differences in the - * prototypes...). - * - * You need to customize the decoder by defining the following - * macros/constants before including this file: - * - * Types: - * unw_word Unsigned integer type with at least 64 bits - * - * Register names: - * UNW_REG_BSP - * UNW_REG_BSPSTORE - * UNW_REG_FPSR - * UNW_REG_LC - * UNW_REG_PFS - * UNW_REG_PR - * UNW_REG_RNAT - * UNW_REG_PSP - * UNW_REG_RP - * UNW_REG_UNAT - * - * Decoder action macros: - * UNW_DEC_BAD_CODE(code) - * UNW_DEC_ABI(fmt,abi,context,arg) - * UNW_DEC_BR_GR(fmt,brmask,gr,arg) - * UNW_DEC_BR_MEM(fmt,brmask,arg) - * UNW_DEC_COPY_STATE(fmt,label,arg) - * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) - * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) - * UNW_DEC_FR_MEM(fmt,frmask,arg) - * UNW_DEC_GR_GR(fmt,grmask,gr,arg) - * UNW_DEC_GR_MEM(fmt,grmask,arg) - * UNW_DEC_LABEL_STATE(fmt,label,arg) - * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) - * UNW_DEC_MEM_STACK_V(fmt,t,arg) - * UNW_DEC_PRIUNAT_GR(fmt,r,arg) - * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) - * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) - * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) - * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) - * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) - * UNW_DEC_REG_REG(fmt,src,dst,arg) - * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) - * UNW_DEC_REG_WHEN(fmt,reg,t,arg) - * UNW_DEC_RESTORE(fmt,t,abreg,arg) - * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) - * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) - * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) - * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) - * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) - */ - -static unw_word unw_decode_uleb128 (const unsigned char **); -static const unsigned char *unw_decode_x1 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_x2 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_x3 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_x4 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_r1 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_r2 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_r3 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_p1 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_p2_p5 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_p6 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_p7_p10 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_b1 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_b2 - (const unsigned char *, unsigned int, void *); -static const unsigned char *unw_decode_b3_x4 - (const unsigned char *, unsigned int, void *); - -static unw_word -unw_decode_uleb128 (const unsigned char **dpp) -{ - unsigned shift = 0; - unw_word byte, result = 0; - const unsigned char *bp = *dpp; - - while (1) - { - byte = *bp++; - result |= (byte & 0x7f) << shift; - - if ((byte & 0x80) == 0) - break; - - shift += 7; - } - - *dpp = bp; - - return result; -} - -static const unsigned char * -unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) -{ - unsigned char byte1, abreg; - unw_word t, off; - - byte1 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg); - return dp; -} - -static const unsigned char * -unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) -{ - unsigned char byte1, byte2, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; - byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - ytreg = byte2; - x = (byte1 >> 7) & 1; - if ((byte1 & 0x80) == 0 && ytreg == 0) - UNW_DEC_RESTORE ("X2", t, abreg, arg); - else - UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg); - return dp; -} - -static const unsigned char * -unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) -{ - unsigned char byte1, byte2, abreg, qp; - unw_word t, off; - - byte1 = *dp++; - byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg); - return dp; -} - -static const unsigned char * -unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) -{ - unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; - byte2 = *dp++; - byte3 = *dp++; - t = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - x = (byte2 >> 7) & 1; - ytreg = byte3; - - if ((byte2 & 0x80) == 0 && byte3 == 0) - UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg); - else - UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg); - return dp; -} - -static const unsigned char * -unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg) -{ - int body = (code & 0x20) != 0; - unw_word rlen; - - rlen = (code & 0x1f); - UNW_DEC_PROLOGUE ("R1", body, rlen, arg); - return dp; -} - -static const unsigned char * -unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg) -{ - unsigned char byte1, mask, grsave; - unw_word rlen; - - byte1 = *dp++; - - mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - grsave = (byte1 & 0x7f); - rlen = unw_decode_uleb128 (& dp); - UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg); - return dp; -} - -static const unsigned char * -unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg) -{ - unw_word rlen; - - rlen = unw_decode_uleb128 (& dp); - UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg); - return dp; -} - -static const unsigned char * -unw_decode_p1 (const unsigned char *dp, unsigned int code, - void *arg ATTRIBUTE_UNUSED) -{ - unsigned char brmask = (code & 0x1f); - - UNW_DEC_BR_MEM ("P1", brmask, arg); - return dp; -} - -static const unsigned char * -unw_decode_p2_p5 (const unsigned char *dp, unsigned int code, - void *arg ATTRIBUTE_UNUSED) -{ - if ((code & 0x10) == 0) - { - unsigned char byte1 = *dp++; - - UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1), - (byte1 & 0x7f), arg); - } - else if ((code & 0x08) == 0) - { - unsigned char byte1 = *dp++, r, dst; - - r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - dst = (byte1 & 0x7f); - switch (r) - { - case 0: - UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg); - break; - case 1: - UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg); - break; - case 2: - UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg); - break; - case 3: - UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg); - break; - case 4: - UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg); - break; - case 5: - UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg); - break; - case 6: - UNW_DEC_RP_BR ("P3", dst, arg); - break; - case 7: - UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg); - break; - case 8: - UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg); - break; - case 9: - UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg); - break; - case 10: - UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg); - break; - case 11: - UNW_DEC_PRIUNAT_GR ("P3", dst, arg); - break; - default: - UNW_DEC_BAD_CODE (r); - break; - } - } - else if ((code & 0x7) == 0) - UNW_DEC_SPILL_MASK ("P4", dp, arg); - else if ((code & 0x7) == 1) - { - unw_word grmask, frmask, byte1, byte2, byte3; - - byte1 = *dp++; - byte2 = *dp++; - byte3 = *dp++; - grmask = ((byte1 >> 4) & 0xf); - frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; - UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg); - } - else - UNW_DEC_BAD_CODE (code); - - return dp; -} - -static const unsigned char * -unw_decode_p6 (const unsigned char *dp, unsigned int code, - void *arg ATTRIBUTE_UNUSED) -{ - int gregs = (code & 0x10) != 0; - unsigned char mask = (code & 0x0f); - - if (gregs) - UNW_DEC_GR_MEM ("P6", mask, arg); - else - UNW_DEC_FR_MEM ("P6", mask, arg); - return dp; -} - -static const unsigned char * -unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg) -{ - unsigned char r, byte1, byte2; - unw_word t, size; - - if ((code & 0x10) == 0) - { - r = (code & 0xf); - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 0: - size = unw_decode_uleb128 (&dp); - UNW_DEC_MEM_STACK_F ("P7", t, size, arg); - break; - - case 1: - UNW_DEC_MEM_STACK_V ("P7", t, arg); - break; - case 2: - UNW_DEC_SPILL_BASE ("P7", t, arg); - break; - case 3: - UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg); - break; - case 4: - UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg); - break; - case 5: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg); - break; - case 6: - UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg); - break; - case 7: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg); - break; - case 8: - UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg); - break; - case 9: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg); - break; - case 10: - UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg); - break; - case 11: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg); - break; - case 12: - UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg); - break; - case 13: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg); - break; - case 14: - UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg); - break; - case 15: - UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg); - break; - default: - UNW_DEC_BAD_CODE (r); - break; - } - } - else - { - switch (code & 0xf) - { - case 0x0: /* p8 */ - { - r = *dp++; - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 1: - UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg); - break; - case 2: - UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg); - break; - case 3: - UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg); - break; - case 4: - UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg); - break; - case 5: - UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg); - break; - case 6: - UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg); - break; - case 7: - UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg); - break; - case 8: - UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg); - break; - case 9: - UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg); - break; - case 10: - UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg); - break; - case 11: - UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg); - break; - case 12: - UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg); - break; - case 13: - UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg); - break; - case 14: - UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg); - break; - case 15: - UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg); - break; - case 16: - UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg); - break; - case 17: - UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg); - break; - case 18: - UNW_DEC_PRIUNAT_SPREL ("P8", t, arg); - break; - case 19: - UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg); - break; - default: - UNW_DEC_BAD_CODE (r); - break; - } - } - break; - - case 0x1: - byte1 = *dp++; - byte2 = *dp++; - UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg); - break; - - case 0xf: /* p10 */ - byte1 = *dp++; - byte2 = *dp++; - UNW_DEC_ABI ("P10", byte1, byte2, arg); - break; - - case 0x9: - return unw_decode_x1 (dp, code, arg); - - case 0xa: - return unw_decode_x2 (dp, code, arg); - - case 0xb: - return unw_decode_x3 (dp, code, arg); - - case 0xc: - return unw_decode_x4 (dp, code, arg); - - default: - UNW_DEC_BAD_CODE (code); - break; - } - } - return dp; -} - -static const unsigned char * -unw_decode_b1 (const unsigned char *dp, unsigned int code, - void *arg ATTRIBUTE_UNUSED) -{ - unw_word label = (code & 0x1f); - - if ((code & 0x20) != 0) - UNW_DEC_COPY_STATE ("B1", label, arg); - else - UNW_DEC_LABEL_STATE ("B1", label, arg); - return dp; -} - -static const unsigned char * -unw_decode_b2 (const unsigned char *dp, unsigned int code, - void *arg ATTRIBUTE_UNUSED) -{ - unw_word t; - - t = unw_decode_uleb128 (& dp); - UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg); - return dp; -} - -static const unsigned char * -unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg) -{ - unw_word t, ecount, label; - - if ((code & 0x10) == 0) - { - t = unw_decode_uleb128 (&dp); - ecount = unw_decode_uleb128 (&dp); - UNW_DEC_EPILOGUE ("B3", t, ecount, arg); - } - else if ((code & 0x07) == 0) - { - label = unw_decode_uleb128 (&dp); - if ((code & 0x08) != 0) - UNW_DEC_COPY_STATE ("B4", label, arg); - else - UNW_DEC_LABEL_STATE ("B4", label, arg); - } - else - switch (code & 0x7) - { - case 1: - return unw_decode_x1 (dp, code, arg); - case 2: - return unw_decode_x2 (dp, code, arg); - case 3: - return unw_decode_x3 (dp, code, arg); - case 4: - return unw_decode_x4 (dp, code, arg); - default: - UNW_DEC_BAD_CODE (code); - break; - } - return dp; -} - -typedef const unsigned char *(*unw_decoder) - (const unsigned char *, unsigned int, void *); - -static const unw_decoder unw_decode_table[2][8] = - { - /* prologue table: */ - { - unw_decode_r1, /* 0 */ - unw_decode_r1, - unw_decode_r2, - unw_decode_r3, - unw_decode_p1, /* 4 */ - unw_decode_p2_p5, - unw_decode_p6, - unw_decode_p7_p10 - }, - { - unw_decode_r1, /* 0 */ - unw_decode_r1, - unw_decode_r2, - unw_decode_r3, - unw_decode_b1, /* 4 */ - unw_decode_b1, - unw_decode_b2, - unw_decode_b3_x4 - } - }; - -/* Decode one descriptor and return address of next descriptor. */ -const unsigned char * -unw_decode (const unsigned char *dp, int inside_body, - void *ptr_inside_body) -{ - unw_decoder decoder; - unsigned char code; - - code = *dp++; - decoder = unw_decode_table[inside_body][code >> 5]; - return (*decoder) (dp, code, ptr_inside_body); -} diff --git a/contrib/binutils-2.22/binutils/unwind-ia64.h b/contrib/binutils-2.22/binutils/unwind-ia64.h deleted file mode 100644 index b004bc3414..0000000000 --- a/contrib/binutils-2.22/binutils/unwind-ia64.h +++ /dev/null @@ -1,32 +0,0 @@ -/* unwind-ia64.h -- dump IA-64 unwind info. - Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc. - Contributed by David Mosberger-Tang - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "elf/ia64.h" -#include "ansidecl.h" - -#define UNW_VER(x) ((x) >> 48) -#define UNW_FLAG_MASK 0x0000ffff00000000LL -#define UNW_FLAG_OSMASK 0x0000f00000000000LL -#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000LL) -#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000LL) -#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffLL) - -extern const unsigned char *unw_decode (const unsigned char *, int, void *); diff --git a/contrib/binutils-2.22/binutils/version.c b/contrib/binutils-2.22/binutils/version.c deleted file mode 100644 index 47e2b31e33..0000000000 --- a/contrib/binutils-2.22/binutils/version.c +++ /dev/null @@ -1,42 +0,0 @@ -/* version.c -- binutils version information - Copyright 1991, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - 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, 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, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include "sysdep.h" -#include "bfd.h" -#include "bucomm.h" - -/* Print the version number and copyright information, and exit. - This implements the --version option for the various programs. */ - -void -print_version (const char *name) -{ - /* This output is intended to follow the GNU standards document. */ - /* xgettext:c-format */ - printf ("GNU %s %s\n", name, BFD_VERSION_STRING); - printf (_("Copyright 2011 Free Software Foundation, Inc.\n")); - printf (_("\ -This program is free software; you may redistribute it under the terms of\n\ -the GNU General Public License version 3 or (at your option) any later version.\n\ -This program has absolutely no warranty.\n")); - exit (0); -} diff --git a/contrib/binutils-2.22/binutils/wrstabs.c b/contrib/binutils-2.22/binutils/wrstabs.c deleted file mode 100644 index bbf257e5f5..0000000000 --- a/contrib/binutils-2.22/binutils/wrstabs.c +++ /dev/null @@ -1,2272 +0,0 @@ -/* wrstabs.c -- Output stabs debugging information - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, - 2007, 2009 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - 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, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This file contains code which writes out stabs debugging - information. */ - -#include "sysdep.h" -#include -#include "bfd.h" -#include "libiberty.h" -#include "filenames.h" -#include "safe-ctype.h" -#include "bucomm.h" -#include "debug.h" -#include "budbg.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" - -/* The size of a stabs symbol. This presumes 32 bit values. */ - -#define STAB_SYMBOL_SIZE (12) - -/* An entry in a string hash table. */ - -struct string_hash_entry -{ - struct bfd_hash_entry root; - /* Next string in this table. */ - struct string_hash_entry *next; - /* Index in string table. */ - long index; - /* Size of type if this is a typedef. */ - unsigned int size; -}; - -/* A string hash table. */ - -struct string_hash_table -{ - struct bfd_hash_table table; -}; - -/* The type stack. Each element on the stack is a string. */ - -struct stab_type_stack -{ - /* The next element on the stack. */ - struct stab_type_stack *next; - /* This element as a string. */ - char *string; - /* The type index of this element. */ - long index; - /* The size of the type. */ - unsigned int size; - /* Whether type string defines a new type. */ - bfd_boolean definition; - /* String defining struct fields. */ - char *fields; - /* NULL terminated array of strings defining base classes for a - class. */ - char **baseclasses; - /* String defining class methods. */ - char *methods; - /* String defining vtable pointer for a class. */ - char *vtable; -}; - -/* This structure is used to keep track of type indices for tagged - types. */ - -struct stab_tag -{ - /* The type index. */ - long index; - /* The tag name. */ - const char *tag; - /* The kind of type. This is set to DEBUG_KIND_ILLEGAL when the - type is defined. */ - enum debug_type_kind kind; - /* The size of the struct. */ - unsigned int size; -}; - -/* We remember various sorts of type indices. They are not related, - but, for convenience, we keep all the information in this - structure. */ - -struct stab_type_cache -{ - /* The void type index. */ - long void_type; - /* Signed integer type indices, indexed by size - 1. */ - long signed_integer_types[8]; - /* Unsigned integer type indices, indexed by size - 1. */ - long unsigned_integer_types[8]; - /* Floating point types, indexed by size - 1. */ - long float_types[16]; - /* Pointers to types, indexed by the type index. */ - long *pointer_types; - size_t pointer_types_alloc; - /* Functions returning types, indexed by the type index. */ - long *function_types; - size_t function_types_alloc; - /* References to types, indexed by the type index. */ - long *reference_types; - size_t reference_types_alloc; - /* Struct/union/class type indices, indexed by the struct id. */ - struct stab_tag *struct_types; - size_t struct_types_alloc; -}; - -/* This is the handle passed through debug_write. */ - -struct stab_write_handle -{ - /* The BFD. */ - bfd *abfd; - /* This buffer holds the symbols. */ - bfd_byte *symbols; - size_t symbols_size; - size_t symbols_alloc; - /* This is a list of hash table entries for the strings. */ - struct string_hash_entry *strings; - /* The last string hash table entry. */ - struct string_hash_entry *last_string; - /* The size of the strings. */ - size_t strings_size; - /* This hash table eliminates duplicate strings. */ - struct string_hash_table strhash; - /* The type stack. */ - struct stab_type_stack *type_stack; - /* The next type index. */ - long type_index; - /* The type cache. */ - struct stab_type_cache type_cache; - /* A mapping from typedef names to type indices. */ - struct string_hash_table typedef_hash; - /* If this is not -1, it is the offset to the most recent N_SO - symbol, and the value of that symbol needs to be set. */ - long so_offset; - /* If this is not -1, it is the offset to the most recent N_FUN - symbol, and the value of that symbol needs to be set. */ - long fun_offset; - /* The last text section address seen. */ - bfd_vma last_text_address; - /* The block nesting depth. */ - unsigned int nesting; - /* The function address. */ - bfd_vma fnaddr; - /* A pending LBRAC symbol. */ - bfd_vma pending_lbrac; - /* The current line number file name. */ - const char *lineno_filename; -}; - -static struct bfd_hash_entry *string_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -static bfd_boolean stab_write_symbol - (struct stab_write_handle *, int, int, bfd_vma, const char *); -static bfd_boolean stab_push_string - (struct stab_write_handle *, const char *, long, bfd_boolean, unsigned int); -static bfd_boolean stab_push_defined_type - (struct stab_write_handle *, long, unsigned int); -static char *stab_pop_type (struct stab_write_handle *); -static bfd_boolean stab_modify_type - (struct stab_write_handle *, int, unsigned int, long **, size_t *); -static long stab_get_struct_index - (struct stab_write_handle *, const char *, unsigned int, - enum debug_type_kind, unsigned int *); -static bfd_boolean stab_class_method_var - (struct stab_write_handle *, const char *, enum debug_visibility, - bfd_boolean, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean); -static bfd_boolean stab_start_compilation_unit (void *, const char *); -static bfd_boolean stab_start_source (void *, const char *); -static bfd_boolean stab_empty_type (void *); -static bfd_boolean stab_void_type (void *); -static bfd_boolean stab_int_type (void *, unsigned int, bfd_boolean); -static bfd_boolean stab_float_type (void *, unsigned int); -static bfd_boolean stab_complex_type (void *, unsigned int); -static bfd_boolean stab_bool_type (void *, unsigned int); -static bfd_boolean stab_enum_type - (void *, const char *, const char **, bfd_signed_vma *); -static bfd_boolean stab_pointer_type (void *); -static bfd_boolean stab_function_type (void *, int, bfd_boolean); -static bfd_boolean stab_reference_type (void *); -static bfd_boolean stab_range_type (void *, bfd_signed_vma, bfd_signed_vma); -static bfd_boolean stab_array_type - (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); -static bfd_boolean stab_set_type (void *, bfd_boolean); -static bfd_boolean stab_offset_type (void *); -static bfd_boolean stab_method_type (void *, bfd_boolean, int, bfd_boolean); -static bfd_boolean stab_const_type (void *); -static bfd_boolean stab_volatile_type (void *); -static bfd_boolean stab_start_struct_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int); -static bfd_boolean stab_struct_field - (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); -static bfd_boolean stab_end_struct_type (void *); -static bfd_boolean stab_start_class_type - (void *, const char *, unsigned int, bfd_boolean, unsigned int, - bfd_boolean, bfd_boolean); -static bfd_boolean stab_class_static_member - (void *, const char *, const char *, enum debug_visibility); -static bfd_boolean stab_class_baseclass - (void *, bfd_vma, bfd_boolean, enum debug_visibility); -static bfd_boolean stab_class_start_method (void *, const char *); -static bfd_boolean stab_class_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, - bfd_vma, bfd_boolean); -static bfd_boolean stab_class_static_method_variant - (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); -static bfd_boolean stab_class_end_method (void *); -static bfd_boolean stab_end_class_type (void *); -static bfd_boolean stab_typedef_type (void *, const char *); -static bfd_boolean stab_tag_type - (void *, const char *, unsigned int, enum debug_type_kind); -static bfd_boolean stab_typdef (void *, const char *); -static bfd_boolean stab_tag (void *, const char *); -static bfd_boolean stab_int_constant (void *, const char *, bfd_vma); -static bfd_boolean stab_float_constant (void *, const char *, double); -static bfd_boolean stab_typed_constant (void *, const char *, bfd_vma); -static bfd_boolean stab_variable - (void *, const char *, enum debug_var_kind, bfd_vma); -static bfd_boolean stab_start_function (void *, const char *, bfd_boolean); -static bfd_boolean stab_function_parameter - (void *, const char *, enum debug_parm_kind, bfd_vma); -static bfd_boolean stab_start_block (void *, bfd_vma); -static bfd_boolean stab_end_block (void *, bfd_vma); -static bfd_boolean stab_end_function (void *); -static bfd_boolean stab_lineno (void *, const char *, unsigned long, bfd_vma); - -static const struct debug_write_fns stab_fns = -{ - stab_start_compilation_unit, - stab_start_source, - stab_empty_type, - stab_void_type, - stab_int_type, - stab_float_type, - stab_complex_type, - stab_bool_type, - stab_enum_type, - stab_pointer_type, - stab_function_type, - stab_reference_type, - stab_range_type, - stab_array_type, - stab_set_type, - stab_offset_type, - stab_method_type, - stab_const_type, - stab_volatile_type, - stab_start_struct_type, - stab_struct_field, - stab_end_struct_type, - stab_start_class_type, - stab_class_static_member, - stab_class_baseclass, - stab_class_start_method, - stab_class_method_variant, - stab_class_static_method_variant, - stab_class_end_method, - stab_end_class_type, - stab_typedef_type, - stab_tag_type, - stab_typdef, - stab_tag, - stab_int_constant, - stab_float_constant, - stab_typed_constant, - stab_variable, - stab_start_function, - stab_function_parameter, - stab_start_block, - stab_end_block, - stab_end_function, - stab_lineno -}; - -/* Routine to create an entry in a string hash table. */ - -static struct bfd_hash_entry * -string_hash_newfunc (struct bfd_hash_entry *entry, - struct bfd_hash_table *table, const char *string) -{ - struct string_hash_entry *ret = (struct string_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct string_hash_entry *) NULL) - ret = ((struct string_hash_entry *) - bfd_hash_allocate (table, sizeof (struct string_hash_entry))); - if (ret == (struct string_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct string_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->next = NULL; - ret->index = -1; - ret->size = 0; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in a string hash table. */ - -#define string_hash_lookup(t, string, create, copy) \ - ((struct string_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Add a symbol to the stabs debugging information we are building. */ - -static bfd_boolean -stab_write_symbol (struct stab_write_handle *info, int type, int desc, - bfd_vma value, const char *string) -{ - bfd_size_type strx; - bfd_byte sym[STAB_SYMBOL_SIZE]; - - if (string == NULL) - strx = 0; - else - { - struct string_hash_entry *h; - - h = string_hash_lookup (&info->strhash, string, TRUE, TRUE); - if (h == NULL) - { - non_fatal (_("string_hash_lookup failed: %s"), - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - if (h->index != -1) - strx = h->index; - else - { - strx = info->strings_size; - h->index = strx; - if (info->last_string == NULL) - info->strings = h; - else - info->last_string->next = h; - info->last_string = h; - info->strings_size += strlen (string) + 1; - } - } - - /* This presumes 32 bit values. */ - bfd_put_32 (info->abfd, strx, sym); - bfd_put_8 (info->abfd, type, sym + 4); - bfd_put_8 (info->abfd, 0, sym + 5); - bfd_put_16 (info->abfd, desc, sym + 6); - bfd_put_32 (info->abfd, value, sym + 8); - - if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc) - { - info->symbols_alloc *= 2; - info->symbols = (bfd_byte *) xrealloc (info->symbols, - info->symbols_alloc); - } - - memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE); - - info->symbols_size += STAB_SYMBOL_SIZE; - - return TRUE; -} - -/* Push a string on to the type stack. */ - -static bfd_boolean -stab_push_string (struct stab_write_handle *info, const char *string, - long tindex, bfd_boolean definition, unsigned int size) -{ - struct stab_type_stack *s; - - s = (struct stab_type_stack *) xmalloc (sizeof *s); - s->string = xstrdup (string); - s->index = tindex; - s->definition = definition; - s->size = size; - - s->fields = NULL; - s->baseclasses = NULL; - s->methods = NULL; - s->vtable = NULL; - - s->next = info->type_stack; - info->type_stack = s; - - return TRUE; -} - -/* Push a type index which has already been defined. */ - -static bfd_boolean -stab_push_defined_type (struct stab_write_handle *info, long tindex, - unsigned int size) -{ - char buf[20]; - - sprintf (buf, "%ld", tindex); - return stab_push_string (info, buf, tindex, FALSE, size); -} - -/* Pop a type off the type stack. The caller is responsible for - freeing the string. */ - -static char * -stab_pop_type (struct stab_write_handle *info) -{ - struct stab_type_stack *s; - char *ret; - - s = info->type_stack; - assert (s != NULL); - - info->type_stack = s->next; - - ret = s->string; - - free (s); - - return ret; -} - -/* The general routine to write out stabs in sections debugging - information. This accumulates the stabs symbols and the strings in - two obstacks. We can't easily write out the information as we go - along, because we need to know the section sizes before we can - write out the section contents. ABFD is the BFD and DHANDLE is the - handle for the debugging information. This sets *PSYMS to point to - the symbols, *PSYMSIZE the size of the symbols, *PSTRINGS to the - strings, and *PSTRINGSIZE to the size of the strings. */ - -bfd_boolean -write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle, - bfd_byte **psyms, - bfd_size_type *psymsize, - bfd_byte **pstrings, - bfd_size_type *pstringsize) -{ - struct stab_write_handle info; - struct string_hash_entry *h; - bfd_byte *p; - - info.abfd = abfd; - - info.symbols_size = 0; - info.symbols_alloc = 500; - info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc); - - info.strings = NULL; - info.last_string = NULL; - /* Reserve 1 byte for a null byte. */ - info.strings_size = 1; - - if (!bfd_hash_table_init (&info.strhash.table, string_hash_newfunc, - sizeof (struct string_hash_entry)) - || !bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc, - sizeof (struct string_hash_entry))) - { - non_fatal ("bfd_hash_table_init_failed: %s", - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - info.type_stack = NULL; - info.type_index = 1; - memset (&info.type_cache, 0, sizeof info.type_cache); - info.so_offset = -1; - info.fun_offset = -1; - info.last_text_address = 0; - info.nesting = 0; - info.fnaddr = 0; - info.pending_lbrac = (bfd_vma) -1; - - /* The initial symbol holds the string size. */ - if (! stab_write_symbol (&info, 0, 0, 0, (const char *) NULL)) - return FALSE; - - /* Output an initial N_SO symbol. */ - info.so_offset = info.symbols_size; - if (! stab_write_symbol (&info, N_SO, 0, 0, bfd_get_filename (abfd))) - return FALSE; - - if (! debug_write (dhandle, &stab_fns, (void *) &info)) - return FALSE; - - assert (info.pending_lbrac == (bfd_vma) -1); - - /* Output a trailing N_SO. */ - if (! stab_write_symbol (&info, N_SO, 0, info.last_text_address, - (const char *) NULL)) - return FALSE; - - /* Put the string size in the initial symbol. */ - bfd_put_32 (abfd, info.strings_size, info.symbols + 8); - - *psyms = info.symbols; - *psymsize = info.symbols_size; - - *pstringsize = info.strings_size; - *pstrings = (bfd_byte *) xmalloc (info.strings_size); - - p = *pstrings; - *p++ = '\0'; - for (h = info.strings; h != NULL; h = h->next) - { - strcpy ((char *) p, h->root.string); - p += strlen ((char *) p) + 1; - } - - return TRUE; -} - -/* Start writing out information for a compilation unit. */ - -static bfd_boolean -stab_start_compilation_unit (void *p, const char *filename) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* We would normally output an N_SO symbol here. However, that - would force us to reset all of our type information. I think we - will be better off just outputting an N_SOL symbol, and not - worrying about splitting information between files. */ - - info->lineno_filename = filename; - - return stab_write_symbol (info, N_SOL, 0, 0, filename); -} - -/* Start writing out information for a particular source file. */ - -static bfd_boolean -stab_start_source (void *p, const char *filename) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* FIXME: The symbol's value is supposed to be the text section - address. However, we would have to fill it in later, and gdb - doesn't care, so we don't bother with it. */ - - info->lineno_filename = filename; - - return stab_write_symbol (info, N_SOL, 0, 0, filename); -} - -/* Push an empty type. This shouldn't normally happen. We just use a - void type. */ - -static bfd_boolean -stab_empty_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* We don't call stab_void_type if the type is not yet defined, - because that might screw up the typedef. */ - - if (info->type_cache.void_type != 0) - return stab_push_defined_type (info, info->type_cache.void_type, 0); - else - { - long tindex; - char buf[40]; - - tindex = info->type_index; - ++info->type_index; - - sprintf (buf, "%ld=%ld", tindex, tindex); - - return stab_push_string (info, buf, tindex, FALSE, 0); - } -} - -/* Push a void type. */ - -static bfd_boolean -stab_void_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - if (info->type_cache.void_type != 0) - return stab_push_defined_type (info, info->type_cache.void_type, 0); - else - { - long tindex; - char buf[40]; - - tindex = info->type_index; - ++info->type_index; - - info->type_cache.void_type = tindex; - - sprintf (buf, "%ld=%ld", tindex, tindex); - - return stab_push_string (info, buf, tindex, TRUE, 0); - } -} - -/* Push an integer type. */ - -static bfd_boolean -stab_int_type (void *p, unsigned int size, bfd_boolean unsignedp) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - long *cache; - - if (size <= 0 || (size > sizeof (long) && size != 8)) - { - non_fatal (_("stab_int_type: bad size %u"), size); - return FALSE; - } - - if (unsignedp) - cache = info->type_cache.signed_integer_types; - else - cache = info->type_cache.unsigned_integer_types; - - if (cache[size - 1] != 0) - return stab_push_defined_type (info, cache[size - 1], size); - else - { - long tindex; - char buf[100]; - - tindex = info->type_index; - ++info->type_index; - - cache[size - 1] = tindex; - - sprintf (buf, "%ld=r%ld;", tindex, tindex); - if (unsignedp) - { - strcat (buf, "0;"); - if (size < sizeof (long)) - sprintf (buf + strlen (buf), "%ld;", ((long) 1 << (size * 8)) - 1); - else if (size == sizeof (long)) - strcat (buf, "-1;"); - else if (size == 8) - strcat (buf, "01777777777777777777777;"); - else - abort (); - } - else - { - if (size <= sizeof (long)) - sprintf (buf + strlen (buf), "%ld;%ld;", - (long) - ((unsigned long) 1 << (size * 8 - 1)), - (long) (((unsigned long) 1 << (size * 8 - 1)) - 1)); - else if (size == 8) - strcat (buf, "01000000000000000000000;0777777777777777777777;"); - else - abort (); - } - - return stab_push_string (info, buf, tindex, TRUE, size); - } -} - -/* Push a floating point type. */ - -static bfd_boolean -stab_float_type (void *p, unsigned int size) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - if (size > 0 - && size - 1 < (sizeof info->type_cache.float_types - / sizeof info->type_cache.float_types[0]) - && info->type_cache.float_types[size - 1] != 0) - return stab_push_defined_type (info, - info->type_cache.float_types[size - 1], - size); - else - { - long tindex; - char *int_type; - char buf[50]; - - /* Floats are defined as a subrange of int. */ - if (! stab_int_type (info, 4, FALSE)) - return FALSE; - int_type = stab_pop_type (info); - - tindex = info->type_index; - ++info->type_index; - - if (size > 0 - && size - 1 < (sizeof info->type_cache.float_types - / sizeof info->type_cache.float_types[0])) - info->type_cache.float_types[size - 1] = tindex; - - sprintf (buf, "%ld=r%s;%u;0;", tindex, int_type, size); - - free (int_type); - - return stab_push_string (info, buf, tindex, TRUE, size); - } -} - -/* Push a complex type. */ - -static bfd_boolean -stab_complex_type (void *p, unsigned int size) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char buf[50]; - long tindex; - - tindex = info->type_index; - ++info->type_index; - - sprintf (buf, "%ld=r%ld;%u;0;", tindex, tindex, size); - - return stab_push_string (info, buf, tindex, TRUE, size * 2); -} - -/* Push a bfd_boolean type. We use an XCOFF predefined type, since gdb - always recognizes them. */ - -static bfd_boolean -stab_bool_type (void *p, unsigned int size) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - long tindex; - - switch (size) - { - case 1: - tindex = -21; - break; - - case 2: - tindex = -22; - break; - - default: - case 4: - tindex = -16; - break; - - case 8: - tindex = -33; - break; - } - - return stab_push_defined_type (info, tindex, size); -} - -/* Push an enum type. */ - -static bfd_boolean -stab_enum_type (void *p, const char *tag, const char **names, - bfd_signed_vma *vals) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - size_t len; - const char **pn; - char *buf; - long tindex = 0; - bfd_signed_vma *pv; - - if (names == NULL) - { - assert (tag != NULL); - - buf = (char *) xmalloc (10 + strlen (tag)); - sprintf (buf, "xe%s:", tag); - /* FIXME: The size is just a guess. */ - if (! stab_push_string (info, buf, 0, FALSE, 4)) - return FALSE; - free (buf); - return TRUE; - } - - len = 10; - if (tag != NULL) - len += strlen (tag); - for (pn = names; *pn != NULL; pn++) - len += strlen (*pn) + 20; - - buf = (char *) xmalloc (len); - - if (tag == NULL) - strcpy (buf, "e"); - else - { - tindex = info->type_index; - ++info->type_index; - sprintf (buf, "%s:T%ld=e", tag, tindex); - } - - for (pn = names, pv = vals; *pn != NULL; pn++, pv++) - sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv); - strcat (buf, ";"); - - if (tag == NULL) - { - /* FIXME: The size is just a guess. */ - if (! stab_push_string (info, buf, 0, FALSE, 4)) - return FALSE; - } - else - { - /* FIXME: The size is just a guess. */ - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf) - || ! stab_push_defined_type (info, tindex, 4)) - return FALSE; - } - - free (buf); - - return TRUE; -} - -/* Push a modification of the top type on the stack. Cache the - results in CACHE and CACHE_ALLOC. */ - -static bfd_boolean -stab_modify_type (struct stab_write_handle *info, int mod, - unsigned int size, long **cache, size_t *cache_alloc) -{ - long targindex; - long tindex; - char *s, *buf; - - assert (info->type_stack != NULL); - targindex = info->type_stack->index; - - if (targindex <= 0 - || cache == NULL) - { - bfd_boolean definition; - - /* Either the target type has no index, or we aren't caching - this modifier. Either way we have no way of recording the - new type, so we don't bother to define one. */ - definition = info->type_stack->definition; - s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 2); - sprintf (buf, "%c%s", mod, s); - free (s); - if (! stab_push_string (info, buf, 0, definition, size)) - return FALSE; - free (buf); - } - else - { - if ((size_t) targindex >= *cache_alloc) - { - size_t alloc; - - alloc = *cache_alloc; - if (alloc == 0) - alloc = 10; - while ((size_t) targindex >= alloc) - alloc *= 2; - *cache = (long *) xrealloc (*cache, alloc * sizeof (long)); - memset (*cache + *cache_alloc, 0, - (alloc - *cache_alloc) * sizeof (long)); - *cache_alloc = alloc; - } - - tindex = (*cache)[targindex]; - if (tindex != 0 && ! info->type_stack->definition) - { - /* We have already defined a modification of this type, and - the entry on the type stack is not a definition, so we - can safely discard it (we may have a definition on the - stack, even if we already defined a modification, if it - is a struct which we did not define at the time it was - referenced). */ - free (stab_pop_type (info)); - if (! stab_push_defined_type (info, tindex, size)) - return FALSE; - } - else - { - tindex = info->type_index; - ++info->type_index; - - s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 20); - sprintf (buf, "%ld=%c%s", tindex, mod, s); - free (s); - - (*cache)[targindex] = tindex; - - if (! stab_push_string (info, buf, tindex, TRUE, size)) - return FALSE; - - free (buf); - } - } - - return TRUE; -} - -/* Push a pointer type. */ - -static bfd_boolean -stab_pointer_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* FIXME: The size should depend upon the architecture. */ - return stab_modify_type (info, '*', 4, &info->type_cache.pointer_types, - &info->type_cache.pointer_types_alloc); -} - -/* Push a function type. */ - -static bfd_boolean -stab_function_type (void *p, int argcount, - bfd_boolean varargs ATTRIBUTE_UNUSED) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - int i; - - /* We have no way to represent the argument types, so we just - discard them. However, if they define new types, we must output - them. We do this by producing empty typedefs. */ - for (i = 0; i < argcount; i++) - { - if (! info->type_stack->definition) - free (stab_pop_type (info)); - else - { - char *s, *buf; - - s = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (s) + 3); - sprintf (buf, ":t%s", s); - free (s); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - } - } - - return stab_modify_type (info, 'f', 0, &info->type_cache.function_types, - &info->type_cache.function_types_alloc); -} - -/* Push a reference type. */ - -static bfd_boolean -stab_reference_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* FIXME: The size should depend upon the architecture. */ - return stab_modify_type (info, '&', 4, &info->type_cache.reference_types, - &info->type_cache.reference_types_alloc); -} - -/* Push a range type. */ - -static bfd_boolean -stab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - unsigned int size; - char *s, *buf; - - definition = info->type_stack->definition; - size = info->type_stack->size; - - s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 100); - sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high); - free (s); - - if (! stab_push_string (info, buf, 0, definition, size)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Push an array type. */ - -static bfd_boolean -stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, - bfd_boolean stringp) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - unsigned int element_size; - char *range, *element, *buf; - long tindex; - unsigned int size; - - definition = info->type_stack->definition; - range = stab_pop_type (info); - - definition = definition || info->type_stack->definition; - element_size = info->type_stack->size; - element = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (range) + strlen (element) + 100); - - if (! stringp) - { - tindex = 0; - *buf = '\0'; - } - else - { - /* We need to define a type in order to include the string - attribute. */ - tindex = info->type_index; - ++info->type_index; - definition = TRUE; - sprintf (buf, "%ld=@S;", tindex); - } - - sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s", - range, (long) low, (long) high, element); - free (range); - free (element); - - if (high < low) - size = 0; - else - size = element_size * ((high - low) + 1); - if (! stab_push_string (info, buf, tindex, definition, size)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Push a set type. */ - -static bfd_boolean -stab_set_type (void *p, bfd_boolean bitstringp) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *s, *buf; - long tindex; - - definition = info->type_stack->definition; - - s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 30); - - if (! bitstringp) - { - *buf = '\0'; - tindex = 0; - } - else - { - /* We need to define a type in order to include the string - attribute. */ - tindex = info->type_index; - ++info->type_index; - definition = TRUE; - sprintf (buf, "%ld=@S;", tindex); - } - - sprintf (buf + strlen (buf), "S%s", s); - free (s); - - if (! stab_push_string (info, buf, tindex, definition, 0)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Push an offset type. */ - -static bfd_boolean -stab_offset_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *target, *base, *buf; - - definition = info->type_stack->definition; - target = stab_pop_type (info); - - definition = definition || info->type_stack->definition; - base = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (target) + strlen (base) + 3); - sprintf (buf, "@%s,%s", base, target); - free (base); - free (target); - - if (! stab_push_string (info, buf, 0, definition, 0)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Push a method type. */ - -static bfd_boolean -stab_method_type (void *p, bfd_boolean domainp, int argcount, - bfd_boolean varargs) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *domain, *return_type, *buf; - char **args; - int i; - size_t len; - - /* We don't bother with stub method types, because that would - require a mangler for C++ argument types. This will waste space - in the debugging output. */ - - /* We need a domain. I'm not sure DOMAINP can ever be false, - anyhow. */ - if (! domainp) - { - if (! stab_empty_type (p)) - return FALSE; - } - - definition = info->type_stack->definition; - domain = stab_pop_type (info); - - /* A non-varargs function is indicated by making the last parameter - type be void. */ - - if (argcount < 0) - { - args = NULL; - argcount = 0; - } - else if (argcount == 0) - { - if (varargs) - args = NULL; - else - { - args = (char **) xmalloc (1 * sizeof (*args)); - if (! stab_empty_type (p)) - return FALSE; - definition = definition || info->type_stack->definition; - args[0] = stab_pop_type (info); - argcount = 1; - } - } - else - { - args = (char **) xmalloc ((argcount + 1) * sizeof (*args)); - for (i = argcount - 1; i >= 0; i--) - { - definition = definition || info->type_stack->definition; - args[i] = stab_pop_type (info); - } - if (! varargs) - { - if (! stab_empty_type (p)) - return FALSE; - definition = definition || info->type_stack->definition; - args[argcount] = stab_pop_type (info); - ++argcount; - } - } - - definition = definition || info->type_stack->definition; - return_type = stab_pop_type (info); - - len = strlen (domain) + strlen (return_type) + 10; - for (i = 0; i < argcount; i++) - len += strlen (args[i]); - - buf = (char *) xmalloc (len); - - sprintf (buf, "#%s,%s", domain, return_type); - free (domain); - free (return_type); - for (i = 0; i < argcount; i++) - { - strcat (buf, ","); - strcat (buf, args[i]); - free (args[i]); - } - strcat (buf, ";"); - - if (args != NULL) - free (args); - - if (! stab_push_string (info, buf, 0, definition, 0)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Push a const version of a type. */ - -static bfd_boolean -stab_const_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - return stab_modify_type (info, 'k', info->type_stack->size, - (long **) NULL, (size_t *) NULL); -} - -/* Push a volatile version of a type. */ - -static bfd_boolean -stab_volatile_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - return stab_modify_type (info, 'B', info->type_stack->size, - (long **) NULL, (size_t *) NULL); -} - -/* Get the type index to use for a struct/union/class ID. This should - return -1 if it fails. */ - -static long -stab_get_struct_index (struct stab_write_handle *info, const char *tag, - unsigned int id, enum debug_type_kind kind, - unsigned int *psize) -{ - if (id >= info->type_cache.struct_types_alloc) - { - size_t alloc; - - alloc = info->type_cache.struct_types_alloc; - if (alloc == 0) - alloc = 10; - while (id >= alloc) - alloc *= 2; - info->type_cache.struct_types = - (struct stab_tag *) xrealloc (info->type_cache.struct_types, - alloc * sizeof (struct stab_tag)); - memset ((info->type_cache.struct_types - + info->type_cache.struct_types_alloc), - 0, - ((alloc - info->type_cache.struct_types_alloc) - * sizeof (struct stab_tag))); - info->type_cache.struct_types_alloc = alloc; - } - - if (info->type_cache.struct_types[id].index == 0) - { - info->type_cache.struct_types[id].index = info->type_index; - ++info->type_index; - info->type_cache.struct_types[id].tag = tag; - info->type_cache.struct_types[id].kind = kind; - } - - if (kind == DEBUG_KIND_ILLEGAL) - { - /* This is a definition of the struct. */ - info->type_cache.struct_types[id].kind = kind; - info->type_cache.struct_types[id].size = *psize; - } - else - *psize = info->type_cache.struct_types[id].size; - - return info->type_cache.struct_types[id].index; -} - -/* Start outputting a struct. We ignore the tag, and handle it in - stab_tag. */ - -static bfd_boolean -stab_start_struct_type (void *p, const char *tag, unsigned int id, - bfd_boolean structp, unsigned int size) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - long tindex; - bfd_boolean definition; - char buf[40]; - - if (id == 0) - { - tindex = 0; - *buf = '\0'; - definition = FALSE; - } - else - { - tindex = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL, - &size); - if (tindex < 0) - return FALSE; - sprintf (buf, "%ld=", tindex); - definition = TRUE; - } - - sprintf (buf + strlen (buf), "%c%u", - structp ? 's' : 'u', - size); - - if (! stab_push_string (info, buf, tindex, definition, size)) - return FALSE; - - info->type_stack->fields = (char *) xmalloc (1); - info->type_stack->fields[0] = '\0'; - - return TRUE; -} - -/* Add a field to a struct. */ - -static bfd_boolean -stab_struct_field (void *p, const char *name, bfd_vma bitpos, - bfd_vma bitsize, enum debug_visibility visibility) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - unsigned int size; - char *s, *n; - const char *vis; - - definition = info->type_stack->definition; - size = info->type_stack->size; - s = stab_pop_type (info); - - /* Add this field to the end of the current struct fields, which is - currently on the top of the stack. */ - - assert (info->type_stack->fields != NULL); - n = (char *) xmalloc (strlen (info->type_stack->fields) - + strlen (name) - + strlen (s) - + 50); - - switch (visibility) - { - default: - abort (); - - case DEBUG_VISIBILITY_PUBLIC: - vis = ""; - break; - - case DEBUG_VISIBILITY_PRIVATE: - vis = "/0"; - break; - - case DEBUG_VISIBILITY_PROTECTED: - vis = "/1"; - break; - } - - if (bitsize == 0) - { - bitsize = size * 8; - if (bitsize == 0) - non_fatal (_("%s: warning: unknown size for field `%s' in struct"), - bfd_get_filename (info->abfd), name); - } - - sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s, - (long) bitpos, (long) bitsize); - - free (info->type_stack->fields); - info->type_stack->fields = n; - - if (definition) - info->type_stack->definition = TRUE; - - return TRUE; -} - -/* Finish up a struct. */ - -static bfd_boolean -stab_end_struct_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - long tindex; - unsigned int size; - char *fields, *first, *buf; - - assert (info->type_stack != NULL && info->type_stack->fields != NULL); - - definition = info->type_stack->definition; - tindex = info->type_stack->index; - size = info->type_stack->size; - fields = info->type_stack->fields; - first = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2); - sprintf (buf, "%s%s;", first, fields); - free (first); - free (fields); - - if (! stab_push_string (info, buf, tindex, definition, size)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Start outputting a class. */ - -static bfd_boolean -stab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean structp, unsigned int size, bfd_boolean vptr, bfd_boolean ownvptr) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *vstring; - - if (! vptr || ownvptr) - { - definition = FALSE; - vstring = NULL; - } - else - { - definition = info->type_stack->definition; - vstring = stab_pop_type (info); - } - - if (! stab_start_struct_type (p, tag, id, structp, size)) - return FALSE; - - if (vptr) - { - char *vtable; - - if (ownvptr) - { - assert (info->type_stack->index > 0); - vtable = (char *) xmalloc (20); - sprintf (vtable, "~%%%ld", info->type_stack->index); - } - else - { - vtable = (char *) xmalloc (strlen (vstring) + 3); - sprintf (vtable, "~%%%s", vstring); - free (vstring); - } - - info->type_stack->vtable = vtable; - } - - if (definition) - info->type_stack->definition = TRUE; - - return TRUE; -} - -/* Add a static member to the class on the type stack. */ - -static bfd_boolean -stab_class_static_member (void *p, const char *name, const char *physname, - enum debug_visibility visibility) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *s, *n; - const char *vis; - - definition = info->type_stack->definition; - s = stab_pop_type (info); - - /* Add this field to the end of the current struct fields, which is - currently on the top of the stack. */ - - assert (info->type_stack->fields != NULL); - n = (char *) xmalloc (strlen (info->type_stack->fields) - + strlen (name) - + strlen (s) - + strlen (physname) - + 10); - - switch (visibility) - { - default: - abort (); - - case DEBUG_VISIBILITY_PUBLIC: - vis = ""; - break; - - case DEBUG_VISIBILITY_PRIVATE: - vis = "/0"; - break; - - case DEBUG_VISIBILITY_PROTECTED: - vis = "/1"; - break; - } - - sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s, - physname); - - free (info->type_stack->fields); - info->type_stack->fields = n; - - if (definition) - info->type_stack->definition = TRUE; - - return TRUE; -} - -/* Add a base class to the class on the type stack. */ - -static bfd_boolean -stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean is_virtual, - enum debug_visibility visibility) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - bfd_boolean definition; - char *s; - char *buf; - unsigned int c; - char **baseclasses; - - definition = info->type_stack->definition; - s = stab_pop_type (info); - - /* Build the base class specifier. */ - - buf = (char *) xmalloc (strlen (s) + 25); - buf[0] = is_virtual ? '1' : '0'; - switch (visibility) - { - default: - abort (); - - case DEBUG_VISIBILITY_PRIVATE: - buf[1] = '0'; - break; - - case DEBUG_VISIBILITY_PROTECTED: - buf[1] = '1'; - break; - - case DEBUG_VISIBILITY_PUBLIC: - buf[1] = '2'; - break; - } - - sprintf (buf + 2, "%ld,%s;", (long) bitpos, s); - free (s); - - /* Add the new baseclass to the existing ones. */ - - assert (info->type_stack != NULL && info->type_stack->fields != NULL); - - if (info->type_stack->baseclasses == NULL) - c = 0; - else - { - c = 0; - while (info->type_stack->baseclasses[c] != NULL) - ++c; - } - - baseclasses = (char **) xrealloc (info->type_stack->baseclasses, - (c + 2) * sizeof (*baseclasses)); - baseclasses[c] = buf; - baseclasses[c + 1] = NULL; - - info->type_stack->baseclasses = baseclasses; - - if (definition) - info->type_stack->definition = TRUE; - - return TRUE; -} - -/* Start adding a method to the class on the type stack. */ - -static bfd_boolean -stab_class_start_method (void *p, const char *name) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *m; - - assert (info->type_stack != NULL && info->type_stack->fields != NULL); - - if (info->type_stack->methods == NULL) - { - m = (char *) xmalloc (strlen (name) + 3); - *m = '\0'; - } - else - { - m = (char *) xrealloc (info->type_stack->methods, - (strlen (info->type_stack->methods) - + strlen (name) - + 4)); - } - - sprintf (m + strlen (m), "%s::", name); - - info->type_stack->methods = m; - - return TRUE; -} - -/* Add a variant, either static or not, to the current method. */ - -static bfd_boolean -stab_class_method_var (struct stab_write_handle *info, const char *physname, - enum debug_visibility visibility, - bfd_boolean staticp, bfd_boolean constp, - bfd_boolean volatilep, bfd_vma voffset, - bfd_boolean contextp) -{ - bfd_boolean definition; - char *type; - char *context = NULL; - char visc, qualc, typec; - - definition = info->type_stack->definition; - type = stab_pop_type (info); - - if (contextp) - { - definition = definition || info->type_stack->definition; - context = stab_pop_type (info); - } - - assert (info->type_stack != NULL && info->type_stack->methods != NULL); - - switch (visibility) - { - default: - abort (); - - case DEBUG_VISIBILITY_PRIVATE: - visc = '0'; - break; - - case DEBUG_VISIBILITY_PROTECTED: - visc = '1'; - break; - - case DEBUG_VISIBILITY_PUBLIC: - visc = '2'; - break; - } - - if (constp) - { - if (volatilep) - qualc = 'D'; - else - qualc = 'B'; - } - else - { - if (volatilep) - qualc = 'C'; - else - qualc = 'A'; - } - - if (staticp) - typec = '?'; - else if (! contextp) - typec = '.'; - else - typec = '*'; - - info->type_stack->methods = - (char *) xrealloc (info->type_stack->methods, - (strlen (info->type_stack->methods) - + strlen (type) - + strlen (physname) - + (contextp ? strlen (context) : 0) - + 40)); - - sprintf (info->type_stack->methods + strlen (info->type_stack->methods), - "%s:%s;%c%c%c", type, physname, visc, qualc, typec); - free (type); - - if (contextp) - { - sprintf (info->type_stack->methods + strlen (info->type_stack->methods), - "%ld;%s;", (long) voffset, context); - free (context); - } - - if (definition) - info->type_stack->definition = TRUE; - - return TRUE; -} - -/* Add a variant to the current method. */ - -static bfd_boolean -stab_class_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep, - bfd_vma voffset, bfd_boolean contextp) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - return stab_class_method_var (info, physname, visibility, FALSE, constp, - volatilep, voffset, contextp); -} - -/* Add a static variant to the current method. */ - -static bfd_boolean -stab_class_static_method_variant (void *p, const char *physname, - enum debug_visibility visibility, - bfd_boolean constp, bfd_boolean volatilep) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - return stab_class_method_var (info, physname, visibility, TRUE, constp, - volatilep, 0, FALSE); -} - -/* Finish up a method. */ - -static bfd_boolean -stab_class_end_method (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - assert (info->type_stack != NULL && info->type_stack->methods != NULL); - - /* We allocated enough room on info->type_stack->methods to add the - trailing semicolon. */ - strcat (info->type_stack->methods, ";"); - - return TRUE; -} - -/* Finish up a class. */ - -static bfd_boolean -stab_end_class_type (void *p) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - size_t len; - unsigned int i = 0; - char *buf; - - assert (info->type_stack != NULL && info->type_stack->fields != NULL); - - /* Work out the size we need to allocate for the class definition. */ - - len = (strlen (info->type_stack->string) - + strlen (info->type_stack->fields) - + 10); - if (info->type_stack->baseclasses != NULL) - { - len += 20; - for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) - len += strlen (info->type_stack->baseclasses[i]); - } - if (info->type_stack->methods != NULL) - len += strlen (info->type_stack->methods); - if (info->type_stack->vtable != NULL) - len += strlen (info->type_stack->vtable); - - /* Build the class definition. */ - - buf = (char *) xmalloc (len); - - strcpy (buf, info->type_stack->string); - - if (info->type_stack->baseclasses != NULL) - { - sprintf (buf + strlen (buf), "!%u,", i); - for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) - { - strcat (buf, info->type_stack->baseclasses[i]); - free (info->type_stack->baseclasses[i]); - } - free (info->type_stack->baseclasses); - info->type_stack->baseclasses = NULL; - } - - strcat (buf, info->type_stack->fields); - free (info->type_stack->fields); - info->type_stack->fields = NULL; - - if (info->type_stack->methods != NULL) - { - strcat (buf, info->type_stack->methods); - free (info->type_stack->methods); - info->type_stack->methods = NULL; - } - - strcat (buf, ";"); - - if (info->type_stack->vtable != NULL) - { - strcat (buf, info->type_stack->vtable); - free (info->type_stack->vtable); - info->type_stack->vtable = NULL; - } - - /* Replace the string on the top of the stack with the complete - class definition. */ - free (info->type_stack->string); - info->type_stack->string = buf; - - return TRUE; -} - -/* Push a typedef which was previously defined. */ - -static bfd_boolean -stab_typedef_type (void *p, const char *name) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - struct string_hash_entry *h; - - h = string_hash_lookup (&info->typedef_hash, name, FALSE, FALSE); - assert (h != NULL && h->index > 0); - - return stab_push_defined_type (info, h->index, h->size); -} - -/* Push a struct, union or class tag. */ - -static bfd_boolean -stab_tag_type (void *p, const char *name, unsigned int id, - enum debug_type_kind kind) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - long tindex; - unsigned int size = 0; - - tindex = stab_get_struct_index (info, name, id, kind, &size); - if (tindex < 0) - return FALSE; - - return stab_push_defined_type (info, tindex, size); -} - -/* Define a typedef. */ - -static bfd_boolean -stab_typdef (void *p, const char *name) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - long tindex; - unsigned int size; - char *s, *buf; - struct string_hash_entry *h; - - tindex = info->type_stack->index; - size = info->type_stack->size; - s = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); - - if (tindex > 0) - sprintf (buf, "%s:t%s", name, s); - else - { - tindex = info->type_index; - ++info->type_index; - sprintf (buf, "%s:t%ld=%s", name, tindex, s); - } - - free (s); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - - h = string_hash_lookup (&info->typedef_hash, name, TRUE, FALSE); - if (h == NULL) - { - non_fatal (_("string_hash_lookup failed: %s"), - bfd_errmsg (bfd_get_error ())); - return FALSE; - } - - /* I don't think we care about redefinitions. */ - - h->index = tindex; - h->size = size; - - return TRUE; -} - -/* Define a tag. */ - -static bfd_boolean -stab_tag (void *p, const char *tag) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *s, *buf; - - s = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3); - - sprintf (buf, "%s:T%s", tag, s); - free (s); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Define an integer constant. */ - -static bfd_boolean -stab_int_constant (void *p, const char *name, bfd_vma val) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *buf; - - buf = (char *) xmalloc (strlen (name) + 20); - sprintf (buf, "%s:c=i%ld", name, (long) val); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Define a floating point constant. */ - -static bfd_boolean -stab_float_constant (void *p, const char *name, double val) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *buf; - - buf = (char *) xmalloc (strlen (name) + 20); - sprintf (buf, "%s:c=f%g", name, val); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Define a typed constant. */ - -static bfd_boolean -stab_typed_constant (void *p, const char *name, bfd_vma val) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *s, *buf; - - s = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); - sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val); - free (s); - - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Record a variable. */ - -static bfd_boolean -stab_variable (void *p, const char *name, enum debug_var_kind kind, - bfd_vma val) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *s, *buf; - int stab_type; - const char *kindstr; - - s = stab_pop_type (info); - - switch (kind) - { - default: - abort (); - - case DEBUG_GLOBAL: - stab_type = N_GSYM; - kindstr = "G"; - break; - - case DEBUG_STATIC: - stab_type = N_STSYM; - kindstr = "S"; - break; - - case DEBUG_LOCAL_STATIC: - stab_type = N_STSYM; - kindstr = "V"; - break; - - case DEBUG_LOCAL: - stab_type = N_LSYM; - kindstr = ""; - - /* Make sure that this is a type reference or definition. */ - if (! ISDIGIT (*s)) - { - char *n; - long tindex; - - tindex = info->type_index; - ++info->type_index; - n = (char *) xmalloc (strlen (s) + 20); - sprintf (n, "%ld=%s", tindex, s); - free (s); - s = n; - } - break; - - case DEBUG_REGISTER: - stab_type = N_RSYM; - kindstr = "r"; - break; - } - - buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); - sprintf (buf, "%s:%s%s", name, kindstr, s); - free (s); - - if (! stab_write_symbol (info, stab_type, 0, val, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Start outputting a function. */ - -static bfd_boolean -stab_start_function (void *p, const char *name, bfd_boolean globalp) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *rettype, *buf; - - assert (info->nesting == 0 && info->fun_offset == -1); - - rettype = stab_pop_type (info); - - buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3); - sprintf (buf, "%s:%c%s", name, - globalp ? 'F' : 'f', - rettype); - - /* We don't know the value now, so we set it in start_block. */ - info->fun_offset = info->symbols_size; - - if (! stab_write_symbol (info, N_FUN, 0, 0, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Output a function parameter. */ - -static bfd_boolean -stab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, bfd_vma val) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - char *s, *buf; - int stab_type; - char kindc; - - s = stab_pop_type (info); - - switch (kind) - { - default: - abort (); - - case DEBUG_PARM_STACK: - stab_type = N_PSYM; - kindc = 'p'; - break; - - case DEBUG_PARM_REG: - stab_type = N_RSYM; - kindc = 'P'; - break; - - case DEBUG_PARM_REFERENCE: - stab_type = N_PSYM; - kindc = 'v'; - break; - - case DEBUG_PARM_REF_REG: - stab_type = N_RSYM; - kindc = 'a'; - break; - } - - buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); - sprintf (buf, "%s:%c%s", name, kindc, s); - free (s); - - if (! stab_write_symbol (info, stab_type, 0, val, buf)) - return FALSE; - - free (buf); - - return TRUE; -} - -/* Start a block. */ - -static bfd_boolean -stab_start_block (void *p, bfd_vma addr) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - /* Fill in any slots which have been waiting for the first known - text address. */ - - if (info->so_offset != -1) - { - bfd_put_32 (info->abfd, addr, info->symbols + info->so_offset + 8); - info->so_offset = -1; - } - - if (info->fun_offset != -1) - { - bfd_put_32 (info->abfd, addr, info->symbols + info->fun_offset + 8); - info->fun_offset = -1; - } - - ++info->nesting; - - /* We will be called with a top level block surrounding the - function, but stabs information does not output that block, so we - ignore it. */ - - if (info->nesting == 1) - { - info->fnaddr = addr; - return TRUE; - } - - /* We have to output the LBRAC symbol after any variables which are - declared inside the block. We postpone the LBRAC until the next - start_block or end_block. */ - - /* If we have postponed an LBRAC, output it now. */ - if (info->pending_lbrac != (bfd_vma) -1) - { - if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, - (const char *) NULL)) - return FALSE; - } - - /* Remember the address and output it later. */ - - info->pending_lbrac = addr - info->fnaddr; - - return TRUE; -} - -/* End a block. */ - -static bfd_boolean -stab_end_block (void *p, bfd_vma addr) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - if (addr > info->last_text_address) - info->last_text_address = addr; - - /* If we have postponed an LBRAC, output it now. */ - if (info->pending_lbrac != (bfd_vma) -1) - { - if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, - (const char *) NULL)) - return FALSE; - info->pending_lbrac = (bfd_vma) -1; - } - - assert (info->nesting > 0); - - --info->nesting; - - /* We ignore the outermost block. */ - if (info->nesting == 0) - return TRUE; - - return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr, - (const char *) NULL); -} - -/* End a function. */ - -static bfd_boolean -stab_end_function (void *p ATTRIBUTE_UNUSED) -{ - return TRUE; -} - -/* Output a line number. */ - -static bfd_boolean -stab_lineno (void *p, const char *file, unsigned long lineno, bfd_vma addr) -{ - struct stab_write_handle *info = (struct stab_write_handle *) p; - - assert (info->lineno_filename != NULL); - - if (addr > info->last_text_address) - info->last_text_address = addr; - - if (filename_cmp (file, info->lineno_filename) != 0) - { - if (! stab_write_symbol (info, N_SOL, 0, addr, file)) - return FALSE; - info->lineno_filename = file; - } - - return stab_write_symbol (info, N_SLINE, lineno, addr - info->fnaddr, - (const char *) NULL); -} diff --git a/contrib/binutils-2.22/elfcpp/README b/contrib/binutils-2.22/elfcpp/README deleted file mode 100644 index 9eb07e8c47..0000000000 --- a/contrib/binutils-2.22/elfcpp/README +++ /dev/null @@ -1,9 +0,0 @@ -elfcpp is a C++ library for reading and writing ELF information. This -was written to support gold, the ELF linker, and may not be generally -useful. - -elfcpp does not do file I/O. It deals only with offsets and memory -data. - -For efficiency, most accessors are templates with two arguments: the -ELF file class (32 or 64 bits) and the endianness. diff --git a/contrib/binutils-2.22/elfcpp/arm.h b/contrib/binutils-2.22/elfcpp/arm.h deleted file mode 100644 index cb85eeb42e..0000000000 --- a/contrib/binutils-2.22/elfcpp/arm.h +++ /dev/null @@ -1,344 +0,0 @@ -// arm.h -- ELF definitions specific to EM_ARM -*- C++ -*- - -// Copyright 2009, Free Software Foundation, Inc. -// Written by Doug Kwan . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_ARM_H -#define ELFCPP_ARM_H - -// The relocation type information is taken from: -// -// ELF for the ARM Architecture -// Document number: ARM IHI 0044C, current through ABI release 2.07 -// Date of Issue: 10th October, 2008 -// - -namespace elfcpp -{ - -// -// ARM Relocations Codes -// - -// Operation notes: -// S: Address of the symbol. -// A: Addend for relocation. -// P: Address of the place being relocated. -// Pa: Adjusted address of the place being relocated (P & 0xfffffffc) -// T: is 1 if S has type STT_FUNC and the symbol addresses a Thumb -// instruction.Thumb-bit; it is 0 otherwise. -// B(S): Addressing origin of the output segment defining S. -// GOT_ORG: Addressing origin of the Global Offset Table. -// GOT(S): Address of the GOT entry for S. -// - -enum -{ - // Type Class Operation - // ------------------------------ - R_ARM_NONE = 0, // Static Misc - R_ARM_PC24 = 1, // Deprecated ARM ((S + A) | T) - P - R_ARM_ABS32 = 2, // Static Data (S + A) | T - R_ARM_REL32 = 3, // Static Data ((S + A) | T) - P - R_ARM_LDR_PC_G0 = 4, // Static ARM S + A - P - R_ARM_ABS16 = 5, // Static Data S + A - R_ARM_ABS12 = 6, // Static ARM S + A - R_ARM_THM_ABS5 = 7, // Static Thumb16 S + A - R_ARM_ABS8 = 8, // Static Data S + A - R_ARM_SBREL32 = 9, // Static Data ((S + A) | T) - B(S) - R_ARM_THM_CALL = 10, // Static Thumb32 ((S + A) | T) - P - R_ARM_THM_PC8 = 11, // Static Thumb16 - R_ARM_BREL_ADJ = 12, // Dynamic Data DeltaB(S) + A - R_ARM_TLS_DESC = 13, // Dynamic Data - R_ARM_THM_SWI8 = 14, // Obsolete - R_ARM_XPC25 = 15, // Obsolete - R_ARM_THM_XPC22 = 16, // Obsolete - R_ARM_TLS_DTPMOD32 = 17, // Dynamic Data Module(S) - R_ARM_TLS_DTPOFF32 = 18, // Dynamic Data S + A - TLS - R_ARM_TLS_TPOFF32 = 19, // Dynamic Data S + A - tp - R_ARM_COPY = 20, // Dynamic Misc - R_ARM_GLOB_DAT = 21, // Dynamic Data (S + A) | T - R_ARM_JUMP_SLOT = 22, // Dynamic Data (S + A) | T - R_ARM_RELATIVE = 23, // Dynamic Data B(S) + A - R_ARM_GOTOFF32 = 24, // Static Data (((S + A) | T) - GOT_ORG - R_ARM_BASE_PREL = 25, // Static Data B(S) + A - P - R_ARM_GOT_BREL = 26, // Static Data GOT(S) + A - GOT_ORG - R_ARM_PLT32 = 27, // Deprecated ARM ((S + A) | T) - P - R_ARM_CALL = 28, // Static ARM ((S + A) | T) - P - R_ARM_JUMP24 = 29, // Static ARM ((S + A) | T) - P - R_ARM_THM_JUMP24 = 30, // Static Thumb32 ((S + A) | T) - P - R_ARM_BASE_ABS = 31, // Static Data B(S) + A - R_ARM_ALU_PCREL_7_0 = 32, // Obsolete - R_ARM_ALU_PCREL_15_8 = 33, // Obsolete - R_ARM_ALU_PCREL_23_15 = 34, // Obsolete - R_ARM_LDR_SBREL_11_0_NC = 35, // Deprecated ARM S + A - B(S) - R_ARM_ALU_SBREL_19_12_NC = 36,// Deprecated ARM S + A - B(S) - R_ARM_ALU_SBREL_27_20_CK = 37,// Deprecated ARM S + A - B(S) - R_ARM_TARGET1 = 38, // Data Misc (S + A) | T or - // ((S + A) | T) - P - R_ARM_SBREL31 = 39, // Deprecated Data ((S + A) | T) - B(S) - R_ARM_V4BX = 40, // Static Misc - R_ARM_TARGET2 = 41, // Static Misc - R_ARM_PREL31 = 42, // Static Data ((S + A) | T) - P - R_ARM_MOVW_ABS_NC = 43, // Static ARM (S + A) | T - R_ARM_MOVT_ABS = 44, // Static ARM S + A - R_ARM_MOVW_PREL_NC = 45, // Static ARM ((S + A) | T) - P - R_ARM_MOVT_PREL = 46, // Static ARM S + A - P - R_ARM_THM_MOVW_ABS_NC = 47, // Static Thumb32 (S + A) | T - R_ARM_THM_MOVT_ABS = 48, // Static Thumb32 S + A - P - R_ARM_THM_MOVW_PREL_NC = 49, // Static Thumb32 ((S + A) | T) - P - R_ARM_THM_MOVT_PREL = 50, // Static Thumb32 S + A - P - R_ARM_THM_JUMP19 = 51, // Static Thumb32 ((S + A) | T) - P - R_ARM_THM_JUMP6 = 52, // Static Thumb16 S + A - P - R_ARM_THM_ALU_PREL_11_0 = 53, // Static Thumb32 ((S + A) | T) - Pa - R_ARM_THM_PC12 = 54, // Static Thumb32 S + A - Pa - R_ARM_ABS32_NOI = 55, // Static Data S + A - R_ARM_REL32_NOI = 56, // Static Data S + A - P - R_ARM_ALU_PC_G0_NC = 57, // Static ARM ((S + A) | T) - P - R_ARM_ALU_PC_G0 = 58, // Static ARM ((S + A) | T) - P - R_ARM_ALU_PC_G1_NC = 59, // Static ARM ((S + A) | T) - P - R_ARM_ALU_PC_G1 = 60, // Static ARM ((S + A) | T) - P - R_ARM_ALU_PC_G2 = 61, // Static ARM ((S + A) | T) - P - R_ARM_LDR_PC_G1 = 62, // Static ARM S + A - P - R_ARM_LDR_PC_G2 = 63, // Static ARM S + A - P - R_ARM_LDRS_PC_G0 = 64, // Static ARM S + A - P - R_ARM_LDRS_PC_G1 = 65, // Static ARM S + A - P - R_ARM_LDRS_PC_G2 = 66, // Static ARM S + A - P - R_ARM_LDC_PC_G0 = 67, // Static ARM S + A - P - R_ARM_LDC_PC_G1 = 68, // Static ARM S + A - P - R_ARM_LDC_PC_G2 = 69, // Static ARM S + A - P - R_ARM_ALU_SB_G0_NC = 70, // Static ARM ((S + A) | T) - B(S) - R_ARM_ALU_SB_G0 = 71, // Static ARM ((S + A) | T) - B(S) - R_ARM_ALU_SB_G1_NC = 72, // Static ARM ((S + A) | T) - B(S) - R_ARM_ALU_SB_G1 = 73, // Static ARM ((S + A) | T) - B(S) - R_ARM_ALU_SB_G2 = 74, // Static ARM ((S + A) | T) - B(S) - R_ARM_LDR_SB_G0 = 75, // Static ARM S + A - B(S) - R_ARM_LDR_SB_G1 = 76, // Static ARM S + A - B(S) - R_ARM_LDR_SB_G2 = 77, // Static ARM S + A - B(S) - R_ARM_LDRS_SB_G0 = 78, // Static ARM S + A - B(S) - R_ARM_LDRS_SB_G1 = 79, // Static ARM S + A - B(S) - R_ARM_LDRS_SB_G2 = 80, // Static ARM S + A - B(S) - R_ARM_LDC_SB_G0 = 81, // Static ARM S + A - B(S) - R_ARM_LDC_SB_G1 = 82, // Static ARM S + A - B(S) - R_ARM_LDC_SB_G2 = 83, // Static ARM S + A - B(S) - R_ARM_MOVW_BREL_NC = 84, // Static ARM ((S + A) | T) - B(S) - R_ARM_MOVT_BREL = 85, // Static ARM S + A - B(S) - R_ARM_MOVW_BREL = 86, // Static ARM ((S + A) | T) - B(S) - R_ARM_THM_MOVW_BREL_NC = 87, // Static Thumb32 ((S + A) | T) - B(S) - R_ARM_THM_MOVT_BREL = 88, // Static Thumb32 S + A - B(S) - R_ARM_THM_MOVW_BREL = 89, // Static Thumb32 ((S + A) | T) - B(S) - R_ARM_TLS_GOTDESC = 90, // Static Data - R_ARM_TLS_CALL = 91, // Static ARM - R_ARM_TLS_DESCSEQ = 92, // Static ARM TLS relaxation - R_ARM_THM_TLS_CALL = 93, // Static Thumb32 - R_ARM_PLT32_ABS = 94, // Static Data PLT(S) + A - R_ARM_GOT_ABS = 95, // Static Data GOT(S) + A - R_ARM_GOT_PREL = 96, // Static Data GOT(S) + A - P - R_ARM_GOT_BREL12 = 97, // Static ARM GOT(S) + A - GOT_ORG - R_ARM_GOTOFF12 = 98, // Static ARM S + A - GOT_ROG - R_ARM_GOTRELAX = 99, // Static Misc - R_ARM_GNU_VTENTRY = 100, // Deprecated Data - R_ARM_GNU_VTINHERIT = 101, // Deprecated Data - R_ARM_THM_JUMP11 = 102, // Static Thumb16 S + A - P - R_ARM_THM_JUMP8 = 103, // Static Thumb16 S + A - P - R_ARM_TLS_GD32 = 104, // Static Data GOT(S) + A - P - R_ARM_TLS_LDM32 = 105, // Static Data GOT(S) + A - P - R_ARM_TLS_LDO32 = 106, // Static Data S + A - TLS - R_ARM_TLS_IE32 = 107, // Static Data GOT(S) + A - P - R_ARM_TLS_LE32 = 108, // Static Data S + A - tp - R_ARM_TLS_LDO12 = 109, // Static ARM S + A - TLS - R_ARM_TLS_LE12 = 110, // Static ARM S + A - tp - R_ARM_TLS_IE12GP = 111, // Static ARM GOT(S) + A - GOT_ORG - R_ARM_PRIVATE_0 = 112, // Private (n = 0, 1, ... 15) - R_ARM_PRIVATE_1 = 113, - R_ARM_PRIVATE_2 = 114, - R_ARM_PRIVATE_3 = 115, - R_ARM_PRIVATE_4 = 116, - R_ARM_PRIVATE_5 = 117, - R_ARM_PRIVATE_6 = 118, - R_ARM_PRIVATE_7 = 119, - R_ARM_PRIVATE_8 = 120, - R_ARM_PRIVATE_9 = 121, - R_ARM_PRIVATE_10 = 122, - R_ARM_PRIVATE_11 = 123, - R_ARM_PRIVATE_12 = 124, - R_ARM_PRIVATE_13 = 125, - R_ARM_PRIVATE_14 = 126, - R_ARM_PRIVATE_15 = 127, - R_ARM_ME_TOO = 128, // Obsolete - R_ARM_THM_TLS_DESCSEQ16 = 129,// Static Thumb16 - R_ARM_THM_TLS_DESCSEQ32 = 130,// Static Thumb32 - // 131 - 139 Unallocated - // 140 - 159 Dynamic Reserved for future allocation - // 160 - 255 Unallocated -}; - -// e_flags values used for ARM. We only support flags defined in AAELF. - -enum -{ - EF_ARM_BE8 = 0x00800000, - - // Mask to extract EABI version, not really a flag value. - EF_ARM_EABIMASK = 0xFF000000, - - EF_ARM_EABI_UNKNOWN = 0x00000000, - EF_ARM_EABI_VER1 = 0x01000000, - EF_ARM_EABI_VER2 = 0x02000000, - EF_ARM_EABI_VER3 = 0x03000000, - EF_ARM_EABI_VER4 = 0x04000000, - EF_ARM_EABI_VER5 = 0x05000000, -}; - -// Extract EABI version from flags. - -inline Elf_Word -arm_eabi_version(Elf_Word flags) -{ return flags & EF_ARM_EABIMASK; } - -// Values for the Tag_CPU_arch EABI attribute. -enum -{ - TAG_CPU_ARCH_PRE_V4, - TAG_CPU_ARCH_V4, - TAG_CPU_ARCH_V4T, - TAG_CPU_ARCH_V5T, - TAG_CPU_ARCH_V5TE, - TAG_CPU_ARCH_V5TEJ, - TAG_CPU_ARCH_V6, - TAG_CPU_ARCH_V6KZ, - TAG_CPU_ARCH_V6T2, - TAG_CPU_ARCH_V6K, - TAG_CPU_ARCH_V7, - TAG_CPU_ARCH_V6_M, - TAG_CPU_ARCH_V6S_M, - TAG_CPU_ARCH_V7E_M, - MAX_TAG_CPU_ARCH = TAG_CPU_ARCH_V7E_M, - // Pseudo-architecture to allow objects to be compatible with the subset of - // armv4t and armv6-m. This value should never be stored in object files. - TAG_CPU_ARCH_V4T_PLUS_V6_M = (MAX_TAG_CPU_ARCH + 1) -}; - -// EABI object attributes. -enum -{ - // 0-3 are generic. - Tag_CPU_raw_name = 4, - Tag_CPU_name = 5, - Tag_CPU_arch = 6, - Tag_CPU_arch_profile = 7, - Tag_ARM_ISA_use = 8, - Tag_THUMB_ISA_use = 9, - Tag_FP_arch = 10, - Tag_WMMX_arch = 11, - Tag_Advanced_SIMD_arch = 12, - Tag_PCS_config = 13, - Tag_ABI_PCS_R9_use = 14, - Tag_ABI_PCS_RW_data = 15, - Tag_ABI_PCS_RO_data = 16, - Tag_ABI_PCS_GOT_use = 17, - Tag_ABI_PCS_wchar_t = 18, - Tag_ABI_FP_rounding = 19, - Tag_ABI_FP_denormal = 20, - Tag_ABI_FP_exceptions = 21, - Tag_ABI_FP_user_exceptions = 22, - Tag_ABI_FP_number_model = 23, - Tag_ABI_align_needed = 24, - Tag_ABI_align_preserved = 25, - Tag_ABI_enum_size = 26, - Tag_ABI_HardFP_use = 27, - Tag_ABI_VFP_args = 28, - Tag_ABI_WMMX_args = 29, - Tag_ABI_optimization_goals = 30, - Tag_ABI_FP_optimization_goals = 31, - // 32 is generic (Tag_compatibility). - Tag_undefined33 = 33, - Tag_CPU_unaligned_access = 34, - Tag_undefined35 = 35, - Tag_FP_HP_extension = 36, - Tag_undefined37 = 37, - Tag_ABI_FP_16bit_format = 38, - Tag_undefined39 = 39, - Tag_undefined40 = 40, - Tag_undefined41 = 41, - Tag_MPextension_use = 42, - Tag_undefined43 = 43, - Tag_DIV_use = 44, - Tag_nodefaults = 64, - Tag_also_compatible_with = 65, - Tag_T2EE_use = 66, - Tag_conformance = 67, - Tag_Virtualization_use = 68, - Tag_undefined69 = 69, - Tag_MPextension_use_legacy = 70, - - // The following tags are legacy names for other tags. - Tag_VFP_arch = Tag_FP_arch, - Tag_ABI_align8_needed = Tag_ABI_align_needed, - Tag_ABI_align8_preserved = Tag_ABI_align_preserved, - Tag_VFP_HP_extension = Tag_FP_HP_extension -}; - -// Values for Tag_ABI_PCS_R9_use. -enum -{ - AEABI_R9_V6 = 0, - AEABI_R9_SB = 1, - AEABI_R9_TLS = 2, - AEABI_R9_unused = 3 -}; - -// Values for Tag_ABI_PCS_RW_data. -enum -{ - AEABI_PCS_RW_data_absolute = 0, - AEABI_PCS_RW_data_PCrel = 1, - AEABI_PCS_RW_data_SBrel = 2, - AEABI_PCS_RW_data_unused = 3 -}; - -// Values for Tag_ABI_enum_size. -enum -{ - AEABI_enum_unused = 0, - AEABI_enum_short = 1, - AEABI_enum_wide = 2, - AEABI_enum_forced_wide = 3 -}; - -// For Exception Index Table. (Exception handling ABI for the ARM -// architectue, Section 5) -enum -{ - EXIDX_CANTUNWIND = 1, -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_ARM_H) diff --git a/contrib/binutils-2.22/elfcpp/dwarf.h b/contrib/binutils-2.22/elfcpp/dwarf.h deleted file mode 100644 index d599c9750b..0000000000 --- a/contrib/binutils-2.22/elfcpp/dwarf.h +++ /dev/null @@ -1,454 +0,0 @@ -// dwarf.h -- DWARF2 constants -*- C++ -*- - -// Copyright 2006, 2007, 2008, 2011 Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_DWARF_H -#define ELFCPP_DWARF_H - -namespace elfcpp -{ - -// DWARF2 codes. - -enum DW_TAG -{ - DW_TAG_padding = 0x00, - 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, - 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, - - // DWARF3. - DW_TAG_dwarf_procedure = 0x36, - DW_TAG_restrict_type = 0x37, - DW_TAG_interface_type = 0x38, - DW_TAG_namespace = 0x39, - DW_TAG_imported_module = 0x3a, - DW_TAG_unspecified_type = 0x3b, - DW_TAG_partial_unit = 0x3c, - DW_TAG_imported_unit = 0x3d, - DW_TAG_condition = 0x3f, - DW_TAG_shared_type = 0x40, - - // SGI/MIPS extensions. - DW_TAG_MIPS_loop = 0x4081, - - // HP extensions. - // See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz. - DW_TAG_HP_array_descriptor = 0x4090, - - // GNU extensions. - DW_TAG_format_label = 0x4101, // For FORTRAN 77 and Fortran 90. - DW_TAG_function_template = 0x4102, // For C++. - DW_TAG_class_template = 0x4103, // For C++. - DW_TAG_GNU_BINCL = 0x4104, - DW_TAG_GNU_EINCL = 0x4105, - - // Extensions for UPC. See: http://upc.gwu.edu/~upc. - DW_TAG_upc_shared_type = 0x8765, - DW_TAG_upc_strict_type = 0x8766, - DW_TAG_upc_relaxed_type = 0x8767, - - // PGI (STMicroelectronics) extensions. No documentation available. - DW_TAG_PGI_kanji_type = 0xA000, - DW_TAG_PGI_interface_block = 0xA020 -}; - -enum DW_FORM -{ - DW_FORM_null = 0x00, - DW_FORM_addr = 0x01, - DW_FORM_block2 = 0x03, - DW_FORM_block4 = 0x04, - DW_FORM_data2 = 0x05, - DW_FORM_data4 = 0x06, - DW_FORM_data8 = 0x07, - DW_FORM_string = 0x08, - DW_FORM_block = 0x09, - DW_FORM_block1 = 0x0a, - DW_FORM_data1 = 0x0b, - DW_FORM_flag = 0x0c, - DW_FORM_sdata = 0x0d, - DW_FORM_strp = 0x0e, - DW_FORM_udata = 0x0f, - DW_FORM_ref_addr = 0x10, - DW_FORM_ref1 = 0x11, - DW_FORM_ref2 = 0x12, - DW_FORM_ref4 = 0x13, - DW_FORM_ref8 = 0x14, - DW_FORM_ref_udata = 0x15, - DW_FORM_indirect = 0x16 -}; - -// Frame unwind information. - -enum DW_EH_PE -{ - DW_EH_PE_absptr = 0x00, - DW_EH_PE_omit = 0xff, - - DW_EH_PE_uleb128 = 0x01, - DW_EH_PE_udata2 = 0x02, - DW_EH_PE_udata4 = 0x03, - DW_EH_PE_udata8 = 0x04, - DW_EH_PE_signed = 0x08, - DW_EH_PE_sleb128 = 0x09, - DW_EH_PE_sdata2 = 0x0a, - DW_EH_PE_sdata4 = 0x0b, - DW_EH_PE_sdata8 = 0x0c, - - DW_EH_PE_pcrel = 0x10, - DW_EH_PE_textrel = 0x20, - DW_EH_PE_datarel = 0x30, - DW_EH_PE_funcrel = 0x40, - DW_EH_PE_aligned = 0x50, - - DW_EH_PE_indirect = 0x80 -}; - -// Line number opcodes. - -enum DW_LINE_OPS -{ - DW_LNS_extended_op = 0, - 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, - // DWARF 3. - DW_LNS_set_prologue_end = 10, - DW_LNS_set_epilogue_begin = 11, - DW_LNS_set_isa = 12 -}; - -// Line number extended opcodes. - -enum DW_LINE_EXTENDED_OPS -{ - DW_LNE_end_sequence = 1, - DW_LNE_set_address = 2, - DW_LNE_define_file = 3, - // HP extensions. - DW_LNE_HP_negate_is_UV_update = 0x11, - DW_LNE_HP_push_context = 0x12, - DW_LNE_HP_pop_context = 0x13, - DW_LNE_HP_set_file_line_column = 0x14, - DW_LNE_HP_set_routine_name = 0x15, - DW_LNE_HP_set_sequence = 0x16, - DW_LNE_HP_negate_post_semantics = 0x17, - DW_LNE_HP_negate_function_exit = 0x18, - DW_LNE_HP_negate_front_end_logical = 0x19, - DW_LNE_HP_define_proc = 0x20 -}; - -// Type encoding names and codes - -enum DW_ENCODING -{ - 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, - // DWARF3/DWARF3f - DW_ATE_imaginary_float =0x9, - DW_ATE_packed_decimal =0xa, - DW_ATE_numeric_string =0xb, - DW_ATE_edited =0xc, - DW_ATE_signed_fixed =0xd, - DW_ATE_unsigned_fixed =0xe, - DW_ATE_decimal_float =0xf, - DW_ATE_lo_user =0x80, - DW_ATE_hi_user =0xff -}; - -// Location virtual machine opcodes - -enum DW_OP -{ - DW_OP_addr =0x03, - DW_OP_deref =0x06, - DW_OP_const1u =0x08, - DW_OP_const1s =0x09, - DW_OP_const2u =0x0a, - DW_OP_const2s =0x0b, - DW_OP_const4u =0x0c, - DW_OP_const4s =0x0d, - DW_OP_const8u =0x0e, - DW_OP_const8s =0x0f, - DW_OP_constu =0x10, - DW_OP_consts =0x11, - DW_OP_dup =0x12, - DW_OP_drop =0x13, - DW_OP_over =0x14, - DW_OP_pick =0x15, - DW_OP_swap =0x16, - DW_OP_rot =0x17, - DW_OP_xderef =0x18, - DW_OP_abs =0x19, - DW_OP_and =0x1a, - DW_OP_div =0x1b, - DW_OP_minus =0x1c, - DW_OP_mod =0x1d, - DW_OP_mul =0x1e, - DW_OP_neg =0x1f, - DW_OP_not =0x20, - DW_OP_or =0x21, - DW_OP_plus =0x22, - DW_OP_plus_uconst =0x23, - DW_OP_shl =0x24, - DW_OP_shr =0x25, - DW_OP_shra =0x26, - DW_OP_xor =0x27, - DW_OP_bra =0x28, - DW_OP_eq =0x29, - DW_OP_ge =0x2a, - DW_OP_gt =0x2b, - DW_OP_le =0x2c, - DW_OP_lt =0x2d, - DW_OP_ne =0x2e, - DW_OP_skip =0x2f, - DW_OP_lit0 =0x30, - DW_OP_lit1 =0x31, - DW_OP_lit2 =0x32, - DW_OP_lit3 =0x33, - DW_OP_lit4 =0x34, - DW_OP_lit5 =0x35, - DW_OP_lit6 =0x36, - DW_OP_lit7 =0x37, - DW_OP_lit8 =0x38, - DW_OP_lit9 =0x39, - DW_OP_lit10 =0x3a, - DW_OP_lit11 =0x3b, - DW_OP_lit12 =0x3c, - DW_OP_lit13 =0x3d, - DW_OP_lit14 =0x3e, - DW_OP_lit15 =0x3f, - DW_OP_lit16 =0x40, - DW_OP_lit17 =0x41, - DW_OP_lit18 =0x42, - DW_OP_lit19 =0x43, - DW_OP_lit20 =0x44, - DW_OP_lit21 =0x45, - DW_OP_lit22 =0x46, - DW_OP_lit23 =0x47, - DW_OP_lit24 =0x48, - DW_OP_lit25 =0x49, - DW_OP_lit26 =0x4a, - DW_OP_lit27 =0x4b, - DW_OP_lit28 =0x4c, - DW_OP_lit29 =0x4d, - DW_OP_lit30 =0x4e, - DW_OP_lit31 =0x4f, - DW_OP_reg0 =0x50, - DW_OP_reg1 =0x51, - DW_OP_reg2 =0x52, - DW_OP_reg3 =0x53, - DW_OP_reg4 =0x54, - DW_OP_reg5 =0x55, - DW_OP_reg6 =0x56, - DW_OP_reg7 =0x57, - DW_OP_reg8 =0x58, - DW_OP_reg9 =0x59, - DW_OP_reg10 =0x5a, - DW_OP_reg11 =0x5b, - DW_OP_reg12 =0x5c, - DW_OP_reg13 =0x5d, - DW_OP_reg14 =0x5e, - DW_OP_reg15 =0x5f, - DW_OP_reg16 =0x60, - DW_OP_reg17 =0x61, - DW_OP_reg18 =0x62, - DW_OP_reg19 =0x63, - DW_OP_reg20 =0x64, - DW_OP_reg21 =0x65, - DW_OP_reg22 =0x66, - DW_OP_reg23 =0x67, - DW_OP_reg24 =0x68, - DW_OP_reg25 =0x69, - DW_OP_reg26 =0x6a, - DW_OP_reg27 =0x6b, - DW_OP_reg28 =0x6c, - DW_OP_reg29 =0x6d, - DW_OP_reg30 =0x6e, - DW_OP_reg31 =0x6f, - DW_OP_breg0 =0x70, - DW_OP_breg1 =0x71, - DW_OP_breg2 =0x72, - DW_OP_breg3 =0x73, - DW_OP_breg4 =0x74, - DW_OP_breg5 =0x75, - DW_OP_breg6 =0x76, - DW_OP_breg7 =0x77, - DW_OP_breg8 =0x78, - DW_OP_breg9 =0x79, - DW_OP_breg10 =0x7a, - DW_OP_breg11 =0x7b, - DW_OP_breg12 =0x7c, - DW_OP_breg13 =0x7d, - DW_OP_breg14 =0x7e, - DW_OP_breg15 =0x7f, - DW_OP_breg16 =0x80, - DW_OP_breg17 =0x81, - DW_OP_breg18 =0x82, - DW_OP_breg19 =0x83, - DW_OP_breg20 =0x84, - DW_OP_breg21 =0x85, - DW_OP_breg22 =0x86, - DW_OP_breg23 =0x87, - DW_OP_breg24 =0x88, - DW_OP_breg25 =0x89, - DW_OP_breg26 =0x8a, - DW_OP_breg27 =0x8b, - DW_OP_breg28 =0x8c, - DW_OP_breg29 =0x8d, - DW_OP_breg30 =0x8e, - DW_OP_breg31 =0x8f, - DW_OP_regX =0x90, - DW_OP_fbreg =0x91, - DW_OP_bregX =0x92, - DW_OP_piece =0x93, - DW_OP_deref_size =0x94, - DW_OP_xderef_size =0x95, - DW_OP_nop =0x96, - // DWARF3/DWARF3f - DW_OP_push_object_address =0x97, - DW_OP_call2 =0x98, - DW_OP_call4 =0x99, - DW_OP_call_ref =0x9a, - DW_OP_form_tls_address =0x9b, - DW_OP_call_frame_cfa =0x9c, - DW_OP_bit_piece =0x9d, - DW_OP_lo_user =0xe0, - DW_OP_hi_user =0xff, - // GNU extensions - DW_OP_GNU_push_tls_address =0xe0 -}; - -// Call frame information. - -enum DW_CFA -{ - DW_CFA_advance_loc = 0x40, - DW_CFA_offset = 0x80, - DW_CFA_restore = 0xc0, - - DW_CFA_nop = 0x00, - DW_CFA_set_loc = 0x01, - DW_CFA_advance_loc1 = 0x02, - DW_CFA_advance_loc2 = 0x03, - DW_CFA_advance_loc4 = 0x04, - DW_CFA_offset_extended = 0x05, - DW_CFA_restore_extended = 0x06, - DW_CFA_undefined = 0x07, - DW_CFA_same_value = 0x08, - DW_CFA_register = 0x09, - DW_CFA_remember_state = 0x0a, - DW_CFA_restore_state = 0x0b, - DW_CFA_def_cfa = 0x0c, - DW_CFA_def_cfa_register = 0x0d, - DW_CFA_def_cfa_offset = 0x0e, - - // DWARF 3. - DW_CFA_def_cfa_expression = 0x0f, - DW_CFA_expression = 0x10, - DW_CFA_offset_extended_sf = 0x11, - DW_CFA_def_cfa_sf = 0x12, - DW_CFA_def_cfa_offset_sf = 0x13, - DW_CFA_val_offset = 0x14, - DW_CFA_val_offset_sf = 0x15, - DW_CFA_val_expression = 0x16, - - DW_CFA_lo_user = 0x1c, - DW_CFA_hi_user = 0x3f, - - // SGI/MIPS specific. - DW_CFA_MIPS_advance_loc8 = 0x1d, - - // GNU extensions. - DW_CFA_GNU_window_save = 0x2d, - DW_CFA_GNU_args_size = 0x2e, - DW_CFA_GNU_negative_offset_extended = 0x2f -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_DWARF_H) diff --git a/contrib/binutils-2.22/elfcpp/elfcpp.h b/contrib/binutils-2.22/elfcpp/elfcpp.h deleted file mode 100644 index 7a70765327..0000000000 --- a/contrib/binutils-2.22/elfcpp/elfcpp.h +++ /dev/null @@ -1,1812 +0,0 @@ -// elfcpp.h -- main header file for elfcpp -*- C++ -*- - -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -// This is the external interface for elfcpp. - -#ifndef ELFCPP_H -#define ELFCPP_H - -#include "elfcpp_swap.h" - -#include - -namespace elfcpp -{ - -// Basic ELF types. - -// These types are always the same size. - -typedef uint16_t Elf_Half; -typedef uint32_t Elf_Word; -typedef int32_t Elf_Sword; -typedef uint64_t Elf_Xword; -typedef int64_t Elf_Sxword; - -// These types vary in size depending on the ELF file class. The -// template parameter should be 32 or 64. - -template -struct Elf_types; - -template<> -struct Elf_types<32> -{ - typedef uint32_t Elf_Addr; - typedef uint32_t Elf_Off; - typedef uint32_t Elf_WXword; - typedef int32_t Elf_Swxword; -}; - -template<> -struct Elf_types<64> -{ - typedef uint64_t Elf_Addr; - typedef uint64_t Elf_Off; - typedef uint64_t Elf_WXword; - typedef int64_t Elf_Swxword; -}; - -// Offsets within the Ehdr e_ident field. - -const int EI_MAG0 = 0; -const int EI_MAG1 = 1; -const int EI_MAG2 = 2; -const int EI_MAG3 = 3; -const int EI_CLASS = 4; -const int EI_DATA = 5; -const int EI_VERSION = 6; -const int EI_OSABI = 7; -const int EI_ABIVERSION = 8; -const int EI_PAD = 9; -const int EI_NIDENT = 16; - -// The valid values found in Ehdr e_ident[EI_MAG0 through EI_MAG3]. - -const int ELFMAG0 = 0x7f; -const int ELFMAG1 = 'E'; -const int ELFMAG2 = 'L'; -const int ELFMAG3 = 'F'; - -// The valid values found in Ehdr e_ident[EI_CLASS]. - -enum -{ - ELFCLASSNONE = 0, - ELFCLASS32 = 1, - ELFCLASS64 = 2 -}; - -// The valid values found in Ehdr e_ident[EI_DATA]. - -enum -{ - ELFDATANONE = 0, - ELFDATA2LSB = 1, - ELFDATA2MSB = 2 -}; - -// The valid values found in Ehdr e_ident[EI_VERSION] and e_version. - -enum -{ - EV_NONE = 0, - EV_CURRENT = 1 -}; - -// The valid values found in Ehdr e_ident[EI_OSABI]. - -enum ELFOSABI -{ - ELFOSABI_NONE = 0, - ELFOSABI_HPUX = 1, - ELFOSABI_NETBSD = 2, - ELFOSABI_GNU = 3, - // ELFOSABI_LINUX is an alias for ELFOSABI_GNU. - ELFOSABI_LINUX = 3, - ELFOSABI_SOLARIS = 6, - ELFOSABI_AIX = 7, - ELFOSABI_IRIX = 8, - ELFOSABI_FREEBSD = 9, - ELFOSABI_TRU64 = 10, - ELFOSABI_MODESTO = 11, - ELFOSABI_OPENBSD = 12, - ELFOSABI_OPENVMS = 13, - ELFOSABI_NSK = 14, - ELFOSABI_AROS = 15, - // A GNU extension for the ARM. - ELFOSABI_ARM = 97, - // A GNU extension for the MSP. - ELFOSABI_STANDALONE = 255 -}; - -// The valid values found in the Ehdr e_type field. - -enum ET -{ - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, - ET_LOOS = 0xfe00, - ET_HIOS = 0xfeff, - ET_LOPROC = 0xff00, - ET_HIPROC = 0xffff -}; - -// The valid values found in the Ehdr e_machine field. - -enum EM -{ - EM_NONE = 0, - EM_M32 = 1, - EM_SPARC = 2, - EM_386 = 3, - EM_68K = 4, - EM_88K = 5, - // 6 used to be EM_486 - EM_860 = 7, - EM_MIPS = 8, - EM_S370 = 9, - EM_MIPS_RS3_LE = 10, - // 11 was the old Sparc V9 ABI. - // 12 through 14 are reserved. - EM_PARISC = 15, - // 16 is reserved. - // Some old PowerPC object files use 17. - EM_VPP500 = 17, - EM_SPARC32PLUS = 18, - EM_960 = 19, - EM_PPC = 20, - EM_PPC64 = 21, - EM_S390 = 22, - // 23 through 35 are served. - EM_V800 = 36, - EM_FR20 = 37, - EM_RH32 = 38, - EM_RCE = 39, - EM_ARM = 40, - EM_ALPHA = 41, - EM_SH = 42, - EM_SPARCV9 = 43, - EM_TRICORE = 44, - EM_ARC = 45, - EM_H8_300 = 46, - EM_H8_300H = 47, - EM_H8S = 48, - EM_H8_500 = 49, - EM_IA_64 = 50, - EM_MIPS_X = 51, - EM_COLDFIRE = 52, - EM_68HC12 = 53, - EM_MMA = 54, - EM_PCP = 55, - EM_NCPU = 56, - EM_NDR1 = 57, - EM_STARCORE = 58, - EM_ME16 = 59, - EM_ST100 = 60, - EM_TINYJ = 61, - EM_X86_64 = 62, - EM_PDSP = 63, - EM_PDP10 = 64, - EM_PDP11 = 65, - EM_FX66 = 66, - EM_ST9PLUS = 67, - EM_ST7 = 68, - EM_68HC16 = 69, - EM_68HC11 = 70, - EM_68HC08 = 71, - EM_68HC05 = 72, - EM_SVX = 73, - EM_ST19 = 74, - EM_VAX = 75, - EM_CRIS = 76, - EM_JAVELIN = 77, - EM_FIREPATH = 78, - EM_ZSP = 79, - EM_MMIX = 80, - EM_HUANY = 81, - EM_PRISM = 82, - EM_AVR = 83, - EM_FR30 = 84, - EM_D10V = 85, - EM_D30V = 86, - EM_V850 = 87, - EM_M32R = 88, - EM_MN10300 = 89, - EM_MN10200 = 90, - EM_PJ = 91, - EM_OPENRISC = 92, - EM_ARC_A5 = 93, - EM_XTENSA = 94, - EM_VIDEOCORE = 95, - EM_TMM_GPP = 96, - EM_NS32K = 97, - EM_TPC = 98, - // Some old picoJava object files use 99 (EM_PJ is correct). - EM_SNP1K = 99, - EM_ST200 = 100, - EM_IP2K = 101, - EM_MAX = 102, - EM_CR = 103, - EM_F2MC16 = 104, - EM_MSP430 = 105, - EM_BLACKFIN = 106, - EM_SE_C33 = 107, - EM_SEP = 108, - EM_ARCA = 109, - EM_UNICORE = 110, - EM_ALTERA_NIOS2 = 113, - EM_CRX = 114, - // The Morph MT. - EM_MT = 0x2530, - // DLX. - EM_DLX = 0x5aa5, - // FRV. - EM_FRV = 0x5441, - // Infineon Technologies 16-bit microcontroller with C166-V2 core. - EM_X16X = 0x4688, - // Xstorym16 - EM_XSTORMY16 = 0xad45, - // Renesas M32C - EM_M32C = 0xfeb0, - // Vitesse IQ2000 - EM_IQ2000 = 0xfeba, - // NIOS - EM_NIOS32 = 0xfebb - // Old AVR objects used 0x1057 (EM_AVR is correct). - // Old MSP430 objects used 0x1059 (EM_MSP430 is correct). - // Old FR30 objects used 0x3330 (EM_FR30 is correct). - // Old OpenRISC objects used 0x3426 and 0x8472 (EM_OPENRISC is correct). - // Old D10V objects used 0x7650 (EM_D10V is correct). - // Old D30V objects used 0x7676 (EM_D30V is correct). - // Old IP2X objects used 0x8217 (EM_IP2K is correct). - // Old PowerPC objects used 0x9025 (EM_PPC is correct). - // Old Alpha objects used 0x9026 (EM_ALPHA is correct). - // Old M32R objects used 0x9041 (EM_M32R is correct). - // Old V850 objects used 0x9080 (EM_V850 is correct). - // Old S/390 objects used 0xa390 (EM_S390 is correct). - // Old Xtensa objects used 0xabc7 (EM_XTENSA is correct). - // Old MN10300 objects used 0xbeef (EM_MN10300 is correct). - // Old MN10200 objects used 0xdead (EM_MN10200 is correct). -}; - -// A special value found in the Ehdr e_phnum field. - -enum -{ - // Number of program segments stored in sh_info field of first - // section headre. - PN_XNUM = 0xffff -}; - -// Special section indices. - -enum -{ - SHN_UNDEF = 0, - SHN_LORESERVE = 0xff00, - SHN_LOPROC = 0xff00, - SHN_HIPROC = 0xff1f, - SHN_LOOS = 0xff20, - SHN_HIOS = 0xff3f, - SHN_ABS = 0xfff1, - SHN_COMMON = 0xfff2, - SHN_XINDEX = 0xffff, - SHN_HIRESERVE = 0xffff, - - // Provide for initial and final section ordering in conjunction - // with the SHF_LINK_ORDER and SHF_ORDERED section flags. - SHN_BEFORE = 0xff00, - SHN_AFTER = 0xff01, - - // x86_64 specific large common symbol. - SHN_X86_64_LCOMMON = 0xff02 -}; - -// The valid values found in the Shdr sh_type field. - -enum SHT -{ - SHT_NULL = 0, - SHT_PROGBITS = 1, - SHT_SYMTAB = 2, - SHT_STRTAB = 3, - SHT_RELA = 4, - SHT_HASH = 5, - SHT_DYNAMIC = 6, - SHT_NOTE = 7, - SHT_NOBITS = 8, - SHT_REL = 9, - SHT_SHLIB = 10, - SHT_DYNSYM = 11, - SHT_INIT_ARRAY = 14, - SHT_FINI_ARRAY = 15, - SHT_PREINIT_ARRAY = 16, - SHT_GROUP = 17, - SHT_SYMTAB_SHNDX = 18, - SHT_LOOS = 0x60000000, - SHT_HIOS = 0x6fffffff, - SHT_LOPROC = 0x70000000, - SHT_HIPROC = 0x7fffffff, - SHT_LOUSER = 0x80000000, - SHT_HIUSER = 0xffffffff, - // The remaining values are not in the standard. - // Incremental build data. - SHT_GNU_INCREMENTAL_INPUTS = 0x6fff4700, - SHT_GNU_INCREMENTAL_SYMTAB = 0x6fff4701, - SHT_GNU_INCREMENTAL_RELOCS = 0x6fff4702, - SHT_GNU_INCREMENTAL_GOT_PLT = 0x6fff4703, - // Object attributes. - SHT_GNU_ATTRIBUTES = 0x6ffffff5, - // GNU style dynamic hash table. - SHT_GNU_HASH = 0x6ffffff6, - // List of prelink dependencies. - SHT_GNU_LIBLIST = 0x6ffffff7, - // Versions defined by file. - SHT_SUNW_verdef = 0x6ffffffd, - SHT_GNU_verdef = 0x6ffffffd, - // Versions needed by file. - SHT_SUNW_verneed = 0x6ffffffe, - SHT_GNU_verneed = 0x6ffffffe, - // Symbol versions, - SHT_SUNW_versym = 0x6fffffff, - SHT_GNU_versym = 0x6fffffff, - - SHT_SPARC_GOTDATA = 0x70000000, - - // ARM-specific section types. - // Exception Index table. - SHT_ARM_EXIDX = 0x70000001, - // BPABI DLL dynamic linking pre-emption map. - SHT_ARM_PREEMPTMAP = 0x70000002, - // Object file compatibility attributes. - SHT_ARM_ATTRIBUTES = 0x70000003, - // Support for debugging overlaid programs. - SHT_ARM_DEBUGOVERLAY = 0x70000004, - SHT_ARM_OVERLAYSECTION = 0x70000005, - - // x86_64 unwind information. - SHT_X86_64_UNWIND = 0x70000001, - - // Link editor is to sort the entries in this section based on the - // address specified in the associated symbol table entry. - SHT_ORDERED = 0x7fffffff -}; - -// The valid bit flags found in the Shdr sh_flags field. - -enum SHF -{ - SHF_WRITE = 0x1, - SHF_ALLOC = 0x2, - SHF_EXECINSTR = 0x4, - SHF_MERGE = 0x10, - SHF_STRINGS = 0x20, - SHF_INFO_LINK = 0x40, - SHF_LINK_ORDER = 0x80, - SHF_OS_NONCONFORMING = 0x100, - SHF_GROUP = 0x200, - SHF_TLS = 0x400, - SHF_MASKOS = 0x0ff00000, - SHF_MASKPROC = 0xf0000000, - - // Indicates this section requires ordering in relation to - // other sections of the same type. Ordered sections are - // combined within the section pointed to by the sh_link entry. - // The sh_info values SHN_BEFORE and SHN_AFTER imply that the - // sorted section is to precede or follow, respectively, all - // other sections in the set being ordered. - SHF_ORDERED = 0x40000000, - // This section is excluded from input to the link-edit of an - // executable or shared object. This flag is ignored if SHF_ALLOC - // is also set, or if relocations exist against the section. - SHF_EXCLUDE = 0x80000000, - - // x86_64 specific large section. - SHF_X86_64_LARGE = 0x10000000 -}; - -// Bit flags which appear in the first 32-bit word of the section data -// of a SHT_GROUP section. - -enum -{ - GRP_COMDAT = 0x1, - GRP_MASKOS = 0x0ff00000, - GRP_MASKPROC = 0xf0000000 -}; - -// The valid values found in the Phdr p_type field. - -enum PT -{ - PT_NULL = 0, - PT_LOAD = 1, - PT_DYNAMIC = 2, - PT_INTERP = 3, - PT_NOTE = 4, - PT_SHLIB = 5, - PT_PHDR = 6, - PT_TLS = 7, - PT_LOOS = 0x60000000, - PT_HIOS = 0x6fffffff, - PT_LOPROC = 0x70000000, - PT_HIPROC = 0x7fffffff, - // The remaining values are not in the standard. - // Frame unwind information. - PT_GNU_EH_FRAME = 0x6474e550, - PT_SUNW_EH_FRAME = 0x6474e550, - // Stack flags. - PT_GNU_STACK = 0x6474e551, - // Read only after relocation. - PT_GNU_RELRO = 0x6474e552, - // Platform architecture compatibility information - PT_ARM_ARCHEXT = 0x70000000, - // Exception unwind tables - PT_ARM_EXIDX = 0x70000001 -}; - -// The valid bit flags found in the Phdr p_flags field. - -enum PF -{ - PF_X = 0x1, - PF_W = 0x2, - PF_R = 0x4, - PF_MASKOS = 0x0ff00000, - PF_MASKPROC = 0xf0000000 -}; - -// Symbol binding from Sym st_info field. - -enum STB -{ - STB_LOCAL = 0, - STB_GLOBAL = 1, - STB_WEAK = 2, - STB_LOOS = 10, - STB_GNU_UNIQUE = 10, - STB_HIOS = 12, - STB_LOPROC = 13, - STB_HIPROC = 15 -}; - -// Symbol types from Sym st_info field. - -enum STT -{ - STT_NOTYPE = 0, - STT_OBJECT = 1, - STT_FUNC = 2, - STT_SECTION = 3, - STT_FILE = 4, - STT_COMMON = 5, - STT_TLS = 6, - STT_LOOS = 10, - STT_GNU_IFUNC = 10, - STT_HIOS = 12, - STT_LOPROC = 13, - STT_HIPROC = 15, - - // The section type that must be used for register symbols on - // Sparc. These symbols initialize a global register. - STT_SPARC_REGISTER = 13, - - // ARM: a THUMB function. This is not defined in ARM ELF Specification but - // used by the GNU tool-chain. - STT_ARM_TFUNC = 13 -}; - -inline STB -elf_st_bind(unsigned char info) -{ - return static_cast(info >> 4); -} - -inline STT -elf_st_type(unsigned char info) -{ - return static_cast(info & 0xf); -} - -inline unsigned char -elf_st_info(STB bind, STT type) -{ - return ((static_cast(bind) << 4) - + (static_cast(type) & 0xf)); -} - -// Symbol visibility from Sym st_other field. - -enum STV -{ - STV_DEFAULT = 0, - STV_INTERNAL = 1, - STV_HIDDEN = 2, - STV_PROTECTED = 3 -}; - -inline STV -elf_st_visibility(unsigned char other) -{ - return static_cast(other & 0x3); -} - -inline unsigned char -elf_st_nonvis(unsigned char other) -{ - return static_cast(other >> 2); -} - -inline unsigned char -elf_st_other(STV vis, unsigned char nonvis) -{ - return ((nonvis << 2) - + (static_cast(vis) & 3)); -} - -// Reloc information from Rel/Rela r_info field. - -template -unsigned int -elf_r_sym(typename Elf_types::Elf_WXword); - -template<> -inline unsigned int -elf_r_sym<32>(Elf_Word v) -{ - return v >> 8; -} - -template<> -inline unsigned int -elf_r_sym<64>(Elf_Xword v) -{ - return v >> 32; -} - -template -unsigned int -elf_r_type(typename Elf_types::Elf_WXword); - -template<> -inline unsigned int -elf_r_type<32>(Elf_Word v) -{ - return v & 0xff; -} - -template<> -inline unsigned int -elf_r_type<64>(Elf_Xword v) -{ - return v & 0xffffffff; -} - -template -typename Elf_types::Elf_WXword -elf_r_info(unsigned int s, unsigned int t); - -template<> -inline Elf_Word -elf_r_info<32>(unsigned int s, unsigned int t) -{ - return (s << 8) + (t & 0xff); -} - -template<> -inline Elf_Xword -elf_r_info<64>(unsigned int s, unsigned int t) -{ - return (static_cast(s) << 32) + (t & 0xffffffff); -} - -// Dynamic tags found in the PT_DYNAMIC segment. - -enum DT -{ - DT_NULL = 0, - DT_NEEDED = 1, - DT_PLTRELSZ = 2, - DT_PLTGOT = 3, - DT_HASH = 4, - DT_STRTAB = 5, - DT_SYMTAB = 6, - DT_RELA = 7, - DT_RELASZ = 8, - DT_RELAENT = 9, - DT_STRSZ = 10, - DT_SYMENT = 11, - DT_INIT = 12, - DT_FINI = 13, - DT_SONAME = 14, - DT_RPATH = 15, - DT_SYMBOLIC = 16, - DT_REL = 17, - DT_RELSZ = 18, - DT_RELENT = 19, - DT_PLTREL = 20, - DT_DEBUG = 21, - DT_TEXTREL = 22, - DT_JMPREL = 23, - DT_BIND_NOW = 24, - DT_INIT_ARRAY = 25, - DT_FINI_ARRAY = 26, - DT_INIT_ARRAYSZ = 27, - DT_FINI_ARRAYSZ = 28, - DT_RUNPATH = 29, - DT_FLAGS = 30, - - // This is used to mark a range of dynamic tags. It is not really - // a tag value. - DT_ENCODING = 32, - - DT_PREINIT_ARRAY = 32, - DT_PREINIT_ARRAYSZ = 33, - DT_LOOS = 0x6000000d, - DT_HIOS = 0x6ffff000, - DT_LOPROC = 0x70000000, - DT_HIPROC = 0x7fffffff, - - // The remaining values are extensions used by GNU or Solaris. - DT_VALRNGLO = 0x6ffffd00, - DT_GNU_PRELINKED = 0x6ffffdf5, - DT_GNU_CONFLICTSZ = 0x6ffffdf6, - DT_GNU_LIBLISTSZ = 0x6ffffdf7, - DT_CHECKSUM = 0x6ffffdf8, - DT_PLTPADSZ = 0x6ffffdf9, - DT_MOVEENT = 0x6ffffdfa, - DT_MOVESZ = 0x6ffffdfb, - DT_FEATURE = 0x6ffffdfc, - DT_POSFLAG_1 = 0x6ffffdfd, - DT_SYMINSZ = 0x6ffffdfe, - DT_SYMINENT = 0x6ffffdff, - DT_VALRNGHI = 0x6ffffdff, - - DT_ADDRRNGLO = 0x6ffffe00, - DT_GNU_HASH = 0x6ffffef5, - DT_TLSDESC_PLT = 0x6ffffef6, - DT_TLSDESC_GOT = 0x6ffffef7, - DT_GNU_CONFLICT = 0x6ffffef8, - DT_GNU_LIBLIST = 0x6ffffef9, - DT_CONFIG = 0x6ffffefa, - DT_DEPAUDIT = 0x6ffffefb, - DT_AUDIT = 0x6ffffefc, - DT_PLTPAD = 0x6ffffefd, - DT_MOVETAB = 0x6ffffefe, - DT_SYMINFO = 0x6ffffeff, - DT_ADDRRNGHI = 0x6ffffeff, - - DT_RELACOUNT = 0x6ffffff9, - DT_RELCOUNT = 0x6ffffffa, - DT_FLAGS_1 = 0x6ffffffb, - DT_VERDEF = 0x6ffffffc, - DT_VERDEFNUM = 0x6ffffffd, - DT_VERNEED = 0x6ffffffe, - DT_VERNEEDNUM = 0x6fffffff, - - DT_VERSYM = 0x6ffffff0, - - // Specify the value of _GLOBAL_OFFSET_TABLE_. - DT_PPC_GOT = 0x70000000, - - // Specify the start of the .glink section. - DT_PPC64_GLINK = 0x70000000, - - // Specify the start and size of the .opd section. - DT_PPC64_OPD = 0x70000001, - DT_PPC64_OPDSZ = 0x70000002, - - // The index of an STT_SPARC_REGISTER symbol within the DT_SYMTAB - // symbol table. One dynamic entry exists for every STT_SPARC_REGISTER - // symbol in the symbol table. - DT_SPARC_REGISTER = 0x70000001, - - DT_AUXILIARY = 0x7ffffffd, - DT_USED = 0x7ffffffe, - DT_FILTER = 0x7fffffff -}; - -// Flags found in the DT_FLAGS dynamic element. - -enum DF -{ - DF_ORIGIN = 0x1, - DF_SYMBOLIC = 0x2, - DF_TEXTREL = 0x4, - DF_BIND_NOW = 0x8, - DF_STATIC_TLS = 0x10 -}; - -// Flags found in the DT_FLAGS_1 dynamic element. - -enum DF_1 -{ - DF_1_NOW = 0x1, - DF_1_GLOBAL = 0x2, - DF_1_GROUP = 0x4, - DF_1_NODELETE = 0x8, - DF_1_LOADFLTR = 0x10, - DF_1_INITFIRST = 0x20, - DF_1_NOOPEN = 0x40, - DF_1_ORIGIN = 0x80, - DF_1_DIRECT = 0x100, - DF_1_TRANS = 0x200, - DF_1_INTERPOSE = 0x400, - DF_1_NODEFLIB = 0x800, - DF_1_NODUMP = 0x1000, - DF_1_CONLFAT = 0x2000 -}; - -// Version numbers which appear in the vd_version field of a Verdef -// structure. - -const int VER_DEF_NONE = 0; -const int VER_DEF_CURRENT = 1; - -// Version numbers which appear in the vn_version field of a Verneed -// structure. - -const int VER_NEED_NONE = 0; -const int VER_NEED_CURRENT = 1; - -// Bit flags which appear in vd_flags of Verdef and vna_flags of -// Vernaux. - -const int VER_FLG_BASE = 0x1; -const int VER_FLG_WEAK = 0x2; -const int VER_FLG_INFO = 0x4; - -// Special constants found in the SHT_GNU_versym entries. - -const int VER_NDX_LOCAL = 0; -const int VER_NDX_GLOBAL = 1; - -// A SHT_GNU_versym section holds 16-bit words. This bit is set if -// the symbol is hidden and can only be seen when referenced using an -// explicit version number. This is a GNU extension. - -const int VERSYM_HIDDEN = 0x8000; - -// This is the mask for the rest of the data in a word read from a -// SHT_GNU_versym section. - -const int VERSYM_VERSION = 0x7fff; - -// Note descriptor type codes for notes in a non-core file with an -// empty name. - -enum -{ - // A version string. - NT_VERSION = 1, - // An architecture string. - NT_ARCH = 2 -}; - -// Note descriptor type codes for notes in a non-core file with the -// name "GNU". - -enum -{ - // The minimum ABI level. This is used by the dynamic linker to - // describe the minimal kernel version on which a shared library may - // be used. Th value should be four words. Word 0 is an OS - // descriptor (see below). Word 1 is the major version of the ABI. - // Word 2 is the minor version. Word 3 is the subminor version. - NT_GNU_ABI_TAG = 1, - // Hardware capabilities information. Word 0 is the number of - // entries. Word 1 is a bitmask of enabled entries. The rest of - // the descriptor is a series of entries, where each entry is a - // single byte followed by a nul terminated string. The byte gives - // the bit number to test if enabled in the bitmask. - NT_GNU_HWCAP = 2, - // The build ID as set by the linker's --build-id option. The - // format of the descriptor depends on the build ID style. - NT_GNU_BUILD_ID = 3, - // The version of gold used to link. Th descriptor is just a - // string. - NT_GNU_GOLD_VERSION = 4 -}; - -// The OS values which may appear in word 0 of a NT_GNU_ABI_TAG note. - -enum -{ - ELF_NOTE_OS_LINUX = 0, - ELF_NOTE_OS_GNU = 1, - ELF_NOTE_OS_SOLARIS2 = 2, - ELF_NOTE_OS_FREEBSD = 3, - ELF_NOTE_OS_NETBSD = 4, - ELF_NOTE_OS_SYLLABLE = 5 -}; - -} // End namespace elfcpp. - -// Include internal details after defining the types. -#include "elfcpp_internal.h" - -namespace elfcpp -{ - -// The offset of the ELF file header in the ELF file. - -const int file_header_offset = 0; - -// ELF structure sizes. - -template -struct Elf_sizes -{ - // Size of ELF file header. - static const int ehdr_size = sizeof(internal::Ehdr_data); - // Size of ELF segment header. - static const int phdr_size = sizeof(internal::Phdr_data); - // Size of ELF section header. - static const int shdr_size = sizeof(internal::Shdr_data); - // Size of ELF symbol table entry. - static const int sym_size = sizeof(internal::Sym_data); - // Sizes of ELF reloc entries. - static const int rel_size = sizeof(internal::Rel_data); - static const int rela_size = sizeof(internal::Rela_data); - // Size of ELF dynamic entry. - static const int dyn_size = sizeof(internal::Dyn_data); - // Size of ELF version structures. - static const int verdef_size = sizeof(internal::Verdef_data); - static const int verdaux_size = sizeof(internal::Verdaux_data); - static const int verneed_size = sizeof(internal::Verneed_data); - static const int vernaux_size = sizeof(internal::Vernaux_data); -}; - -// Accessor class for the ELF file header. - -template -class Ehdr -{ - public: - Ehdr(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Ehdr(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - const unsigned char* - get_e_ident() const - { return this->p_->e_ident; } - - Elf_Half - get_e_type() const - { return Convert<16, big_endian>::convert_host(this->p_->e_type); } - - Elf_Half - get_e_machine() const - { return Convert<16, big_endian>::convert_host(this->p_->e_machine); } - - Elf_Word - get_e_version() const - { return Convert<32, big_endian>::convert_host(this->p_->e_version); } - - typename Elf_types::Elf_Addr - get_e_entry() const - { return Convert::convert_host(this->p_->e_entry); } - - typename Elf_types::Elf_Off - get_e_phoff() const - { return Convert::convert_host(this->p_->e_phoff); } - - typename Elf_types::Elf_Off - get_e_shoff() const - { return Convert::convert_host(this->p_->e_shoff); } - - Elf_Word - get_e_flags() const - { return Convert<32, big_endian>::convert_host(this->p_->e_flags); } - - Elf_Half - get_e_ehsize() const - { return Convert<16, big_endian>::convert_host(this->p_->e_ehsize); } - - Elf_Half - get_e_phentsize() const - { return Convert<16, big_endian>::convert_host(this->p_->e_phentsize); } - - Elf_Half - get_e_phnum() const - { return Convert<16, big_endian>::convert_host(this->p_->e_phnum); } - - Elf_Half - get_e_shentsize() const - { return Convert<16, big_endian>::convert_host(this->p_->e_shentsize); } - - Elf_Half - get_e_shnum() const - { return Convert<16, big_endian>::convert_host(this->p_->e_shnum); } - - Elf_Half - get_e_shstrndx() const - { return Convert<16, big_endian>::convert_host(this->p_->e_shstrndx); } - - private: - const internal::Ehdr_data* p_; -}; - -// Write class for the ELF file header. - -template -class Ehdr_write -{ - public: - Ehdr_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_e_ident(const unsigned char v[EI_NIDENT]) const - { memcpy(this->p_->e_ident, v, EI_NIDENT); } - - void - put_e_type(Elf_Half v) - { this->p_->e_type = Convert<16, big_endian>::convert_host(v); } - - void - put_e_machine(Elf_Half v) - { this->p_->e_machine = Convert<16, big_endian>::convert_host(v); } - - void - put_e_version(Elf_Word v) - { this->p_->e_version = Convert<32, big_endian>::convert_host(v); } - - void - put_e_entry(typename Elf_types::Elf_Addr v) - { this->p_->e_entry = Convert::convert_host(v); } - - void - put_e_phoff(typename Elf_types::Elf_Off v) - { this->p_->e_phoff = Convert::convert_host(v); } - - void - put_e_shoff(typename Elf_types::Elf_Off v) - { this->p_->e_shoff = Convert::convert_host(v); } - - void - put_e_flags(Elf_Word v) - { this->p_->e_flags = Convert<32, big_endian>::convert_host(v); } - - void - put_e_ehsize(Elf_Half v) - { this->p_->e_ehsize = Convert<16, big_endian>::convert_host(v); } - - void - put_e_phentsize(Elf_Half v) - { this->p_->e_phentsize = Convert<16, big_endian>::convert_host(v); } - - void - put_e_phnum(Elf_Half v) - { this->p_->e_phnum = Convert<16, big_endian>::convert_host(v); } - - void - put_e_shentsize(Elf_Half v) - { this->p_->e_shentsize = Convert<16, big_endian>::convert_host(v); } - - void - put_e_shnum(Elf_Half v) - { this->p_->e_shnum = Convert<16, big_endian>::convert_host(v); } - - void - put_e_shstrndx(Elf_Half v) - { this->p_->e_shstrndx = Convert<16, big_endian>::convert_host(v); } - - private: - internal::Ehdr_data* p_; -}; - -// Accessor class for an ELF section header. - -template -class Shdr -{ - public: - Shdr(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Shdr(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Word - get_sh_name() const - { return Convert<32, big_endian>::convert_host(this->p_->sh_name); } - - Elf_Word - get_sh_type() const - { return Convert<32, big_endian>::convert_host(this->p_->sh_type); } - - typename Elf_types::Elf_WXword - get_sh_flags() const - { return Convert::convert_host(this->p_->sh_flags); } - - typename Elf_types::Elf_Addr - get_sh_addr() const - { return Convert::convert_host(this->p_->sh_addr); } - - typename Elf_types::Elf_Off - get_sh_offset() const - { return Convert::convert_host(this->p_->sh_offset); } - - typename Elf_types::Elf_WXword - get_sh_size() const - { return Convert::convert_host(this->p_->sh_size); } - - Elf_Word - get_sh_link() const - { return Convert<32, big_endian>::convert_host(this->p_->sh_link); } - - Elf_Word - get_sh_info() const - { return Convert<32, big_endian>::convert_host(this->p_->sh_info); } - - typename Elf_types::Elf_WXword - get_sh_addralign() const - { return - Convert::convert_host(this->p_->sh_addralign); } - - typename Elf_types::Elf_WXword - get_sh_entsize() const - { return Convert::convert_host(this->p_->sh_entsize); } - - private: - const internal::Shdr_data* p_; -}; - -// Write class for an ELF section header. - -template -class Shdr_write -{ - public: - Shdr_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_sh_name(Elf_Word v) - { this->p_->sh_name = Convert<32, big_endian>::convert_host(v); } - - void - put_sh_type(Elf_Word v) - { this->p_->sh_type = Convert<32, big_endian>::convert_host(v); } - - void - put_sh_flags(typename Elf_types::Elf_WXword v) - { this->p_->sh_flags = Convert::convert_host(v); } - - void - put_sh_addr(typename Elf_types::Elf_Addr v) - { this->p_->sh_addr = Convert::convert_host(v); } - - void - put_sh_offset(typename Elf_types::Elf_Off v) - { this->p_->sh_offset = Convert::convert_host(v); } - - void - put_sh_size(typename Elf_types::Elf_WXword v) - { this->p_->sh_size = Convert::convert_host(v); } - - void - put_sh_link(Elf_Word v) - { this->p_->sh_link = Convert<32, big_endian>::convert_host(v); } - - void - put_sh_info(Elf_Word v) - { this->p_->sh_info = Convert<32, big_endian>::convert_host(v); } - - void - put_sh_addralign(typename Elf_types::Elf_WXword v) - { this->p_->sh_addralign = Convert::convert_host(v); } - - void - put_sh_entsize(typename Elf_types::Elf_WXword v) - { this->p_->sh_entsize = Convert::convert_host(v); } - - private: - internal::Shdr_data* p_; -}; - -// Accessor class for an ELF segment header. - -template -class Phdr -{ - public: - Phdr(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Phdr(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Word - get_p_type() const - { return Convert<32, big_endian>::convert_host(this->p_->p_type); } - - typename Elf_types::Elf_Off - get_p_offset() const - { return Convert::convert_host(this->p_->p_offset); } - - typename Elf_types::Elf_Addr - get_p_vaddr() const - { return Convert::convert_host(this->p_->p_vaddr); } - - typename Elf_types::Elf_Addr - get_p_paddr() const - { return Convert::convert_host(this->p_->p_paddr); } - - typename Elf_types::Elf_WXword - get_p_filesz() const - { return Convert::convert_host(this->p_->p_filesz); } - - typename Elf_types::Elf_WXword - get_p_memsz() const - { return Convert::convert_host(this->p_->p_memsz); } - - Elf_Word - get_p_flags() const - { return Convert<32, big_endian>::convert_host(this->p_->p_flags); } - - typename Elf_types::Elf_WXword - get_p_align() const - { return Convert::convert_host(this->p_->p_align); } - - private: - const internal::Phdr_data* p_; -}; - -// Write class for an ELF segment header. - -template -class Phdr_write -{ - public: - Phdr_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_p_type(Elf_Word v) - { this->p_->p_type = Convert<32, big_endian>::convert_host(v); } - - void - put_p_offset(typename Elf_types::Elf_Off v) - { this->p_->p_offset = Convert::convert_host(v); } - - void - put_p_vaddr(typename Elf_types::Elf_Addr v) - { this->p_->p_vaddr = Convert::convert_host(v); } - - void - put_p_paddr(typename Elf_types::Elf_Addr v) - { this->p_->p_paddr = Convert::convert_host(v); } - - void - put_p_filesz(typename Elf_types::Elf_WXword v) - { this->p_->p_filesz = Convert::convert_host(v); } - - void - put_p_memsz(typename Elf_types::Elf_WXword v) - { this->p_->p_memsz = Convert::convert_host(v); } - - void - put_p_flags(Elf_Word v) - { this->p_->p_flags = Convert<32, big_endian>::convert_host(v); } - - void - put_p_align(typename Elf_types::Elf_WXword v) - { this->p_->p_align = Convert::convert_host(v); } - - private: - internal::Phdr_data* p_; -}; - -// Accessor class for an ELF symbol table entry. - -template -class Sym -{ - public: - Sym(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Sym(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Word - get_st_name() const - { return Convert<32, big_endian>::convert_host(this->p_->st_name); } - - typename Elf_types::Elf_Addr - get_st_value() const - { return Convert::convert_host(this->p_->st_value); } - - typename Elf_types::Elf_WXword - get_st_size() const - { return Convert::convert_host(this->p_->st_size); } - - unsigned char - get_st_info() const - { return this->p_->st_info; } - - STB - get_st_bind() const - { return elf_st_bind(this->get_st_info()); } - - STT - get_st_type() const - { return elf_st_type(this->get_st_info()); } - - unsigned char - get_st_other() const - { return this->p_->st_other; } - - STV - get_st_visibility() const - { return elf_st_visibility(this->get_st_other()); } - - unsigned char - get_st_nonvis() const - { return elf_st_nonvis(this->get_st_other()); } - - Elf_Half - get_st_shndx() const - { return Convert<16, big_endian>::convert_host(this->p_->st_shndx); } - - private: - const internal::Sym_data* p_; -}; - -// Writer class for an ELF symbol table entry. - -template -class Sym_write -{ - public: - Sym_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_st_name(Elf_Word v) - { this->p_->st_name = Convert<32, big_endian>::convert_host(v); } - - void - put_st_value(typename Elf_types::Elf_Addr v) - { this->p_->st_value = Convert::convert_host(v); } - - void - put_st_size(typename Elf_types::Elf_WXword v) - { this->p_->st_size = Convert::convert_host(v); } - - void - put_st_info(unsigned char v) - { this->p_->st_info = v; } - - void - put_st_info(STB bind, STT type) - { this->p_->st_info = elf_st_info(bind, type); } - - void - put_st_other(unsigned char v) - { this->p_->st_other = v; } - - void - put_st_other(STV vis, unsigned char nonvis) - { this->p_->st_other = elf_st_other(vis, nonvis); } - - void - put_st_shndx(Elf_Half v) - { this->p_->st_shndx = Convert<16, big_endian>::convert_host(v); } - - Sym - sym() - { return Sym(reinterpret_cast(this->p_)); } - - private: - internal::Sym_data* p_; -}; - -// Accessor classes for an ELF REL relocation entry. - -template -class Rel -{ - public: - Rel(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Rel(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - typename Elf_types::Elf_Addr - get_r_offset() const - { return Convert::convert_host(this->p_->r_offset); } - - typename Elf_types::Elf_WXword - get_r_info() const - { return Convert::convert_host(this->p_->r_info); } - - private: - const internal::Rel_data* p_; -}; - -// Writer class for an ELF Rel relocation. - -template -class Rel_write -{ - public: - Rel_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_r_offset(typename Elf_types::Elf_Addr v) - { this->p_->r_offset = Convert::convert_host(v); } - - void - put_r_info(typename Elf_types::Elf_WXword v) - { this->p_->r_info = Convert::convert_host(v); } - - private: - internal::Rel_data* p_; -}; - -// Accessor class for an ELF Rela relocation. - -template -class Rela -{ - public: - Rela(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Rela(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - typename Elf_types::Elf_Addr - get_r_offset() const - { return Convert::convert_host(this->p_->r_offset); } - - typename Elf_types::Elf_WXword - get_r_info() const - { return Convert::convert_host(this->p_->r_info); } - - typename Elf_types::Elf_Swxword - get_r_addend() const - { return Convert::convert_host(this->p_->r_addend); } - - private: - const internal::Rela_data* p_; -}; - -// Writer class for an ELF Rela relocation. - -template -class Rela_write -{ - public: - Rela_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_r_offset(typename Elf_types::Elf_Addr v) - { this->p_->r_offset = Convert::convert_host(v); } - - void - put_r_info(typename Elf_types::Elf_WXword v) - { this->p_->r_info = Convert::convert_host(v); } - - void - put_r_addend(typename Elf_types::Elf_Swxword v) - { this->p_->r_addend = Convert::convert_host(v); } - - private: - internal::Rela_data* p_; -}; - -// Accessor classes for entries in the ELF SHT_DYNAMIC section aka -// PT_DYNAMIC segment. - -template -class Dyn -{ - public: - Dyn(const unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - template - Dyn(File* file, typename File::Location loc) - : p_(reinterpret_cast*>( - file->view(loc.file_offset, loc.data_size).data())) - { } - - typename Elf_types::Elf_Swxword - get_d_tag() const - { return Convert::convert_host(this->p_->d_tag); } - - typename Elf_types::Elf_WXword - get_d_val() const - { return Convert::convert_host(this->p_->d_val); } - - typename Elf_types::Elf_Addr - get_d_ptr() const - { return Convert::convert_host(this->p_->d_val); } - - private: - const internal::Dyn_data* p_; -}; - -// Write class for an entry in the SHT_DYNAMIC section. - -template -class Dyn_write -{ - public: - Dyn_write(unsigned char* p) - : p_(reinterpret_cast*>(p)) - { } - - void - put_d_tag(typename Elf_types::Elf_Swxword v) - { this->p_->d_tag = Convert::convert_host(v); } - - void - put_d_val(typename Elf_types::Elf_WXword v) - { this->p_->d_val = Convert::convert_host(v); } - - void - put_d_ptr(typename Elf_types::Elf_Addr v) - { this->p_->d_val = Convert::convert_host(v); } - - private: - internal::Dyn_data* p_; -}; - -// Accessor classes for entries in the ELF SHT_GNU_verdef section. - -template -class Verdef -{ - public: - Verdef(const unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - template - Verdef(File* file, typename File::Location loc) - : p_(reinterpret_cast( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Half - get_vd_version() const - { return Convert<16, big_endian>::convert_host(this->p_->vd_version); } - - Elf_Half - get_vd_flags() const - { return Convert<16, big_endian>::convert_host(this->p_->vd_flags); } - - Elf_Half - get_vd_ndx() const - { return Convert<16, big_endian>::convert_host(this->p_->vd_ndx); } - - Elf_Half - get_vd_cnt() const - { return Convert<16, big_endian>::convert_host(this->p_->vd_cnt); } - - Elf_Word - get_vd_hash() const - { return Convert<32, big_endian>::convert_host(this->p_->vd_hash); } - - Elf_Word - get_vd_aux() const - { return Convert<32, big_endian>::convert_host(this->p_->vd_aux); } - - Elf_Word - get_vd_next() const - { return Convert<32, big_endian>::convert_host(this->p_->vd_next); } - - private: - const internal::Verdef_data* p_; -}; - -template -class Verdef_write -{ - public: - Verdef_write(unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - void - set_vd_version(Elf_Half v) - { this->p_->vd_version = Convert<16, big_endian>::convert_host(v); } - - void - set_vd_flags(Elf_Half v) - { this->p_->vd_flags = Convert<16, big_endian>::convert_host(v); } - - void - set_vd_ndx(Elf_Half v) - { this->p_->vd_ndx = Convert<16, big_endian>::convert_host(v); } - - void - set_vd_cnt(Elf_Half v) - { this->p_->vd_cnt = Convert<16, big_endian>::convert_host(v); } - - void - set_vd_hash(Elf_Word v) - { this->p_->vd_hash = Convert<32, big_endian>::convert_host(v); } - - void - set_vd_aux(Elf_Word v) - { this->p_->vd_aux = Convert<32, big_endian>::convert_host(v); } - - void - set_vd_next(Elf_Word v) - { this->p_->vd_next = Convert<32, big_endian>::convert_host(v); } - - private: - internal::Verdef_data* p_; -}; - -// Accessor classes for auxiliary entries in the ELF SHT_GNU_verdef -// section. - -template -class Verdaux -{ - public: - Verdaux(const unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - template - Verdaux(File* file, typename File::Location loc) - : p_(reinterpret_cast( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Word - get_vda_name() const - { return Convert<32, big_endian>::convert_host(this->p_->vda_name); } - - Elf_Word - get_vda_next() const - { return Convert<32, big_endian>::convert_host(this->p_->vda_next); } - - private: - const internal::Verdaux_data* p_; -}; - -template -class Verdaux_write -{ - public: - Verdaux_write(unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - void - set_vda_name(Elf_Word v) - { this->p_->vda_name = Convert<32, big_endian>::convert_host(v); } - - void - set_vda_next(Elf_Word v) - { this->p_->vda_next = Convert<32, big_endian>::convert_host(v); } - - private: - internal::Verdaux_data* p_; -}; - -// Accessor classes for entries in the ELF SHT_GNU_verneed section. - -template -class Verneed -{ - public: - Verneed(const unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - template - Verneed(File* file, typename File::Location loc) - : p_(reinterpret_cast( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Half - get_vn_version() const - { return Convert<16, big_endian>::convert_host(this->p_->vn_version); } - - Elf_Half - get_vn_cnt() const - { return Convert<16, big_endian>::convert_host(this->p_->vn_cnt); } - - Elf_Word - get_vn_file() const - { return Convert<32, big_endian>::convert_host(this->p_->vn_file); } - - Elf_Word - get_vn_aux() const - { return Convert<32, big_endian>::convert_host(this->p_->vn_aux); } - - Elf_Word - get_vn_next() const - { return Convert<32, big_endian>::convert_host(this->p_->vn_next); } - - private: - const internal::Verneed_data* p_; -}; - -template -class Verneed_write -{ - public: - Verneed_write(unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - void - set_vn_version(Elf_Half v) - { this->p_->vn_version = Convert<16, big_endian>::convert_host(v); } - - void - set_vn_cnt(Elf_Half v) - { this->p_->vn_cnt = Convert<16, big_endian>::convert_host(v); } - - void - set_vn_file(Elf_Word v) - { this->p_->vn_file = Convert<32, big_endian>::convert_host(v); } - - void - set_vn_aux(Elf_Word v) - { this->p_->vn_aux = Convert<32, big_endian>::convert_host(v); } - - void - set_vn_next(Elf_Word v) - { this->p_->vn_next = Convert<32, big_endian>::convert_host(v); } - - private: - internal::Verneed_data* p_; -}; - -// Accessor classes for auxiliary entries in the ELF SHT_GNU_verneed -// section. - -template -class Vernaux -{ - public: - Vernaux(const unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - template - Vernaux(File* file, typename File::Location loc) - : p_(reinterpret_cast( - file->view(loc.file_offset, loc.data_size).data())) - { } - - Elf_Word - get_vna_hash() const - { return Convert<32, big_endian>::convert_host(this->p_->vna_hash); } - - Elf_Half - get_vna_flags() const - { return Convert<16, big_endian>::convert_host(this->p_->vna_flags); } - - Elf_Half - get_vna_other() const - { return Convert<16, big_endian>::convert_host(this->p_->vna_other); } - - Elf_Word - get_vna_name() const - { return Convert<32, big_endian>::convert_host(this->p_->vna_name); } - - Elf_Word - get_vna_next() const - { return Convert<32, big_endian>::convert_host(this->p_->vna_next); } - - private: - const internal::Vernaux_data* p_; -}; - -template -class Vernaux_write -{ - public: - Vernaux_write(unsigned char* p) - : p_(reinterpret_cast(p)) - { } - - void - set_vna_hash(Elf_Word v) - { this->p_->vna_hash = Convert<32, big_endian>::convert_host(v); } - - void - set_vna_flags(Elf_Half v) - { this->p_->vna_flags = Convert<16, big_endian>::convert_host(v); } - - void - set_vna_other(Elf_Half v) - { this->p_->vna_other = Convert<16, big_endian>::convert_host(v); } - - void - set_vna_name(Elf_Word v) - { this->p_->vna_name = Convert<32, big_endian>::convert_host(v); } - - void - set_vna_next(Elf_Word v) - { this->p_->vna_next = Convert<32, big_endian>::convert_host(v); } - - private: - internal::Vernaux_data* p_; -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFPCP_H) diff --git a/contrib/binutils-2.22/elfcpp/elfcpp_file.h b/contrib/binutils-2.22/elfcpp/elfcpp_file.h deleted file mode 100644 index 8dd7ad5cca..0000000000 --- a/contrib/binutils-2.22/elfcpp/elfcpp_file.h +++ /dev/null @@ -1,688 +0,0 @@ -// elfcpp_file.h -- file access for elfcpp -*- C++ -*- - -// Copyright 2006, 2007, Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -// This header file defines the class Elf_file which can be used to -// read useful data from an ELF file. The functions here are all -// templates which take a file interface object as a parameter. This -// type must have a subtype View. This type must support two methods: -// View view(off_t file_offset, off_t data_size) -// returns a View for the specified part of the file. -// void error(const char* printf_format, ...) -// prints an error message and does not return. The subtype View must -// support a method -// const unsigned char* data() -// which returns a pointer to a buffer containing the requested data. -// This general interface is used to read data from the file. Objects -// of type View will never survive longer than the elfcpp function. - -// Some of these functions must return a reference to part of the -// file. To use these, the file interface must support a subtype -// Location: -// Location(off_t file_offset, off_t data_size) -// To use this in conjunction with the accessors types Shdr, etc., the -// file interface should support an overload of view: -// View view(Location) -// This permits writing -// elfcpp::Shdr shdr(file, ef.section_header(n)); - -#ifndef ELFCPP_FILE_H -#define ELFCPP_FILE_H - -#include -#include -#include - -#include "elfcpp.h" - -namespace elfcpp -{ - -// A simple helper class to recognize if a file has an ELF header. - -class Elf_recognizer -{ - public: - // Maximum header size. The user should try to read this much of - // the file when using this class. - - static const int max_header_size = Elf_sizes<64>::ehdr_size; - - // Checks if the file contains the ELF magic. Other header fields - // are not checked. - - static bool - is_elf_file(const unsigned char* ehdr_buf, int size); - - // Check if EHDR_BUF/BUFSIZE is a valid header of a 32-bit or - // 64-bit, little-endian or big-endian ELF file. Assumes - // is_elf_file() has been checked to be true. If the header is not - // valid, *ERROR contains a human-readable error message. If is is, - // *SIZE is set to either 32 or 64, *BIG_ENDIAN is set to indicate - // whether the file is big-endian. - - static bool - is_valid_header(const unsigned char* ehdr_buf, off_t bufsize, - int* size, bool* big_endian, - std::string* error); -}; - -// This object is used to read an ELF file. -// SIZE: The size of file, 32 or 64. -// BIG_ENDIAN: Whether the file is in big-endian format. -// FILE: A file reading type as described above. - -template -class Elf_file -{ - private: - typedef Elf_file This; - - public: - static const int ehdr_size = Elf_sizes::ehdr_size; - static const int phdr_size = Elf_sizes::phdr_size; - static const int shdr_size = Elf_sizes::shdr_size; - static const int sym_size = Elf_sizes::sym_size; - static const int rel_size = Elf_sizes::rel_size; - static const int rela_size = Elf_sizes::rela_size; - - typedef Ehdr Ef_ehdr; - typedef Phdr Ef_phdr; - typedef Shdr Ef_shdr; - typedef Sym Ef_sym; - - // Construct an Elf_file given an ELF file header. - Elf_file(File* file, const Ef_ehdr& ehdr) - { this->construct(file, ehdr); } - - // Construct an ELF file. - inline - Elf_file(File* file); - - // Return the file offset to the section headers. - off_t - shoff() const - { return this->shoff_; } - - // Find the first section with an sh_type field equal to TYPE and - // return its index. Returns SHN_UNDEF if there is no such section. - unsigned int - find_section_by_type(unsigned int type); - - // Return the number of sections. - unsigned int - shnum() - { - this->initialize_shnum(); - return this->shnum_; - } - - // Return the section index of the section name string table. - unsigned int - shstrndx() - { - this->initialize_shnum(); - return this->shstrndx_; - } - - // Return the value to subtract from section indexes >= - // SHN_LORESERVE. See the comment in initialize_shnum. - int - large_shndx_offset() - { - this->initialize_shnum(); - return this->large_shndx_offset_; - } - - // Return the location of the header of section SHNDX. - typename File::Location - section_header(unsigned int shndx) - { - return typename File::Location(this->section_header_offset(shndx), - shdr_size); - } - - // Return the name of section SHNDX. - std::string - section_name(unsigned int shndx); - - // Return the location of the contents of section SHNDX. - typename File::Location - section_contents(unsigned int shndx); - - // Return the size of section SHNDX. - typename Elf_types::Elf_WXword - section_size(unsigned int shndx); - - // Return the flags of section SHNDX. - typename Elf_types::Elf_WXword - section_flags(unsigned int shndx); - - // Return the address of section SHNDX. - typename Elf_types::Elf_Addr - section_addr(unsigned int shndx); - - // Return the type of section SHNDX. - Elf_Word - section_type(unsigned int shndx); - - // Return the link field of section SHNDX. - Elf_Word - section_link(unsigned int shndx); - - // Return the info field of section SHNDX. - Elf_Word - section_info(unsigned int shndx); - - // Return the addralign field of section SHNDX. - typename Elf_types::Elf_WXword - section_addralign(unsigned int shndx); - - private: - // Shared constructor code. - void - construct(File* file, const Ef_ehdr& ehdr); - - // Initialize shnum_ and shstrndx_. - void - initialize_shnum(); - - // Return the file offset of the header of section SHNDX. - off_t - section_header_offset(unsigned int shndx); - - // The file we are reading. - File* file_; - // The file offset to the section headers. - off_t shoff_; - // The number of sections. - unsigned int shnum_; - // The section index of the section name string table. - unsigned int shstrndx_; - // Offset to add to sections larger than SHN_LORESERVE. - int large_shndx_offset_; -}; - -// A small wrapper around SHT_STRTAB data mapped to memory. It checks that the -// index is not out of bounds and the string is NULL-terminated. - -class Elf_strtab -{ - public: - // Construct an Elf_strtab for a section with contents *P and size SIZE. - Elf_strtab(const unsigned char* p, size_t size); - - // Return the file offset to the section headers. - bool - get_c_string(size_t offset, const char** cstring) const - { - if (offset >= this->usable_size_) - return false; - *cstring = this->base_ + offset; - return true; - } - - private: - // Contents of the section mapped to memory. - const char* base_; - // One larger that the position of the last NULL character in the section. - // For valid SHT_STRTAB sections, this is the size of the section. - size_t usable_size_; -}; - -// Inline function definitions. - -// Check for presence of the ELF magic number. - -inline bool -Elf_recognizer::is_elf_file(const unsigned char* ehdr_buf, int size) -{ - if (size < 4) - return false; - - static unsigned char elfmagic[4] = - { - elfcpp::ELFMAG0, elfcpp::ELFMAG1, - elfcpp::ELFMAG2, elfcpp::ELFMAG3 - }; - return memcmp(ehdr_buf, elfmagic, 4) == 0; -} - -namespace -{ - -// Print a number to a string. - -inline std::string -internal_printf_int(const char* format, int arg) -{ - char buf[256]; - snprintf(buf, sizeof(buf), format, arg); - return std::string(buf); -} - -} // End anonymous namespace. - -// Check the validity of the ELF header. - -inline bool -Elf_recognizer::is_valid_header( - const unsigned char* ehdr_buf, - off_t bufsize, - int* size, - bool* big_endian, - std::string* error) -{ - if (bufsize < elfcpp::EI_NIDENT) - { - *error = _("ELF file too short"); - return false; - } - - int v = ehdr_buf[elfcpp::EI_VERSION]; - if (v != elfcpp::EV_CURRENT) - { - if (v == elfcpp::EV_NONE) - *error = _("invalid ELF version 0"); - else - *error = internal_printf_int(_("unsupported ELF version %d"), v); - return false; - } - - int c = ehdr_buf[elfcpp::EI_CLASS]; - if (c == elfcpp::ELFCLASSNONE) - { - *error = _("invalid ELF class 0"); - return false; - } - else if (c != elfcpp::ELFCLASS32 - && c != elfcpp::ELFCLASS64) - { - *error = internal_printf_int(_("unsupported ELF class %d"), c); - return false; - } - - int d = ehdr_buf[elfcpp::EI_DATA]; - if (d == elfcpp::ELFDATANONE) - { - *error = _("invalid ELF data encoding"); - return false; - } - else if (d != elfcpp::ELFDATA2LSB - && d != elfcpp::ELFDATA2MSB) - { - *error = internal_printf_int(_("unsupported ELF data encoding %d"), d); - return false; - } - - *big_endian = (d == elfcpp::ELFDATA2MSB); - - if (c == elfcpp::ELFCLASS32) - { - if (bufsize < elfcpp::Elf_sizes<32>::ehdr_size) - { - *error = _("ELF file too short"); - return false; - } - *size = 32; - } - else - { - if (bufsize < elfcpp::Elf_sizes<64>::ehdr_size) - { - *error = _("ELF file too short"); - return false; - } - *size = 64; - } - - return true; -} - -// Template function definitions. - -// Construct an Elf_file given an ELF file header. - -template -void -Elf_file::construct(File* file, const Ef_ehdr& ehdr) -{ - this->file_ = file; - this->shoff_ = ehdr.get_e_shoff(); - this->shnum_ = ehdr.get_e_shnum(); - this->shstrndx_ = ehdr.get_e_shstrndx(); - this->large_shndx_offset_ = 0; - if (ehdr.get_e_ehsize() != This::ehdr_size) - file->error(_("bad e_ehsize (%d != %d)"), - ehdr.get_e_ehsize(), This::ehdr_size); - if (ehdr.get_e_shentsize() != This::shdr_size) - file->error(_("bad e_shentsize (%d != %d)"), - ehdr.get_e_shentsize(), This::shdr_size); -} - -// Construct an ELF file. - -template -inline -Elf_file::Elf_file(File* file) -{ - typename File::View v(file->view(file_header_offset, This::ehdr_size)); - this->construct(file, Ef_ehdr(v.data())); -} - -// Initialize the shnum_ and shstrndx_ fields, handling overflow. - -template -void -Elf_file::initialize_shnum() -{ - if ((this->shnum_ == 0 || this->shstrndx_ == SHN_XINDEX) - && this->shoff_ != 0) - { - typename File::View v(this->file_->view(this->shoff_, This::shdr_size)); - Ef_shdr shdr(v.data()); - - if (this->shnum_ == 0) - this->shnum_ = shdr.get_sh_size(); - - if (this->shstrndx_ == SHN_XINDEX) - { - this->shstrndx_ = shdr.get_sh_link(); - - // Versions of the GNU binutils between 2.12 and 2.18 did - // not handle objects with more than SHN_LORESERVE sections - // correctly. All large section indexes were offset by - // 0x100. Some information can be found here: - // http://sourceware.org/bugzilla/show_bug.cgi?id=5900 . - // Fortunately these object files are easy to detect, as the - // GNU binutils always put the section header string table - // near the end of the list of sections. Thus if the - // section header string table index is larger than the - // number of sections, then we know we have to subtract - // 0x100 to get the real section index. - if (this->shstrndx_ >= this->shnum_) - { - if (this->shstrndx_ >= elfcpp::SHN_LORESERVE + 0x100) - { - this->large_shndx_offset_ = - 0x100; - this->shstrndx_ -= 0x100; - } - if (this->shstrndx_ >= this->shnum_) - this->file_->error(_("bad shstrndx: %u >= %u"), - this->shstrndx_, this->shnum_); - } - } - } -} - -// Find section with sh_type equal to TYPE and return its index. -// Returns SHN_UNDEF if not found. - -template -unsigned int -Elf_file::find_section_by_type(unsigned int type) -{ - unsigned int shnum = this->shnum(); - typename File::View v(this->file_->view(this->shoff_, - This::shdr_size * shnum)); - for (unsigned int i = 0; i < shnum; i++) - { - Ef_shdr shdr(v.data() + This::shdr_size * i); - if (shdr.get_sh_type() == type) - return i; - } - return SHN_UNDEF; -} - -// Return the file offset of the section header of section SHNDX. - -template -off_t -Elf_file::section_header_offset(unsigned int shndx) -{ - if (shndx >= this->shnum()) - this->file_->error(_("section_header_offset: bad shndx %u >= %u"), - shndx, this->shnum()); - return this->shoff_ + This::shdr_size * shndx; -} - -// Return the name of section SHNDX. - -template -std::string -Elf_file::section_name(unsigned int shndx) -{ - File* const file = this->file_; - - // Get the section name offset. - unsigned int sh_name; - { - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - Ef_shdr shdr(v.data()); - sh_name = shdr.get_sh_name(); - } - - // Get the file offset for the section name string table data. - off_t shstr_off; - typename Elf_types::Elf_WXword shstr_size; - { - const unsigned int shstrndx = this->shstrndx_; - typename File::View v(file->view(this->section_header_offset(shstrndx), - This::shdr_size)); - Ef_shdr shstr_shdr(v.data()); - shstr_off = shstr_shdr.get_sh_offset(); - shstr_size = shstr_shdr.get_sh_size(); - } - - if (sh_name >= shstr_size) - file->error(_("bad section name offset for section %u: %u"), - shndx, sh_name); - - typename File::View v(file->view(shstr_off, shstr_size)); - - const unsigned char* datau = v.data(); - const char* data = reinterpret_cast(datau); - const void* p = ::memchr(data + sh_name, '\0', shstr_size - sh_name); - if (p == NULL) - file->error(_("missing null terminator for name of section %u"), - shndx); - - size_t len = static_cast(p) - (data + sh_name); - - return std::string(data + sh_name, len); -} - -// Return the contents of section SHNDX. - -template -typename File::Location -Elf_file::section_contents(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_contents: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - Ef_shdr shdr(v.data()); - return typename File::Location(shdr.get_sh_offset(), shdr.get_sh_size()); -} - -// Get the size of section SHNDX. - -template -typename Elf_types::Elf_WXword -Elf_file::section_size(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_size: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_size(); -} - -// Return the section flags of section SHNDX. - -template -typename Elf_types::Elf_WXword -Elf_file::section_flags(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_flags: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_flags(); -} - -// Return the address of section SHNDX. - -template -typename Elf_types::Elf_Addr -Elf_file::section_addr(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_flags: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_addr(); -} - -// Return the type of section SHNDX. - -template -Elf_Word -Elf_file::section_type(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_type: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_type(); -} - -// Return the sh_link field of section SHNDX. - -template -Elf_Word -Elf_file::section_link(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_link: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_link(); -} - -// Return the sh_info field of section SHNDX. - -template -Elf_Word -Elf_file::section_info(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_info: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_info(); -} - -// Return the sh_addralign field of section SHNDX. - -template -typename Elf_types::Elf_WXword -Elf_file::section_addralign(unsigned int shndx) -{ - File* const file = this->file_; - - if (shndx >= this->shnum()) - file->error(_("section_addralign: bad shndx %u >= %u"), - shndx, this->shnum()); - - typename File::View v(file->view(this->section_header_offset(shndx), - This::shdr_size)); - - Ef_shdr shdr(v.data()); - return shdr.get_sh_addralign(); -} - -inline -Elf_strtab::Elf_strtab(const unsigned char* p, size_t size) -{ - // Check if the section is NUL-terminated. If it isn't, we ignore - // the last part to make sure we don't return non-NUL-terminated - // strings. - while (size > 0 && p[size - 1] != 0) - size--; - this->base_ = reinterpret_cast(p); - this->usable_size_ = size; -} - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_FILE_H) diff --git a/contrib/binutils-2.22/elfcpp/elfcpp_internal.h b/contrib/binutils-2.22/elfcpp/elfcpp_internal.h deleted file mode 100644 index df84e7e765..0000000000 --- a/contrib/binutils-2.22/elfcpp/elfcpp_internal.h +++ /dev/null @@ -1,240 +0,0 @@ -// elfcpp_internal.h -- internals for elfcpp -*- C++ -*- - -// Copyright 2006, 2007, Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -// This is included by elfcpp.h, the external interface, but holds -// information which we want to keep private. - -#ifndef ELFCPP_INTERNAL_H -#define ELFCPP_INTERNAL_H - -namespace elfcpp -{ - -namespace internal -{ - -// The ELF file header. - -template -struct Ehdr_data -{ - unsigned char e_ident[EI_NIDENT]; - Elf_Half e_type; - Elf_Half e_machine; - Elf_Word e_version; - typename Elf_types::Elf_Addr e_entry; - typename Elf_types::Elf_Off e_phoff; - typename Elf_types::Elf_Off e_shoff; - Elf_Word e_flags; - Elf_Half e_ehsize; - Elf_Half e_phentsize; - Elf_Half e_phnum; - Elf_Half e_shentsize; - Elf_Half e_shnum; - Elf_Half e_shstrndx; -}; - -// An ELF section header. - -template -struct Shdr_data -{ - Elf_Word sh_name; - Elf_Word sh_type; - typename Elf_types::Elf_WXword sh_flags; - typename Elf_types::Elf_Addr sh_addr; - typename Elf_types::Elf_Off sh_offset; - typename Elf_types::Elf_WXword sh_size; - Elf_Word sh_link; - Elf_Word sh_info; - typename Elf_types::Elf_WXword sh_addralign; - typename Elf_types::Elf_WXword sh_entsize; -}; - -// An ELF segment header. We use template specialization for the -// 32-bit and 64-bit versions because the fields are in a different -// order. - -template -struct Phdr_data; - -template<> -struct Phdr_data<32> -{ - Elf_Word p_type; - Elf_types<32>::Elf_Off p_offset; - Elf_types<32>::Elf_Addr p_vaddr; - Elf_types<32>::Elf_Addr p_paddr; - Elf_Word p_filesz; - Elf_Word p_memsz; - Elf_Word p_flags; - Elf_Word p_align; -}; - -template<> -struct Phdr_data<64> -{ - Elf_Word p_type; - Elf_Word p_flags; - Elf_types<64>::Elf_Off p_offset; - Elf_types<64>::Elf_Addr p_vaddr; - Elf_types<64>::Elf_Addr p_paddr; - Elf_Xword p_filesz; - Elf_Xword p_memsz; - Elf_Xword p_align; -}; - -// An ELF symbol table entry. We use template specialization for the -// 32-bit and 64-bit versions because the fields are in a different -// order. - -template -struct Sym_data; - -template<> -struct Sym_data<32> -{ - Elf_Word st_name; - Elf_types<32>::Elf_Addr st_value; - Elf_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf_Half st_shndx; -}; - -template<> -struct Sym_data<64> -{ - Elf_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf_Half st_shndx; - Elf_types<64>::Elf_Addr st_value; - Elf_Xword st_size; -}; - -// ELF relocation table entries. - -template -struct Rel_data -{ - typename Elf_types::Elf_Addr r_offset; - typename Elf_types::Elf_WXword r_info; -}; - -template -struct Rela_data -{ - typename Elf_types::Elf_Addr r_offset; - typename Elf_types::Elf_WXword r_info; - typename Elf_types::Elf_Swxword r_addend; -}; - -// An entry in the ELF SHT_DYNAMIC section aka PT_DYNAMIC segment. - -template -struct Dyn_data -{ - typename Elf_types::Elf_Swxword d_tag; - typename Elf_types::Elf_WXword d_val; -}; - -// An entry in a SHT_GNU_verdef section. This structure is the same -// in 32-bit and 64-bit ELF files. - -struct Verdef_data -{ - // Version number of structure (VER_DEF_*). - Elf_Half vd_version; - // Bit flags (VER_FLG_*). - Elf_Half vd_flags; - // Version index. - Elf_Half vd_ndx; - // Number of auxiliary Verdaux entries. - Elf_Half vd_cnt; - // Hash of name. - Elf_Word vd_hash; - // Byte offset to first Verdaux entry. - Elf_Word vd_aux; - // Byte offset to next Verdef entry. - Elf_Word vd_next; -}; - -// An auxiliary entry in a SHT_GNU_verdef section. This structure is -// the same in 32-bit and 64-bit ELF files. - -struct Verdaux_data -{ - // Offset in string table of version name. - Elf_Word vda_name; - // Byte offset to next Verdaux entry. - Elf_Word vda_next; -}; - -// An entry in a SHT_GNU_verneed section. This structure is the same -// in 32-bit and 64-bit ELF files. - -struct Verneed_data -{ - // Version number of structure (VER_NEED_*). - Elf_Half vn_version; - // Number of auxiliary Vernaux entries. - Elf_Half vn_cnt; - // Offset in string table of library name. - Elf_Word vn_file; - // Byte offset to first Vernaux entry. - Elf_Word vn_aux; - // Byt eoffset to next Verneed entry. - Elf_Word vn_next; -}; - -// An auxiliary entry in a SHT_GNU_verneed section. This structure is -// the same in 32-bit and 64-bit ELF files. - -struct Vernaux_data -{ - // Hash of dependency name. - Elf_Word vna_hash; - // Bit flags (VER_FLG_*). - Elf_Half vna_flags; - // Version index used in SHT_GNU_versym entries. - Elf_Half vna_other; - // Offset in string table of version name. - Elf_Word vna_name; - // Byte offset to next Vernaux entry. - Elf_Word vna_next; -}; - -} // End namespace internal. - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_INTERNAL_H) diff --git a/contrib/binutils-2.22/elfcpp/elfcpp_swap.h b/contrib/binutils-2.22/elfcpp/elfcpp_swap.h deleted file mode 100644 index 0685276158..0000000000 --- a/contrib/binutils-2.22/elfcpp/elfcpp_swap.h +++ /dev/null @@ -1,435 +0,0 @@ -// elfcpp_swap.h -- Handle swapping for elfcpp -*- C++ -*- - -// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -// This header file defines basic template classes to efficiently swap -// numbers between host form and target form. When the host and -// target have the same endianness, these turn into no-ops. - -#ifndef ELFCPP_SWAP_H -#define ELFCPP_SWAP_H - -#include - -// We need an autoconf-generated config.h file for endianness and -// swapping. We check two macros: WORDS_BIGENDIAN and -// HAVE_BYTESWAP_H. - -#include "config.h" - -#ifdef HAVE_BYTESWAP_H -#include -#else -// Provide our own versions of the byteswap functions. -inline uint16_t -bswap_16(uint16_t v) -{ - return ((v >> 8) & 0xff) | ((v & 0xff) << 8); -} - -inline uint32_t -bswap_32(uint32_t v) -{ - return ( ((v & 0xff000000) >> 24) - | ((v & 0x00ff0000) >> 8) - | ((v & 0x0000ff00) << 8) - | ((v & 0x000000ff) << 24)); -} - -inline uint64_t -bswap_64(uint64_t v) -{ - return ( ((v & 0xff00000000000000ULL) >> 56) - | ((v & 0x00ff000000000000ULL) >> 40) - | ((v & 0x0000ff0000000000ULL) >> 24) - | ((v & 0x000000ff00000000ULL) >> 8) - | ((v & 0x00000000ff000000ULL) << 8) - | ((v & 0x0000000000ff0000ULL) << 24) - | ((v & 0x000000000000ff00ULL) << 40) - | ((v & 0x00000000000000ffULL) << 56)); -} -#endif // !defined(HAVE_BYTESWAP_H) - -// gcc 4.3 and later provides __builtin_bswap32 and __builtin_bswap64. - -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) -#undef bswap_32 -#define bswap_32 __builtin_bswap32 -#undef bswap_64 -#define bswap_64 __builtin_bswap64 -#endif - -namespace elfcpp -{ - -// Endian simply indicates whether the host is big endian or not. - -struct Endian -{ - public: - // Used for template specializations. - static const bool host_big_endian = -#ifdef WORDS_BIGENDIAN - true -#else - false -#endif - ; -}; - -// Valtype_base is a template based on size (8, 16, 32, 64) which -// defines the type Valtype as the unsigned integer, and -// Signed_valtype as the signed integer, of the specified size. - -template -struct Valtype_base; - -template<> -struct Valtype_base<8> -{ - typedef uint8_t Valtype; - typedef int8_t Signed_valtype; -}; - -template<> -struct Valtype_base<16> -{ - typedef uint16_t Valtype; - typedef int16_t Signed_valtype; -}; - -template<> -struct Valtype_base<32> -{ - typedef uint32_t Valtype; - typedef int32_t Signed_valtype; -}; - -template<> -struct Valtype_base<64> -{ - typedef uint64_t Valtype; - typedef int64_t Signed_valtype; -}; - -// Convert_endian is a template based on size and on whether the host -// and target have the same endianness. It defines the type Valtype -// as Valtype_base does, and also defines a function convert_host -// which takes an argument of type Valtype and returns the same value, -// but swapped if the host and target have different endianness. - -template -struct Convert_endian; - -template -struct Convert_endian -{ - typedef typename Valtype_base::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { return v; } -}; - -template<> -struct Convert_endian<8, false> -{ - typedef Valtype_base<8>::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { return v; } -}; - -template<> -struct Convert_endian<16, false> -{ - typedef Valtype_base<16>::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { return bswap_16(v); } -}; - -template<> -struct Convert_endian<32, false> -{ - typedef Valtype_base<32>::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { return bswap_32(v); } -}; - -template<> -struct Convert_endian<64, false> -{ - typedef Valtype_base<64>::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { return bswap_64(v); } -}; - -// Convert is a template based on size and on whether the target is -// big endian. It defines Valtype and convert_host like -// Convert_endian. That is, it is just like Convert_endian except in -// the meaning of the second template parameter. - -template -struct Convert -{ - typedef typename Valtype_base::Valtype Valtype; - - static inline Valtype - convert_host(Valtype v) - { - return Convert_endian - ::convert_host(v); - } -}; - -// Swap is a template based on size and on whether the target is big -// endian. It defines the type Valtype and the functions readval and -// writeval. The functions read and write values of the appropriate -// size out of buffers, swapping them if necessary. readval and -// writeval are overloaded to take pointers to the appropriate type or -// pointers to unsigned char. - -template -struct Swap -{ - typedef typename Valtype_base::Valtype Valtype; - - static inline Valtype - readval(const Valtype* wv) - { return Convert::convert_host(*wv); } - - static inline void - writeval(Valtype* wv, Valtype v) - { *wv = Convert::convert_host(v); } - - static inline Valtype - readval(const unsigned char* wv) - { return readval(reinterpret_cast(wv)); } - - static inline void - writeval(unsigned char* wv, Valtype v) - { writeval(reinterpret_cast(wv), v); } -}; - -// We need to specialize the 8-bit version of Swap to avoid -// conflicting overloads, since both versions of readval and writeval -// will have the same type parameters. - -template -struct Swap<8, big_endian> -{ - typedef typename Valtype_base<8>::Valtype Valtype; - - static inline Valtype - readval(const Valtype* wv) - { return *wv; } - - static inline void - writeval(Valtype* wv, Valtype v) - { *wv = v; } -}; - -// Swap_unaligned is a template based on size and on whether the -// target is big endian. It defines the type Valtype and the -// functions readval and writeval. The functions read and write -// values of the appropriate size out of buffers which may be -// misaligned. - -template -struct Swap_unaligned; - -template -struct Swap_unaligned<8, big_endian> -{ - typedef typename Valtype_base<8>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { return *wv; } - - static inline void - writeval(unsigned char* wv, Valtype v) - { *wv = v; } -}; - -template<> -struct Swap_unaligned<16, false> -{ - typedef Valtype_base<16>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return (wv[1] << 8) | wv[0]; - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[1] = v >> 8; - wv[0] = v; - } -}; - -template<> -struct Swap_unaligned<16, true> -{ - typedef Valtype_base<16>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return (wv[0] << 8) | wv[1]; - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[0] = v >> 8; - wv[1] = v; - } -}; - -template<> -struct Swap_unaligned<32, false> -{ - typedef Valtype_base<32>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return (wv[3] << 24) | (wv[2] << 16) | (wv[1] << 8) | wv[0]; - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[3] = v >> 24; - wv[2] = v >> 16; - wv[1] = v >> 8; - wv[0] = v; - } -}; - -template<> -struct Swap_unaligned<32, true> -{ - typedef Valtype_base<32>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return (wv[0] << 24) | (wv[1] << 16) | (wv[2] << 8) | wv[3]; - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[0] = v >> 24; - wv[1] = v >> 16; - wv[2] = v >> 8; - wv[3] = v; - } -}; - -template<> -struct Swap_unaligned<64, false> -{ - typedef Valtype_base<64>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return ((static_cast(wv[7]) << 56) - | (static_cast(wv[6]) << 48) - | (static_cast(wv[5]) << 40) - | (static_cast(wv[4]) << 32) - | (static_cast(wv[3]) << 24) - | (static_cast(wv[2]) << 16) - | (static_cast(wv[1]) << 8) - | static_cast(wv[0])); - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[7] = v >> 56; - wv[6] = v >> 48; - wv[5] = v >> 40; - wv[4] = v >> 32; - wv[3] = v >> 24; - wv[2] = v >> 16; - wv[1] = v >> 8; - wv[0] = v; - } -}; - -template<> -struct Swap_unaligned<64, true> -{ - typedef Valtype_base<64>::Valtype Valtype; - - static inline Valtype - readval(const unsigned char* wv) - { - return ((static_cast(wv[0]) << 56) - | (static_cast(wv[1]) << 48) - | (static_cast(wv[2]) << 40) - | (static_cast(wv[3]) << 32) - | (static_cast(wv[4]) << 24) - | (static_cast(wv[5]) << 16) - | (static_cast(wv[6]) << 8) - | static_cast(wv[7])); - } - - static inline void - writeval(unsigned char* wv, Valtype v) - { - wv[0] = v >> 56; - wv[1] = v >> 48; - wv[2] = v >> 40; - wv[3] = v >> 32; - wv[4] = v >> 24; - wv[5] = v >> 16; - wv[6] = v >> 8; - wv[7] = v; - } -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_SWAP_H) diff --git a/contrib/binutils-2.22/elfcpp/i386.h b/contrib/binutils-2.22/elfcpp/i386.h deleted file mode 100644 index 6903859f98..0000000000 --- a/contrib/binutils-2.22/elfcpp/i386.h +++ /dev/null @@ -1,98 +0,0 @@ -// i386.h -- ELF definitions specific to EM_386 -*- C++ -*- - -// Copyright 2006, 2007, 2010 Free Software Foundation, Inc. -// Written by Ian Lance Taylor . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_I386_H -#define ELFCPP_I386_H - -// Documentation for the TLS relocs is taken from -// http://people.redhat.com/drepper/tls.pdf -// http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt - -namespace elfcpp -{ - -enum -{ - R_386_NONE = 0, // No reloc - R_386_32 = 1, // Direct 32 bit zero extended - R_386_PC32 = 2, // PC relative 32 bit signed - R_386_GOT32 = 3, // 32 bit GOT entry - R_386_PLT32 = 4, // 32 bit PLT address - R_386_COPY = 5, // Copy symbol at runtime - R_386_GLOB_DAT = 6, // Create GOT entry - R_386_JUMP_SLOT = 7, // Create PLT entry - R_386_RELATIVE = 8, // Adjust by program base - R_386_GOTOFF = 9, // 32-bit GOT offset - R_386_GOTPC = 10, // 32-bit PC relative offset to GOT - // Used by Sun. - R_386_32PLT = 11, - // TLS extensions. - R_386_TLS_TPOFF = 14, // Outstanding Initial Exec reloc, gnu-style (both) - R_386_TLS_IE = 15, // Initial Initial Exec reloc, gnu-style (no-PIC) - R_386_TLS_GOTIE = 16, // Initial Initial Exec reloc, gnu-style (for PIC) - R_386_TLS_LE = 17, // Initial Local Exec reloc, gnu-style - R_386_TLS_GD = 18, // Initial General Dynamic reloc, gnu-style - R_386_TLS_LDM = 19, // Initial Local Dynamic reloc, gnu-style - // GNU extensions. - R_386_16 = 20, // Direct 16 bit zero extended - R_386_PC16 = 21, // 16 bit sign extended pc relative - R_386_8 = 22, // Direct 8 bit sign extended - R_386_PC8 = 23, // 8 bit sign extended pc relative - // More TLS relocs. - R_386_TLS_GD_32 = 24, // Initial General Dynamic reloc, sun-style - R_386_TLS_GD_PUSH = 25, // Initial General Dynamic reloc, sun-style - R_386_TLS_GD_CALL = 26, // Initial General Dynamic reloc, sun-style - R_386_TLS_GD_POP = 27, // Initial General Dynamic reloc, sun-style - R_386_TLS_LDM_32 = 28, // Initial Local Dynamic reloc, sun-style - R_386_TLS_LDM_PUSH = 29, // Initial Local Dynamic reloc, sun-style - R_386_TLS_LDM_CALL = 30, // Initial Local Dynamic reloc, sun-style - R_386_TLS_LDM_POP = 31, // Initial Local Dynamic reloc, sun-style - R_386_TLS_LDO_32 = 32, // Initial Local Dynamic reloc, sun+gnu styles - R_386_TLS_IE_32 = 33, // Initial Initial Exec reloc, sun-style - R_386_TLS_LE_32 = 34, // Initial Local Exec reloc, sun-style - R_386_TLS_DTPMOD32 = 35, // Outstanding General/Local Dynamic reloc, sun+gnu - R_386_TLS_DTPOFF32 = 36, // Outstanding General Dynamic reloc, sun+gnu - R_386_TLS_TPOFF32 = 37, // Outstanding Initial Exec reloc, sun-style - R_386_TLS_GOTDESC = 39, // GOT offset for TLS descriptor - R_386_TLS_DESC_CALL = 40, // Marker of call through TLS desc for relaxation - R_386_TLS_DESC = 41, // TLS descriptor containing pointer to code and - // to argument, returning TLS offset for symbol - R_386_IRELATIVE = 42, // Adjust indirectly by program base - // Used by Intel. - R_386_USED_BY_INTEL_200 = 200, - // GNU vtable garbage collection extensions. - R_386_GNU_VTINHERIT = 250, - R_386_GNU_VTENTRY = 251 -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_I386_H) diff --git a/contrib/binutils-2.22/elfcpp/powerpc.h b/contrib/binutils-2.22/elfcpp/powerpc.h deleted file mode 100644 index 2bcb3ca12e..0000000000 --- a/contrib/binutils-2.22/elfcpp/powerpc.h +++ /dev/null @@ -1,189 +0,0 @@ -// powerpc.h -- ELF definitions specific to EM_PPC and EM_PPC64 -*- C++ -*- - -// Copyright 2008, 2010 Free Software Foundation, Inc. -// Written by David S. Miller . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_POWERPC_H -#define ELFCPP_POWERPC_H - -namespace elfcpp -{ - -// The relocation numbers for 32-bit and 64-bit powerpc are nearly -// identical. Therefore I've adopted the convention of using -// R_POWERPC_foo for values which are the same in R_PPC_* and R_PPC64_*. -// For relocations which are specific to the word size I will use -// R_PPC_foo or R_PPC64_foo. -enum -{ - R_POWERPC_NONE = 0, - R_POWERPC_ADDR32 = 1, - R_POWERPC_ADDR24 = 2, - R_POWERPC_ADDR16 = 3, - R_POWERPC_ADDR16_LO = 4, - R_POWERPC_ADDR16_HI = 5, - R_POWERPC_ADDR16_HA = 6, - R_POWERPC_ADDR14 = 7, - R_POWERPC_ADDR14_BRTAKEN = 8, - R_POWERPC_ADDR14_BRNTAKEN = 9, - R_POWERPC_REL24 = 10, - R_POWERPC_REL14 = 11, - R_POWERPC_REL14_BRTAKEN = 12, - R_POWERPC_REL14_BRNTAKEN = 13, - R_POWERPC_GOT16 = 14, - R_POWERPC_GOT16_LO = 15, - R_POWERPC_GOT16_HI = 16, - R_POWERPC_GOT16_HA = 17, - R_PPC_PLTREL24 = 18, - R_POWERPC_COPY = 19, - R_POWERPC_GLOB_DAT = 20, - R_POWERPC_JMP_SLOT = 21, - R_POWERPC_RELATIVE = 22, - R_PPC_LOCAL24PC = 23, - R_POWERPC_UADDR32 = 24, - R_POWERPC_UADDR16 = 25, - R_POWERPC_REL32 = 26, - R_POWERPC_PLT32 = 27, - R_POWERPC_PLTREL32 = 28, - R_POWERPC_PLT16_LO = 29, - R_POWERPC_PLT16_HI = 30, - R_POWERPC_PLT16_HA = 31, - R_PPC_SDAREL16 = 32, - R_POWERPC_SECTOFF = 33, - R_POWERPC_SECTOFF_LO = 34, - R_POWERPC_SECTOFF_HI = 35, - R_POWERPC_SECTOFF_HA = 36, - R_POWERPC_ADDR30 = 37, - R_PPC64_ADDR64 = 38, - R_PPC64_ADDR16_HIGHER = 39, - R_PPC64_ADDR16_HIGHERA = 40, - R_PPC64_ADDR16_HIGHEST = 41, - R_PPC64_ADDR16_HIGHESTA = 42, - R_PPC64_UADDR64 = 43, - R_PPC64_REL64 = 44, - R_PPC64_PLT64 = 45, - R_PPC64_PLTREL64 = 46, - R_PPC64_TOC16 = 47, - R_PPC64_TOC16_LO = 48, - R_PPC64_TOC16_HI = 49, - R_PPC64_TOC16_HA = 50, - R_PPC64_TOC = 51, - R_PPC64_PLTGOT16 = 52, - R_PPC64_PLTGOT16_LO = 53, - R_PPC64_PLTGOT16_HI = 54, - R_PPC64_PLTGOT16_HA = 55, - R_PPC64_ADDR16_DS = 56, - R_PPC64_ADDR16_LO_DS = 57, - R_PPC64_GOT16_DS = 58, - R_PPC64_GOT16_LO_DS = 59, - R_PPC64_PLT16_LO_DS = 60, - R_PPC64_SECTOFF_DS = 61, - R_PPC64_SECTOFF_LO_DS = 62, - R_PPC64_TOC16_DS = 63, - R_PPC64_TOC16_LO_DS = 64, - R_PPC64_PLTGOT16_DS = 65, - R_PPC64_PLTGOT16_LO_DS = 66, - R_POWERPC_TLS = 67, - R_POWERPC_DTPMOD = 68, - R_POWERPC_TPREL16 = 69, - R_POWERPC_TPREL16_LO = 70, - R_POWERPC_TPREL16_HI = 71, - R_POWERPC_TPREL16_HA = 72, - R_POWERPC_TPREL = 73, - R_POWERPC_DTPREL16 = 74, - R_POWERPC_DTPREL16_LO = 75, - R_POWERPC_DTPREL16_HI = 76, - R_POWERPC_DTPREL16_HA = 77, - R_POWERPC_DTPREL = 78, - R_POWERPC_GOT_TLSGD16 = 79, - R_POWERPC_GOT_TLSGD16_LO = 80, - R_POWERPC_GOT_TLSGD16_HI = 81, - R_POWERPC_GOT_TLSGD16_HA = 82, - R_POWERPC_GOT_TLSLD16 = 83, - R_POWERPC_GOT_TLSLD16_LO = 84, - R_POWERPC_GOT_TLSLD16_HI = 85, - R_POWERPC_GOT_TLSLD16_HA = 86, - R_POWERPC_GOT_TPREL16 = 87, - R_POWERPC_GOT_TPREL16_LO = 88, - R_POWERPC_GOT_TPREL16_HI = 89, - R_POWERPC_GOT_TPREL16_HA = 90, - R_POWERPC_GOT_DTPREL16 = 91, - R_POWERPC_GOT_DTPREL16_LO = 92, - R_POWERPC_GOT_DTPREL16_HI = 93, - R_POWERPC_GOT_DTPREL16_HA = 94, - R_PPC64_TPREL16_DS = 95, - R_PPC64_TPREL16_LO_DS = 96, - R_PPC64_TPREL16_HIGHER = 97, - R_PPC64_TPREL16_HIGHERA = 98, - R_PPC64_TPREL16_HIGHEST = 99, - R_PPC64_TPREL16_HIGHESTA = 100, - R_PPC64_DTPREL16_DS = 101, - R_PPC64_DTPREL16_LO_DS = 102, - R_PPC64_DTPREL16_HIGHER = 103, - R_PPC64_DTPREL16_HIGHERA = 104, - R_PPC64_DTPREL16_HIGHEST = 105, - R_PPC64_DTPREL16_HIGHESTA = 106, - R_PPC_EMB_NADDR32 = 101, - R_PPC_EMB_NADDR16 = 102, - R_PPC_EMB_NADDR16_LO = 103, - R_PPC_EMB_NADDR16_HI = 104, - R_PPC_EMB_NADDR16_HA = 105, - R_PPC_EMB_SDAI16 = 106, - R_PPC_EMB_SDA2I16 = 107, - R_PPC_EMB_SDA2REL = 108, - R_PPC_EMB_SDA21 = 109, - R_PPC_EMB_MRKREF = 110, - R_PPC_EMB_RELSEC16 = 111, - R_PPC_EMB_RELST_LO = 112, - R_PPC_EMB_RELST_HI = 113, - R_PPC_EMB_RELST_HA = 114, - R_PPC_EMB_BIT_FLD = 115, - R_PPC_EMB_RELSDA = 116, - - R_POWERPC_IRELATIVE = 248, - R_PPC_REL16 = 249, - R_PPC_REL16_LO = 250, - R_PPC_REL16_HI = 251, - R_PPC_REL16_HA = 252, - R_POWERPC_GNU_VTINHERIT = 253, - R_POWERPC_GNU_VTENTRY = 254, - R_PPC_TOC16 = 255, -}; - -// e_flags values defined for powerpc -enum -{ - EF_PPC_EMB = 0x80000000, // PowerPC embedded flag. - EF_PPC_RELOCATABLE = 0x00010000, // PowerPC -mrelocatable flag. */ - EF_PPC_RELOCATABLE_LIB = 0x00008000, // PowerPC -mrelocatable-lib flag. */ -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_POWERPC_H) diff --git a/contrib/binutils-2.22/elfcpp/sparc.h b/contrib/binutils-2.22/elfcpp/sparc.h deleted file mode 100644 index 6a9193b355..0000000000 --- a/contrib/binutils-2.22/elfcpp/sparc.h +++ /dev/null @@ -1,171 +0,0 @@ -// sparc.h -- ELF definitions specific to EM_SPARC -*- C++ -*- - -// Copyright 2008, 2010 Free Software Foundation, Inc. -// Written by David S. Miller . - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_SPARC_H -#define ELFCPP_SPARC_H - -// Documentation for the TLS relocs is taken from -// http://people.redhat.com/drepper/tls.pdf -// -// More full documentation on sparc specific ELF file -// format details can be found at -// -// http://docs.sun.com/app/docs/doc/819/0690/ -// "Linker and Libraries Guide" -// -// specifically Chapter 7 "Object File Format" and -// Chapter 8 "Thread-Local Storage" - -namespace elfcpp -{ - -enum -{ - R_SPARC_NONE = 0, // No reloc - R_SPARC_8 = 1, // Direct 8 bit - R_SPARC_16 = 2, // Direct 16 bit - R_SPARC_32 = 3, // Direct 32 bit - R_SPARC_DISP8 = 4, // PC relative 8 bit - R_SPARC_DISP16 = 5, // PC relative 16 bit - R_SPARC_DISP32 = 6, // PC relative 32 bit - R_SPARC_WDISP30 = 7, // PC relative 30 bit shifted - R_SPARC_WDISP22 = 8, // PC relative 22 bit shifted - R_SPARC_HI22 = 9, // High 22 bit - R_SPARC_22 = 10, // Direct 22 bit - R_SPARC_13 = 11, // Direct 13 bit - R_SPARC_LO10 = 12, // Truncated 10 bit - R_SPARC_GOT10 = 13, // Truncated 10 bit GOT entry - R_SPARC_GOT13 = 14, // 13 bit GOT entry - R_SPARC_GOT22 = 15, // 22 bit GOT entry shifted - R_SPARC_PC10 = 16, // PC relative 10 bit truncated - R_SPARC_PC22 = 17, // PC relative 22 bit shifted - R_SPARC_WPLT30 = 18, // 30 bit PC relative PLT address - R_SPARC_COPY = 19, // Copy symbol at runtime - R_SPARC_GLOB_DAT = 20, // Create GOT entry - R_SPARC_JMP_SLOT = 21, // Create PLT entry - R_SPARC_RELATIVE = 22, // Adjust by program base - R_SPARC_UA32 = 23, // Direct 32 bit unaligned - R_SPARC_PLT32 = 24, // Direct 32 bit ref to PLT entry - R_SPARC_HIPLT22 = 25, // High 22 bit PLT entry - R_SPARC_LOPLT10 = 26, // Truncated 10 bit PLT entry - R_SPARC_PCPLT32 = 27, // PC rel 32 bit ref to PLT entry - R_SPARC_PCPLT22 = 28, // PC rel high 22 bit PLT entry - R_SPARC_PCPLT10 = 29, // PC rel trunc 10 bit PLT entry - R_SPARC_10 = 30, // Direct 10 bit - R_SPARC_11 = 31, // Direct 11 bit - R_SPARC_64 = 32, // Direct 64 bit - R_SPARC_OLO10 = 33, // 10bit with secondary 13bit addend - R_SPARC_HH22 = 34, // Top 22 bits of direct 64 bit - R_SPARC_HM10 = 35, // High middle 10 bits of ... - R_SPARC_LM22 = 36, // Low middle 22 bits of ... - R_SPARC_PC_HH22 = 37, // Top 22 bits of pc rel 64 bit - R_SPARC_PC_HM10 = 38, // High middle 10 bit of ... - R_SPARC_PC_LM22 = 39, // Low miggle 22 bits of ... - R_SPARC_WDISP16 = 40, // PC relative 16 bit shifted - R_SPARC_WDISP19 = 41, // PC relative 19 bit shifted - R_SPARC_GLOB_JMP = 42, // was part of v9 ABI but was removed - R_SPARC_7 = 43, // Direct 7 bit - R_SPARC_5 = 44, // Direct 5 bit - R_SPARC_6 = 45, // Direct 6 bit - R_SPARC_DISP64 = 46, // PC relative 64 bit - R_SPARC_PLT64 = 47, // Direct 64 bit ref to PLT entry - R_SPARC_HIX22 = 48, // High 22 bit complemented - R_SPARC_LOX10 = 49, // Truncated 11 bit complemented - R_SPARC_H44 = 50, // Direct high 12 of 44 bit - R_SPARC_M44 = 51, // Direct mid 22 of 44 bit - R_SPARC_L44 = 52, // Direct low 10 of 44 bit - R_SPARC_REGISTER = 53, // Global register usage - R_SPARC_UA64 = 54, // Direct 64 bit unaligned - R_SPARC_UA16 = 55, // Direct 16 bit unaligned - R_SPARC_TLS_GD_HI22 = 56, // Initial General Dynamic reloc, high 22-bit - R_SPARC_TLS_GD_LO10 = 57, // Initial General Dynamic reloc, low 10-bit - R_SPARC_TLS_GD_ADD = 58, // Initial General Dynamic reloc, add - R_SPARC_TLS_GD_CALL = 59, // Initial General Dynamic reloc, call - R_SPARC_TLS_LDM_HI22 = 60, // Initial Local Dynamic reloc, high 22-bit - R_SPARC_TLS_LDM_LO10 = 61, // Initial Local Dynamic reloc, low 10-bit - R_SPARC_TLS_LDM_ADD = 62, // Initial Local Dynamic reloc, add - R_SPARC_TLS_LDM_CALL = 63, // Initial Local Dynamic reloc, call - R_SPARC_TLS_LDO_HIX22 = 64, // Initial Local Dynamic, high extended 22-bit - R_SPARC_TLS_LDO_LOX10 = 65, // Initial Local Dynamic, low extended 10-bit - R_SPARC_TLS_LDO_ADD = 66, // Initial Local Dynamic, add extended - R_SPARC_TLS_IE_HI22 = 67, // Initial Initial Exec reloc, high 22-bit - R_SPARC_TLS_IE_LO10 = 68, // Initial Initial Exec reloc, low 10-bit - R_SPARC_TLS_IE_LD = 69, // Initial Initial Exec reloc, load 32-bit - R_SPARC_TLS_IE_LDX = 70, // Initial Initial Exec reloc, load 64-bit - R_SPARC_TLS_IE_ADD = 71, // Initial Initial Exec reloc, add - R_SPARC_TLS_LE_HIX22 = 72, // Initial Local Exec reloc, high extended 22-bit - R_SPARC_TLS_LE_LOX10 = 73, // Initial Local Exec reloc, low extended 10-bit - R_SPARC_TLS_DTPMOD32 = 74, // Outstanding General/Local Dynamic reloc, 32-bit - R_SPARC_TLS_DTPMOD64 = 75, // Outstanding General/Local Dynamic reloc, 64-bit - R_SPARC_TLS_DTPOFF32 = 76, // Outstanding General Dynamic reloc, 32-bit - R_SPARC_TLS_DTPOFF64 = 77, // Outstanding General Dynamic reloc, 64-bit - R_SPARC_TLS_TPOFF32 = 78, // Outstanding Initial Exec reloc, 32-bit - R_SPARC_TLS_TPOFF64 = 79, // Outstanding Initial Exec reloc, 64-bit - - // GOT data code transformations - R_SPARC_GOTDATA_HIX22 = 80, - R_SPARC_GOTDATA_LOX10 = 81, - R_SPARC_GOTDATA_OP_HIX22 = 82, - R_SPARC_GOTDATA_OP_LOX10 = 83, - R_SPARC_GOTDATA_OP = 84, - - R_SPARC_H34 = 85, // Direct high 12 of 34 bit - R_SPARC_SIZE32 = 86, // size of symbol, 32-bit - R_SPARC_SIZE64 = 87, // size of symbol, 64-bit - - R_SPARC_IRELATIVE = 249, // Adjust indirectly by program base - - // GNU vtable garbage collection extensions. - R_SPARC_GNU_VTINHERIT = 250, - R_SPARC_GNU_VTENTRY = 251, - - R_SPARC_REV32 = 252, -}; - -// e_flags values defined for sparc -enum -{ - EF_SPARC_EXT_MASK = 0xffff00, // reserved for vendor extensions - EF_SPARC_32PLUS_MASK = 0xffff00, // bits indicating V8+ type - EF_SPARC_32PLUS = 0x000100, // generic V8+ features - EF_SPARC_SUN_US1 = 0x000200, // Sun UltraSPARC-I extensions - EF_SPARC_HAL_R1 = 0x000400, // HAL R1 extensions - EF_SPARC_SUN_US3 = 0x000800, // Sun UltraSPARC-III extensions - EF_SPARC_LEDATA = 0x800000, // little endian data - EF_SPARCV9_MM = 0x3, // memory model mask - EF_SPARCV9_TSO = 0x0, // total store ordering - EF_SPARCV9_PSO = 0x1, // partial store ordering - EF_SPARCV9_RMO = 0x2, // relaxed store ordering -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_SPARC_H) diff --git a/contrib/binutils-2.22/elfcpp/x86_64.h b/contrib/binutils-2.22/elfcpp/x86_64.h deleted file mode 100644 index ae7d0a8ba5..0000000000 --- a/contrib/binutils-2.22/elfcpp/x86_64.h +++ /dev/null @@ -1,101 +0,0 @@ -// x86-64.h -- ELF definitions specific to EM_X86_64 -*- C++ -*- - -// Copyright 2006, 2007, 2010 Free Software Foundation, Inc. -// Written by Andrew Chatham. - -// This file is part of elfcpp. - -// This program 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, or -// (at your option) any later version. - -// In addition to the permissions in the GNU Library General Public -// License, the Free Software Foundation gives you unlimited -// permission to link the compiled version of this file into -// combinations with other programs, and to distribute those -// combinations without any restriction coming from the use of this -// file. (The Library Public License restrictions do apply in other -// respects; for example, they cover modification of the file, and -/// distribution when not linked into a combined executable.) - -// 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 -// Library General Public License for more details. - -// You should have received a copy of the GNU Library 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. - -#ifndef ELFCPP_X86_64_H -#define ELFCPP_X86_64_H - -namespace elfcpp -{ - -// Documentation is taken from -// http://www.x86-64.org/documentation/abi-0.98.pdf -// elf.h -// Documentation for the TLS relocs is taken from -// http://people.redhat.com/drepper/tls.pdf -// http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt - -enum -{ - R_X86_64_NONE = 0, // No reloc - R_X86_64_64 = 1, // Direct 64 bit - R_X86_64_PC32 = 2, // PC relative 32 bit signed - R_X86_64_GOT32 = 3, // 32 bit GOT entry - R_X86_64_PLT32 = 4, // 32 bit PLT address - R_X86_64_COPY = 5, // Copy symbol at runtime - R_X86_64_GLOB_DAT = 6, // Create GOT entry - R_X86_64_JUMP_SLOT = 7, // Create PLT entry - R_X86_64_RELATIVE = 8, // Adjust by program base - R_X86_64_GOTPCREL = 9, // 32 bit signed PC relative offset to GOT - R_X86_64_32 = 10, // Direct 32 bit zero extended - R_X86_64_32S = 11, // Direct 32 bit sign extended - R_X86_64_16 = 12, // Direct 16 bit zero extended - R_X86_64_PC16 = 13, // 16 bit sign extended pc relative - R_X86_64_8 = 14, // Direct 8 bit sign extended - R_X86_64_PC8 = 15, // 8 bit sign extended pc relative - - // TLS relocations - R_X86_64_DTPMOD64 = 16, // ID of module containing symbol - R_X86_64_DTPOFF64 = 17, // Offset in module's TLS block - R_X86_64_TPOFF64 = 18, // Offset in initial TLS block - R_X86_64_TLSGD = 19, // 32 bit signed PC relative offset to two - // GOT entries for GD symbol - R_X86_64_TLSLD = 20, // 32 bit signed PC relative offset to two - // GOT entries for LD symbol - R_X86_64_DTPOFF32 = 21, // Offset in TLS block - R_X86_64_GOTTPOFF = 22, // 32 bit signed PC relative offset to GOT - // entry for IE symbol - R_X86_64_TPOFF32 = 23, // Offset in initial TLS block - - R_X86_64_PC64 = 24, // 64-bit PC relative - R_X86_64_GOTOFF64 = 25, // 64-bit GOT offset - R_X86_64_GOTPC32 = 26, // 32-bit PC relative offset to GOT - - R_X86_64_GOT64 = 27, // 64-bit GOT entry offset - R_X86_64_GOTPCREL64 = 28, // 64-bit PC relative offset to GOT entry - R_X86_64_GOTPC64 = 29, // 64-bit PC relative offset to GOT - R_X86_64_GOTPLT64 = 30, // Like GOT64, indicates that PLT entry needed - R_X86_64_PLTOFF64 = 31, // 64-bit GOT relative offset to PLT entry - - R_X86_64_SIZE32 = 32, - R_X86_64_SIZE64 = 33, - - R_X86_64_GOTPC32_TLSDESC = 34, // 32-bit PC relative to TLS descriptor in GOT - R_X86_64_TLSDESC_CALL = 35, // Relaxable call through TLS descriptor - R_X86_64_TLSDESC = 36, // 2 by 64-bit TLS descriptor - R_X86_64_IRELATIVE = 37, // Adjust indirectly by program base - // GNU vtable garbage collection extensions. - R_X86_64_GNU_VTINHERIT = 250, - R_X86_64_GNU_VTENTRY = 251 -}; - -} // End namespace elfcpp. - -#endif // !defined(ELFCPP_X86_64_H) diff --git a/contrib/binutils-2.22/gas/COPYING b/contrib/binutils-2.22/gas/COPYING deleted file mode 100644 index 94a9ed024d..0000000000 --- a/contrib/binutils-2.22/gas/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - 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 --git a/contrib/binutils-2.22/gas/README b/contrib/binutils-2.22/gas/README deleted file mode 100644 index c249fd97fd..0000000000 --- a/contrib/binutils-2.22/gas/README +++ /dev/null @@ -1,164 +0,0 @@ - README for GAS - -A number of things have changed since version 1 and the wonderful -world of gas looks very different. There's still a lot of irrelevant -garbage lying around that will be cleaned up in time. Documentation -is scarce, as are logs of the changes made since the last gas release. -My apologies, and I'll try to get something useful. - -Unpacking and Installation - Summary -==================================== - -See ../binutils/README. - -To build just the assembler, make the target all-gas. - -Documentation -============= - -The GAS release includes texinfo source for its manual, which can be processed -into `info' or `dvi' forms. - -The DVI form is suitable for printing or displaying; the commands for doing -this vary from system to system. On many systems, `lpr -d' will print a DVI -file. On others, you may need to run a program such as `dvips' to convert the -DVI file into a form your system can print. - -If you wish to build the DVI file, you will need to have TeX installed on your -system. You can rebuild it by typing: - - cd gas/doc - make as.dvi - -The Info form is viewable with the GNU Emacs `info' subsystem, or the -stand-alone `info' program, available as part of the GNU Texinfo distribution. -To build the info files, you will need the `makeinfo' program. Type: - - cd gas/doc - make info - -Specifying names for hosts and targets -====================================== - - The specifications used for hosts and targets in the `configure' -script are based on a three-part naming scheme, but some short -predefined aliases are also supported. The full naming scheme encodes -three pieces of information in the following pattern: - - ARCHITECTURE-VENDOR-OS - - For example, you can use the alias `sun4' as a HOST argument or in a -`--target=TARGET' option. The equivalent full name is -`sparc-sun-sunos4'. - - The `configure' script accompanying GAS does not provide any query -facility to list all supported host and target names or aliases. -`configure' calls the Bourne shell script `config.sub' to map -abbreviations to full names; you can read the script, if you wish, or -you can use it to test your guesses on abbreviations--for example: - - % sh config.sub i386v - i386-unknown-sysv - % sh config.sub i786v - Invalid configuration `i786v': machine `i786v' not recognized - - -`configure' options -=================== - - Here is a summary of the `configure' options and arguments that are -most often useful for building GAS. `configure' also has several other -options not listed here. - - configure [--help] - [--prefix=DIR] - [--srcdir=PATH] - [--host=HOST] - [--target=TARGET] - [--with-OPTION] - [--enable-OPTION] - -You may introduce options with a single `-' rather than `--' if you -prefer; but you may abbreviate option names if you use `--'. - -`--help' - Print a summary of the options to `configure', and exit. - -`-prefix=DIR' - Configure the source to install programs and files under directory - `DIR'. - -`--srcdir=PATH' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--host=HOST' - Configure GAS to run on the specified HOST. Normally the - configure script can figure this out automatically. - - There is no convenient way to generate a list of all available - hosts. - -`--target=TARGET' - Configure GAS for cross-assembling programs for the specified - TARGET. Without this option, GAS is configured to assemble .o files - that run on the same machine (HOST) as GAS itself. - - There is no convenient way to generate a list of all available - targets. - -`--enable-OPTION' - These flags tell the program or library being configured to - configure itself differently from the default for the specified - host/target combination. See below for a list of `--enable' - options recognized in the gas distribution. - -`configure' accepts other options, for compatibility with configuring -other GNU tools recursively; but these are the only options that affect -GAS or its supporting libraries. - -The `--enable' options recognized by software in the gas distribution are: - -`--enable-targets=...' - This causes one or more specified configurations to be added to those for - which BFD support is compiled. Currently gas cannot use any format other - than its compiled-in default, so this option is not very useful. - -`--enable-bfd-assembler' - This causes the assembler to use the new code being merged into it to use - BFD data structures internally, and use BFD for writing object files. - For most targets, this isn't supported yet. For most targets where it has - been done, it's already the default. So generally you won't need to use - this option. - -Compiler Support Hacks -====================== - -On a few targets, the assembler has been modified to support a feature -that is potentially useful when assembling compiler output, but which -may confuse assembly language programmers. If assembler encounters a -.word pseudo-op of the form symbol1-symbol2 (the difference of two -symbols), and the difference of those two symbols will not fit in 16 -bits, the assembler will create a branch around a long jump to -symbol1, and insert this into the output directly before the next -label: The .word will (instead of containing garbage, or giving an -error message) contain (the address of the long jump)-symbol2. This -allows the assembler to assemble jump tables that jump to locations -very far away into code that works properly. If the next label is -more than 32K away from the .word, you lose (silently); RMS claims -this will never happen. If the -K option is given, you will get a -warning message when this happens. - - -REPORTING BUGS IN GAS -===================== - -Bugs in gas should be reported to: - - bug-binutils@gnu.org. - -They may be cross-posted to gcc-bugs@gnu.org if they affect the use of -gas with gcc. They should not be reported just to gcc-bugs, since not -all of the maintainers read that list. - -See ../binutils/README for what we need in a bug report. diff --git a/contrib/binutils-2.22/gas/app.c b/contrib/binutils-2.22/gas/app.c deleted file mode 100644 index 3229336068..0000000000 --- a/contrib/binutils-2.22/gas/app.c +++ /dev/null @@ -1,1472 +0,0 @@ -/* This is the Assembler Pre-Processor - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90. */ -/* App, the assembler pre-processor. This pre-processor strips out - excess spaces, turns single-quoted characters into a decimal - constant, and turns the # in # into a - .linefile. This needs better error-handling. */ - -#include "as.h" - -#if (__STDC__ != 1) -#ifndef const -#define const /* empty */ -#endif -#endif - -#ifdef H_TICK_HEX -int enable_h_tick_hex = 0; -#endif - -#ifdef TC_M68K -/* Whether we are scrubbing in m68k MRI mode. This is different from - flag_m68k_mri, because the two flags will be affected by the .mri - pseudo-op at different times. */ -static int scrub_m68k_mri; - -/* The pseudo-op which switches in and out of MRI mode. See the - comment in do_scrub_chars. */ -static const char mri_pseudo[] = ".mri 0"; -#else -#define scrub_m68k_mri 0 -#endif - -#if defined TC_ARM && defined OBJ_ELF -/* The pseudo-op for which we need to special-case `@' characters. - See the comment in do_scrub_chars. */ -static const char symver_pseudo[] = ".symver"; -static const char * symver_state; -#endif - -static char lex[256]; -static const char symbol_chars[] = -"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -#define LEX_IS_SYMBOL_COMPONENT 1 -#define LEX_IS_WHITESPACE 2 -#define LEX_IS_LINE_SEPARATOR 3 -#define LEX_IS_COMMENT_START 4 -#define LEX_IS_LINE_COMMENT_START 5 -#define LEX_IS_TWOCHAR_COMMENT_1ST 6 -#define LEX_IS_STRINGQUOTE 8 -#define LEX_IS_COLON 9 -#define LEX_IS_NEWLINE 10 -#define LEX_IS_ONECHAR_QUOTE 11 -#ifdef TC_V850 -#define LEX_IS_DOUBLEDASH_1ST 12 -#endif -#ifdef TC_M32R -#define DOUBLEBAR_PARALLEL -#endif -#ifdef DOUBLEBAR_PARALLEL -#define LEX_IS_DOUBLEBAR_1ST 13 -#endif -#define LEX_IS_PARALLEL_SEPARATOR 14 -#ifdef H_TICK_HEX -#define LEX_IS_H 15 -#endif -#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT) -#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE) -#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR) -#define IS_PARALLEL_SEPARATOR(c) (lex[c] == LEX_IS_PARALLEL_SEPARATOR) -#define IS_COMMENT(c) (lex[c] == LEX_IS_COMMENT_START) -#define IS_LINE_COMMENT(c) (lex[c] == LEX_IS_LINE_COMMENT_START) -#define IS_NEWLINE(c) (lex[c] == LEX_IS_NEWLINE) - -static int process_escape (int); - -/* FIXME-soon: The entire lexer/parser thingy should be - built statically at compile time rather than dynamically - each and every time the assembler is run. xoxorich. */ - -void -do_scrub_begin (int m68k_mri ATTRIBUTE_UNUSED) -{ - const char *p; - int c; - - lex[' '] = LEX_IS_WHITESPACE; - lex['\t'] = LEX_IS_WHITESPACE; - lex['\r'] = LEX_IS_WHITESPACE; - lex['\n'] = LEX_IS_NEWLINE; - lex[':'] = LEX_IS_COLON; - -#ifdef TC_M68K - scrub_m68k_mri = m68k_mri; - - if (! m68k_mri) -#endif - { - lex['"'] = LEX_IS_STRINGQUOTE; - -#if ! defined (TC_HPPA) && ! defined (TC_I370) - /* I370 uses single-quotes to delimit integer, float constants. */ - lex['\''] = LEX_IS_ONECHAR_QUOTE; -#endif - -#ifdef SINGLE_QUOTE_STRINGS - lex['\''] = LEX_IS_STRINGQUOTE; -#endif - } - - /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop - in state 5 of do_scrub_chars must be changed. */ - - /* Note that these override the previous defaults, e.g. if ';' is a - comment char, then it isn't a line separator. */ - for (p = symbol_chars; *p; ++p) - lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT; - - for (c = 128; c < 256; ++c) - lex[c] = LEX_IS_SYMBOL_COMPONENT; - -#ifdef tc_symbol_chars - /* This macro permits the processor to specify all characters which - may appears in an operand. This will prevent the scrubber from - discarding meaningful whitespace in certain cases. The i386 - backend uses this to support prefixes, which can confuse the - scrubber as to whether it is parsing operands or opcodes. */ - for (p = tc_symbol_chars; *p; ++p) - lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT; -#endif - - /* The m68k backend wants to be able to change comment_chars. */ -#ifndef tc_comment_chars -#define tc_comment_chars comment_chars -#endif - for (p = tc_comment_chars; *p; p++) - lex[(unsigned char) *p] = LEX_IS_COMMENT_START; - - for (p = line_comment_chars; *p; p++) - lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START; - - for (p = line_separator_chars; *p; p++) - lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR; - -#ifdef tc_parallel_separator_chars - /* This macro permits the processor to specify all characters which - separate parallel insns on the same line. */ - for (p = tc_parallel_separator_chars; *p; p++) - lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR; -#endif - - /* Only allow slash-star comments if slash is not in use. - FIXME: This isn't right. We should always permit them. */ - if (lex['/'] == 0) - lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; - -#ifdef TC_M68K - if (m68k_mri) - { - lex['\''] = LEX_IS_STRINGQUOTE; - lex[';'] = LEX_IS_COMMENT_START; - lex['*'] = LEX_IS_LINE_COMMENT_START; - /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but - then it can't be used in an expression. */ - lex['!'] = LEX_IS_LINE_COMMENT_START; - } -#endif - -#ifdef TC_V850 - lex['-'] = LEX_IS_DOUBLEDASH_1ST; -#endif -#ifdef DOUBLEBAR_PARALLEL - lex['|'] = LEX_IS_DOUBLEBAR_1ST; -#endif -#ifdef TC_D30V - /* Must do this is we want VLIW instruction with "->" or "<-". */ - lex['-'] = LEX_IS_SYMBOL_COMPONENT; -#endif - -#ifdef H_TICK_HEX - if (enable_h_tick_hex) - { - lex['h'] = LEX_IS_H; - lex['H'] = LEX_IS_H; - } -#endif -} - -/* Saved state of the scrubber. */ -static int state; -static int old_state; -static char *out_string; -static char out_buf[20]; -static int add_newlines; -static char *saved_input; -static int saved_input_len; -static char input_buffer[32 * 1024]; -static const char *mri_state; -static char mri_last_ch; - -/* Data structure for saving the state of app across #include's. Note that - app is called asynchronously to the parsing of the .include's, so our - state at the time .include is interpreted is completely unrelated. - That's why we have to save it all. */ - -struct app_save -{ - int state; - int old_state; - char * out_string; - char out_buf[sizeof (out_buf)]; - int add_newlines; - char * saved_input; - int saved_input_len; -#ifdef TC_M68K - int scrub_m68k_mri; -#endif - const char * mri_state; - char mri_last_ch; -#if defined TC_ARM && defined OBJ_ELF - const char * symver_state; -#endif -}; - -char * -app_push (void) -{ - register struct app_save *saved; - - saved = (struct app_save *) xmalloc (sizeof (*saved)); - saved->state = state; - saved->old_state = old_state; - saved->out_string = out_string; - memcpy (saved->out_buf, out_buf, sizeof (out_buf)); - saved->add_newlines = add_newlines; - if (saved_input == NULL) - saved->saved_input = NULL; - else - { - saved->saved_input = (char *) xmalloc (saved_input_len); - memcpy (saved->saved_input, saved_input, saved_input_len); - saved->saved_input_len = saved_input_len; - } -#ifdef TC_M68K - saved->scrub_m68k_mri = scrub_m68k_mri; -#endif - saved->mri_state = mri_state; - saved->mri_last_ch = mri_last_ch; -#if defined TC_ARM && defined OBJ_ELF - saved->symver_state = symver_state; -#endif - - /* do_scrub_begin() is not useful, just wastes time. */ - - state = 0; - saved_input = NULL; - - return (char *) saved; -} - -void -app_pop (char *arg) -{ - register struct app_save *saved = (struct app_save *) arg; - - /* There is no do_scrub_end (). */ - state = saved->state; - old_state = saved->old_state; - out_string = saved->out_string; - memcpy (out_buf, saved->out_buf, sizeof (out_buf)); - add_newlines = saved->add_newlines; - if (saved->saved_input == NULL) - saved_input = NULL; - else - { - gas_assert (saved->saved_input_len <= (int) (sizeof input_buffer)); - memcpy (input_buffer, saved->saved_input, saved->saved_input_len); - saved_input = input_buffer; - saved_input_len = saved->saved_input_len; - free (saved->saved_input); - } -#ifdef TC_M68K - scrub_m68k_mri = saved->scrub_m68k_mri; -#endif - mri_state = saved->mri_state; - mri_last_ch = saved->mri_last_ch; -#if defined TC_ARM && defined OBJ_ELF - symver_state = saved->symver_state; -#endif - - free (arg); -} - -/* @@ This assumes that \n &c are the same on host and target. This is not - necessarily true. */ - -static int -process_escape (int ch) -{ - switch (ch) - { - case 'b': - return '\b'; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case '\'': - return '\''; - case '"': - return '\"'; - default: - return ch; - } -} - -/* This function is called to process input characters. The GET - parameter is used to retrieve more input characters. GET should - set its parameter to point to a buffer, and return the length of - the buffer; it should return 0 at end of file. The scrubbed output - characters are put into the buffer starting at TOSTART; the TOSTART - buffer is TOLEN bytes in length. The function returns the number - of scrubbed characters put into TOSTART. This will be TOLEN unless - end of file was seen. This function is arranged as a state - machine, and saves its state so that it may return at any point. - This is the way the old code used to work. */ - -int -do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen) -{ - char *to = tostart; - char *toend = tostart + tolen; - char *from; - char *fromend; - int fromlen; - register int ch, ch2 = 0; - /* Character that started the string we're working on. */ - static char quotechar; - - /*State 0: beginning of normal line - 1: After first whitespace on line (flush more white) - 2: After first non-white (opcode) on line (keep 1white) - 3: after second white on line (into operands) (flush white) - 4: after putting out a .linefile, put out digits - 5: parsing a string, then go to old-state - 6: putting out \ escape in a "d string. - 7: no longer used - 8: no longer used - 9: After seeing symbol char in state 3 (keep 1white after symchar) - 10: After seeing whitespace in state 9 (keep white before symchar) - 11: After seeing a symbol character in state 0 (eg a label definition) - -1: output string in out_string and go to the state in old_state - -2: flush text until a '*' '/' is seen, then go to state old_state -#ifdef TC_V850 - 12: After seeing a dash, looking for a second dash as a start - of comment. -#endif -#ifdef DOUBLEBAR_PARALLEL - 13: After seeing a vertical bar, looking for a second - vertical bar as a parallel expression separator. -#endif -#ifdef TC_PREDICATE_START_CHAR - 14: After seeing a predicate start character at state 0, looking - for a predicate end character as predicate. - 15: After seeing a predicate start character at state 1, looking - for a predicate end character as predicate. -#endif -#ifdef TC_Z80 - 16: After seeing an 'a' or an 'A' at the start of a symbol - 17: After seeing an 'f' or an 'F' in state 16 -#endif - */ - - /* I added states 9 and 10 because the MIPS ECOFF assembler uses - constructs like ``.loc 1 20''. This was turning into ``.loc - 120''. States 9 and 10 ensure that a space is never dropped in - between characters which could appear in an identifier. Ian - Taylor, ian@cygnus.com. - - I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works - correctly on the PA (and any other target where colons are optional). - Jeff Law, law@cs.utah.edu. - - I added state 13 so that something like "cmp r1, r2 || trap #1" does not - get squashed into "cmp r1,r2||trap#1", with the all important space - between the 'trap' and the '#1' being eliminated. nickc@cygnus.com */ - - /* This macro gets the next input character. */ - -#define GET() \ - (from < fromend \ - ? * (unsigned char *) (from++) \ - : (saved_input = NULL, \ - fromlen = (*get) (input_buffer, sizeof input_buffer), \ - from = input_buffer, \ - fromend = from + fromlen, \ - (fromlen == 0 \ - ? EOF \ - : * (unsigned char *) (from++)))) - - /* This macro pushes a character back on the input stream. */ - -#define UNGET(uch) (*--from = (uch)) - - /* This macro puts a character into the output buffer. If this - character fills the output buffer, this macro jumps to the label - TOFULL. We use this rather ugly approach because we need to - handle two different termination conditions: EOF on the input - stream, and a full output buffer. It would be simpler if we - always read in the entire input stream before processing it, but - I don't want to make such a significant change to the assembler's - memory usage. */ - -#define PUT(pch) \ - do \ - { \ - *to++ = (pch); \ - if (to >= toend) \ - goto tofull; \ - } \ - while (0) - - if (saved_input != NULL) - { - from = saved_input; - fromend = from + saved_input_len; - } - else - { - fromlen = (*get) (input_buffer, sizeof input_buffer); - if (fromlen == 0) - return 0; - from = input_buffer; - fromend = from + fromlen; - } - - while (1) - { - /* The cases in this switch end with continue, in order to - branch back to the top of this while loop and generate the - next output character in the appropriate state. */ - switch (state) - { - case -1: - ch = *out_string++; - if (*out_string == '\0') - { - state = old_state; - old_state = 3; - } - PUT (ch); - continue; - - case -2: - for (;;) - { - do - { - ch = GET (); - - if (ch == EOF) - { - as_warn (_("end of file in comment")); - goto fromeof; - } - - if (ch == '\n') - PUT ('\n'); - } - while (ch != '*'); - - while ((ch = GET ()) == '*') - ; - - if (ch == EOF) - { - as_warn (_("end of file in comment")); - goto fromeof; - } - - if (ch == '/') - break; - - UNGET (ch); - } - - state = old_state; - UNGET (' '); - continue; - - case 4: - ch = GET (); - if (ch == EOF) - goto fromeof; - else if (ch >= '0' && ch <= '9') - PUT (ch); - else - { - while (ch != EOF && IS_WHITESPACE (ch)) - ch = GET (); - if (ch == '"') - { - quotechar = ch; - state = 5; - old_state = 3; - PUT (ch); - } - else - { - while (ch != EOF && ch != '\n') - ch = GET (); - state = 0; - PUT (ch); - } - } - continue; - - case 5: - /* We are going to copy everything up to a quote character, - with special handling for a backslash. We try to - optimize the copying in the simple case without using the - GET and PUT macros. */ - { - char *s; - int len; - - for (s = from; s < fromend; s++) - { - ch = *s; - if (ch == '\\' - || ch == quotechar - || ch == '\n') - break; - } - len = s - from; - if (len > toend - to) - len = toend - to; - if (len > 0) - { - memcpy (to, from, len); - to += len; - from += len; - if (to >= toend) - goto tofull; - } - } - - ch = GET (); - if (ch == EOF) - { - /* This buffer is here specifically so - that the UNGET below will work. */ - static char one_char_buf[1]; - - as_warn (_("end of file in string; '%c' inserted"), quotechar); - state = old_state; - from = fromend = one_char_buf + 1; - fromlen = 1; - UNGET ('\n'); - PUT (quotechar); - } - else if (ch == quotechar) - { - state = old_state; - PUT (ch); - } -#ifndef NO_STRING_ESCAPES - else if (ch == '\\') - { - state = 6; - PUT (ch); - } -#endif - else if (scrub_m68k_mri && ch == '\n') - { - /* Just quietly terminate the string. This permits lines like - bne label loop if we haven't reach end yet. */ - state = old_state; - UNGET (ch); - PUT ('\''); - } - else - { - PUT (ch); - } - continue; - - case 6: - state = 5; - ch = GET (); - switch (ch) - { - /* Handle strings broken across lines, by turning '\n' into - '\\' and 'n'. */ - case '\n': - UNGET ('n'); - add_newlines++; - PUT ('\\'); - continue; - - case EOF: - as_warn (_("end of file in string; '%c' inserted"), quotechar); - PUT (quotechar); - continue; - - case '"': - case '\\': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - case 'v': - case 'x': - case 'X': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - break; - - default: -#ifdef ONLY_STANDARD_ESCAPES - as_warn (_("unknown escape '\\%c' in string; ignored"), ch); -#endif - break; - } - PUT (ch); - continue; - -#ifdef DOUBLEBAR_PARALLEL - case 13: - ch = GET (); - if (ch != '|') - abort (); - - /* Reset back to state 1 and pretend that we are parsing a - line from just after the first white space. */ - state = 1; - PUT ('|'); -#ifdef TC_TIC6X - /* "||^" is used for SPMASKed instructions. */ - ch = GET (); - if (ch == EOF) - goto fromeof; - else if (ch == '^') - PUT ('^'); - else - UNGET (ch); -#endif - continue; -#endif -#ifdef TC_Z80 - case 16: - /* We have seen an 'a' at the start of a symbol, look for an 'f'. */ - ch = GET (); - if (ch == 'f' || ch == 'F') - { - state = 17; - PUT (ch); - } - else - { - state = 9; - break; - } - case 17: - /* We have seen "af" at the start of a symbol, - a ' here is a part of that symbol. */ - ch = GET (); - state = 9; - if (ch == '\'') - /* Change to avoid warning about unclosed string. */ - PUT ('`'); - else if (ch != EOF) - UNGET (ch); - break; -#endif - } - - /* OK, we are somewhere in states 0 through 4 or 9 through 11. */ - - /* flushchar: */ - ch = GET (); - -#ifdef TC_PREDICATE_START_CHAR - if (ch == TC_PREDICATE_START_CHAR && (state == 0 || state == 1)) - { - state += 14; - PUT (ch); - continue; - } - else if (state == 14 || state == 15) - { - if (ch == TC_PREDICATE_END_CHAR) - { - state -= 14; - PUT (ch); - ch = GET (); - } - else - { - PUT (ch); - continue; - } - } -#endif - - recycle: - -#if defined TC_ARM && defined OBJ_ELF - /* We need to watch out for .symver directives. See the comment later - in this function. */ - if (symver_state == NULL) - { - if ((state == 0 || state == 1) && ch == symver_pseudo[0]) - symver_state = symver_pseudo + 1; - } - else - { - /* We advance to the next state if we find the right - character. */ - if (ch != '\0' && (*symver_state == ch)) - ++symver_state; - else if (*symver_state != '\0') - /* We did not get the expected character, or we didn't - get a valid terminating character after seeing the - entire pseudo-op, so we must go back to the beginning. */ - symver_state = NULL; - else - { - /* We've read the entire pseudo-op. If this is the end - of the line, go back to the beginning. */ - if (IS_NEWLINE (ch)) - symver_state = NULL; - } - } -#endif /* TC_ARM && OBJ_ELF */ - -#ifdef TC_M68K - /* We want to have pseudo-ops which control whether we are in - MRI mode or not. Unfortunately, since m68k MRI mode affects - the scrubber, that means that we need a special purpose - recognizer here. */ - if (mri_state == NULL) - { - if ((state == 0 || state == 1) - && ch == mri_pseudo[0]) - mri_state = mri_pseudo + 1; - } - else - { - /* We advance to the next state if we find the right - character, or if we need a space character and we get any - whitespace character, or if we need a '0' and we get a - '1' (this is so that we only need one state to handle - ``.mri 0'' and ``.mri 1''). */ - if (ch != '\0' - && (*mri_state == ch - || (*mri_state == ' ' - && lex[ch] == LEX_IS_WHITESPACE) - || (*mri_state == '0' - && ch == '1'))) - { - mri_last_ch = ch; - ++mri_state; - } - else if (*mri_state != '\0' - || (lex[ch] != LEX_IS_WHITESPACE - && lex[ch] != LEX_IS_NEWLINE)) - { - /* We did not get the expected character, or we didn't - get a valid terminating character after seeing the - entire pseudo-op, so we must go back to the - beginning. */ - mri_state = NULL; - } - else - { - /* We've read the entire pseudo-op. mips_last_ch is - either '0' or '1' indicating whether to enter or - leave MRI mode. */ - do_scrub_begin (mri_last_ch == '1'); - mri_state = NULL; - - /* We continue handling the character as usual. The - main gas reader must also handle the .mri pseudo-op - to control expression parsing and the like. */ - } - } -#endif - - if (ch == EOF) - { - if (state != 0) - { - as_warn (_("end of file not at end of a line; newline inserted")); - state = 0; - PUT ('\n'); - } - goto fromeof; - } - - switch (lex[ch]) - { - case LEX_IS_WHITESPACE: - do - { - ch = GET (); - } - while (ch != EOF && IS_WHITESPACE (ch)); - if (ch == EOF) - goto fromeof; - - if (state == 0) - { - /* Preserve a single whitespace character at the - beginning of a line. */ - state = 1; - UNGET (ch); - PUT (' '); - break; - } - -#ifdef KEEP_WHITE_AROUND_COLON - if (lex[ch] == LEX_IS_COLON) - { - /* Only keep this white if there's no white *after* the - colon. */ - ch2 = GET (); - if (ch2 != EOF) - UNGET (ch2); - if (!IS_WHITESPACE (ch2)) - { - state = 9; - UNGET (ch); - PUT (' '); - break; - } - } -#endif - if (IS_COMMENT (ch) - || ch == '/' - || IS_LINE_SEPARATOR (ch) - || IS_PARALLEL_SEPARATOR (ch)) - { - if (scrub_m68k_mri) - { - /* In MRI mode, we keep these spaces. */ - UNGET (ch); - PUT (' '); - break; - } - goto recycle; - } - - /* If we're in state 2 or 11, we've seen a non-white - character followed by whitespace. If the next character - is ':', this is whitespace after a label name which we - normally must ignore. In MRI mode, though, spaces are - not permitted between the label and the colon. */ - if ((state == 2 || state == 11) - && lex[ch] == LEX_IS_COLON - && ! scrub_m68k_mri) - { - state = 1; - PUT (ch); - break; - } - - switch (state) - { - case 1: - /* We can arrive here if we leave a leading whitespace - character at the beginning of a line. */ - goto recycle; - case 2: - state = 3; - if (to + 1 < toend) - { - /* Optimize common case by skipping UNGET/GET. */ - PUT (' '); /* Sp after opco */ - goto recycle; - } - UNGET (ch); - PUT (' '); - break; - case 3: -#ifndef TC_KEEP_OPERAND_SPACES - /* For TI C6X, we keep these spaces as they may separate - functional unit specifiers from operands. */ - if (scrub_m68k_mri) -#endif - { - /* In MRI mode, we keep these spaces. */ - UNGET (ch); - PUT (' '); - break; - } - goto recycle; /* Sp in operands */ - case 9: - case 10: -#ifndef TC_KEEP_OPERAND_SPACES - if (scrub_m68k_mri) -#endif - { - /* In MRI mode, we keep these spaces. */ - state = 3; - UNGET (ch); - PUT (' '); - break; - } - state = 10; /* Sp after symbol char */ - goto recycle; - case 11: - if (LABELS_WITHOUT_COLONS || flag_m68k_mri) - state = 1; - else - { - /* We know that ch is not ':', since we tested that - case above. Therefore this is not a label, so it - must be the opcode, and we've just seen the - whitespace after it. */ - state = 3; - } - UNGET (ch); - PUT (' '); /* Sp after label definition. */ - break; - default: - BAD_CASE (state); - } - break; - - case LEX_IS_TWOCHAR_COMMENT_1ST: - ch2 = GET (); - if (ch2 == '*') - { - for (;;) - { - do - { - ch2 = GET (); - if (ch2 != EOF && IS_NEWLINE (ch2)) - add_newlines++; - } - while (ch2 != EOF && ch2 != '*'); - - while (ch2 == '*') - ch2 = GET (); - - if (ch2 == EOF || ch2 == '/') - break; - - /* This UNGET will ensure that we count newlines - correctly. */ - UNGET (ch2); - } - - if (ch2 == EOF) - as_warn (_("end of file in multiline comment")); - - ch = ' '; - goto recycle; - } -#ifdef DOUBLESLASH_LINE_COMMENTS - else if (ch2 == '/') - { - do - { - ch = GET (); - } - while (ch != EOF && !IS_NEWLINE (ch)); - if (ch == EOF) - as_warn ("end of file in comment; newline inserted"); - state = 0; - PUT ('\n'); - break; - } -#endif - else - { - if (ch2 != EOF) - UNGET (ch2); - if (state == 9 || state == 10) - state = 3; - PUT (ch); - } - break; - - case LEX_IS_STRINGQUOTE: - quotechar = ch; - if (state == 10) - { - /* Preserve the whitespace in foo "bar". */ - UNGET (ch); - state = 3; - PUT (' '); - - /* PUT didn't jump out. We could just break, but we - know what will happen, so optimize a bit. */ - ch = GET (); - old_state = 3; - } - else if (state == 9) - old_state = 3; - else - old_state = state; - state = 5; - PUT (ch); - break; - -#ifndef IEEE_STYLE - case LEX_IS_ONECHAR_QUOTE: -#ifdef H_TICK_HEX - if (state == 9 && enable_h_tick_hex) - { - char c; - - c = GET (); - as_warn ("'%c found after symbol", c); - UNGET (c); - } -#endif - if (state == 10) - { - /* Preserve the whitespace in foo 'b'. */ - UNGET (ch); - state = 3; - PUT (' '); - break; - } - ch = GET (); - if (ch == EOF) - { - as_warn (_("end of file after a one-character quote; \\0 inserted")); - ch = 0; - } - if (ch == '\\') - { - ch = GET (); - if (ch == EOF) - { - as_warn (_("end of file in escape character")); - ch = '\\'; - } - else - ch = process_escape (ch); - } - sprintf (out_buf, "%d", (int) (unsigned char) ch); - - /* None of these 'x constants for us. We want 'x'. */ - if ((ch = GET ()) != '\'') - { -#ifdef REQUIRE_CHAR_CLOSE_QUOTE - as_warn (_("missing close quote; (assumed)")); -#else - if (ch != EOF) - UNGET (ch); -#endif - } - if (strlen (out_buf) == 1) - { - PUT (out_buf[0]); - break; - } - if (state == 9) - old_state = 3; - else - old_state = state; - state = -1; - out_string = out_buf; - PUT (*out_string++); - break; -#endif - - case LEX_IS_COLON: -#ifdef KEEP_WHITE_AROUND_COLON - state = 9; -#else - if (state == 9 || state == 10) - state = 3; - else if (state != 3) - state = 1; -#endif - PUT (ch); - break; - - case LEX_IS_NEWLINE: - /* Roll out a bunch of newlines from inside comments, etc. */ - if (add_newlines) - { - --add_newlines; - UNGET (ch); - } - /* Fall through. */ - - case LEX_IS_LINE_SEPARATOR: - state = 0; - PUT (ch); - break; - - case LEX_IS_PARALLEL_SEPARATOR: - state = 1; - PUT (ch); - break; - -#ifdef TC_V850 - case LEX_IS_DOUBLEDASH_1ST: - ch2 = GET (); - if (ch2 != '-') - { - if (ch2 != EOF) - UNGET (ch2); - goto de_fault; - } - /* Read and skip to end of line. */ - do - { - ch = GET (); - } - while (ch != EOF && ch != '\n'); - - if (ch == EOF) - as_warn (_("end of file in comment; newline inserted")); - - state = 0; - PUT ('\n'); - break; -#endif -#ifdef DOUBLEBAR_PARALLEL - case LEX_IS_DOUBLEBAR_1ST: - ch2 = GET (); - if (ch2 != EOF) - UNGET (ch2); - if (ch2 != '|') - goto de_fault; - - /* Handle '||' in two states as invoking PUT twice might - result in the first one jumping out of this loop. We'd - then lose track of the state and one '|' char. */ - state = 13; - PUT ('|'); - break; -#endif - case LEX_IS_LINE_COMMENT_START: - /* FIXME-someday: The two character comment stuff was badly - thought out. On i386, we want '/' as line comment start - AND we want C style comments. hence this hack. The - whole lexical process should be reworked. xoxorich. */ - if (ch == '/') - { - ch2 = GET (); - if (ch2 == '*') - { - old_state = 3; - state = -2; - break; - } - else - { - UNGET (ch2); - } - } - - if (state == 0 || state == 1) /* Only comment at start of line. */ - { - int startch; - - startch = ch; - - do - { - ch = GET (); - } - while (ch != EOF && IS_WHITESPACE (ch)); - - if (ch == EOF) - { - as_warn (_("end of file in comment; newline inserted")); - PUT ('\n'); - break; - } - - if (ch < '0' || ch > '9' || state != 0 || startch != '#') - { - /* Not a cpp line. */ - while (ch != EOF && !IS_NEWLINE (ch)) - ch = GET (); - if (ch == EOF) - as_warn (_("end of file in comment; newline inserted")); - state = 0; - PUT ('\n'); - break; - } - /* Looks like `# 123 "filename"' from cpp. */ - UNGET (ch); - old_state = 4; - state = -1; - if (scrub_m68k_mri) - out_string = "\tlinefile "; - else - out_string = "\t.linefile "; - PUT (*out_string++); - break; - } - -#ifdef TC_D10V - /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true. - Trap is the only short insn that has a first operand that is - neither register nor label. - We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 . - We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is - already LEX_IS_LINE_COMMENT_START. However, it is the - only character in line_comment_chars for d10v, hence we - can recognize it as such. */ - /* An alternative approach would be to reset the state to 1 when - we see '||', '<'- or '->', but that seems to be overkill. */ - if (state == 10) - PUT (' '); -#endif - /* We have a line comment character which is not at the - start of a line. If this is also a normal comment - character, fall through. Otherwise treat it as a default - character. */ - if (strchr (tc_comment_chars, ch) == NULL - && (! scrub_m68k_mri - || (ch != '!' && ch != '*'))) - goto de_fault; - if (scrub_m68k_mri - && (ch == '!' || ch == '*' || ch == '#') - && state != 1 - && state != 10) - goto de_fault; - /* Fall through. */ - case LEX_IS_COMMENT_START: -#if defined TC_ARM && defined OBJ_ELF - /* On the ARM, `@' is the comment character. - Unfortunately this is also a special character in ELF .symver - directives (and .type, though we deal with those another way). - So we check if this line is such a directive, and treat - the character as default if so. This is a hack. */ - if ((symver_state != NULL) && (*symver_state == 0)) - goto de_fault; -#endif - -#ifdef TC_ARM - /* For the ARM, care is needed not to damage occurrences of \@ - by stripping the @ onwards. Yuck. */ - if (to > tostart && *(to - 1) == '\\') - /* Do not treat the @ as a start-of-comment. */ - goto de_fault; -#endif - -#ifdef WARN_COMMENTS - if (!found_comment) - as_where (&found_comment_file, &found_comment); -#endif - do - { - ch = GET (); - } - while (ch != EOF && !IS_NEWLINE (ch)); - if (ch == EOF) - as_warn (_("end of file in comment; newline inserted")); - state = 0; - PUT ('\n'); - break; - -#ifdef H_TICK_HEX - case LEX_IS_H: - /* Look for strings like H'[0-9A-Fa-f] and if found, replace - the H' with 0x to make them gas-style hex characters. */ - if (enable_h_tick_hex) - { - char quot; - - quot = GET (); - if (quot == '\'') - { - UNGET ('x'); - ch = '0'; - } - else - UNGET (quot); - } - /* FALL THROUGH */ -#endif - - case LEX_IS_SYMBOL_COMPONENT: - if (state == 10) - { - /* This is a symbol character following another symbol - character, with whitespace in between. We skipped - the whitespace earlier, so output it now. */ - UNGET (ch); - state = 3; - PUT (' '); - break; - } - -#ifdef TC_Z80 - /* "af'" is a symbol containing '\''. */ - if (state == 3 && (ch == 'a' || ch == 'A')) - { - state = 16; - PUT (ch); - ch = GET (); - if (ch == 'f' || ch == 'F') - { - state = 17; - PUT (ch); - break; - } - else - { - state = 9; - if (!IS_SYMBOL_COMPONENT (ch)) - { - if (ch != EOF) - UNGET (ch); - break; - } - } - } -#endif - if (state == 3) - state = 9; - - /* This is a common case. Quickly copy CH and all the - following symbol component or normal characters. */ - if (to + 1 < toend - && mri_state == NULL -#if defined TC_ARM && defined OBJ_ELF - && symver_state == NULL -#endif - ) - { - char *s; - int len; - - for (s = from; s < fromend; s++) - { - int type; - - ch2 = *(unsigned char *) s; - type = lex[ch2]; - if (type != 0 - && type != LEX_IS_SYMBOL_COMPONENT) - break; - } - - if (s > from) - /* Handle the last character normally, for - simplicity. */ - --s; - - len = s - from; - - if (len > (toend - to) - 1) - len = (toend - to) - 1; - - if (len > 0) - { - PUT (ch); - memcpy (to, from, len); - to += len; - from += len; - if (to >= toend) - goto tofull; - ch = GET (); - } - } - - /* Fall through. */ - default: - de_fault: - /* Some relatively `normal' character. */ - if (state == 0) - { - state = 11; /* Now seeing label definition. */ - } - else if (state == 1) - { - state = 2; /* Ditto. */ - } - else if (state == 9) - { - if (!IS_SYMBOL_COMPONENT (ch)) - state = 3; - } - else if (state == 10) - { - if (ch == '\\') - { - /* Special handling for backslash: a backslash may - be the beginning of a formal parameter (of a - macro) following another symbol character, with - whitespace in between. If that is the case, we - output a space before the parameter. Strictly - speaking, correct handling depends upon what the - macro parameter expands into; if the parameter - expands into something which does not start with - an operand character, then we don't want to keep - the space. We don't have enough information to - make the right choice, so here we are making the - choice which is more likely to be correct. */ - if (to + 1 >= toend) - { - /* If we're near the end of the buffer, save the - character for the next time round. Otherwise - we'll lose our state. */ - UNGET (ch); - goto tofull; - } - *to++ = ' '; - } - - state = 3; - } - PUT (ch); - break; - } - } - - /*NOTREACHED*/ - - fromeof: - /* We have reached the end of the input. */ - return to - tostart; - - tofull: - /* The output buffer is full. Save any input we have not yet - processed. */ - if (fromend > from) - { - saved_input = from; - saved_input_len = fromend - from; - } - else - saved_input = NULL; - - return to - tostart; -} diff --git a/contrib/binutils-2.22/gas/as.c b/contrib/binutils-2.22/gas/as.c deleted file mode 100644 index b99ea1e8be..0000000000 --- a/contrib/binutils-2.22/gas/as.c +++ /dev/null @@ -1,1310 +0,0 @@ -/* as.c - GAS main program. - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Main program for AS; a 32-bit assembler of GNU. - Understands command arguments. - Has a few routines that don't fit in other modules because they - are shared. - - bugs - - : initialisers - Since no-one else says they will support them in future: I - don't support them now. */ - -#define COMMON - -#include "as.h" -#include "subsegs.h" -#include "output-file.h" -#include "sb.h" -#include "macro.h" -#include "dwarf2dbg.h" -#include "dw2gencfi.h" -#include "bfdver.h" - -#ifdef HAVE_ITBL_CPU -#include "itbl-ops.h" -#else -#define itbl_init() -#endif - -#ifdef HAVE_SBRK -#ifdef NEED_DECLARATION_SBRK -extern void *sbrk (); -#endif -#endif - -#ifdef USING_CGEN -/* Perform any cgen specific initialisation for gas. */ -extern void gas_cgen_begin (void); -#endif - -/* We build a list of defsyms as we read the options, and then define - them after we have initialized everything. */ -struct defsym_list -{ - struct defsym_list *next; - char *name; - valueT value; -}; - - -/* True if a listing is wanted. */ -int listing; - -/* Type of debugging to generate. */ -enum debug_info_type debug_type = DEBUG_UNSPECIFIED; -int use_gnu_debug_info_extensions = 0; - -#ifndef MD_DEBUG_FORMAT_SELECTOR -#define MD_DEBUG_FORMAT_SELECTOR NULL -#endif -static enum debug_info_type (*md_debug_format_selector) (int *) = MD_DEBUG_FORMAT_SELECTOR; - -/* Maximum level of macro nesting. */ -int max_macro_nest = 100; - -/* argv[0] */ -static char * myname; - -/* The default obstack chunk size. If we set this to zero, the - obstack code will use whatever will fit in a 4096 byte block. */ -int chunksize = 0; - -/* To monitor memory allocation more effectively, make this non-zero. - Then the chunk sizes for gas and bfd will be reduced. */ -int debug_memory = 0; - -/* Enable verbose mode. */ -int verbose = 0; - -/* Keep the output file. */ -int keep_it = 0; - -segT reg_section; -segT expr_section; -segT text_section; -segT data_section; -segT bss_section; - -/* Name of listing file. */ -static char *listing_filename = NULL; - -static struct defsym_list *defsyms; - -#ifdef HAVE_ITBL_CPU -/* Keep a record of the itbl files we read in. */ -struct itbl_file_list -{ - struct itbl_file_list *next; - char *name; -}; -static struct itbl_file_list *itbl_files; -#endif - -static long start_time; - -static int flag_macro_alternate; - - -#ifdef USE_EMULATIONS -#define EMULATION_ENVIRON "AS_EMULATION" - -extern struct emulation mipsbelf, mipslelf, mipself; -extern struct emulation mipsbecoff, mipslecoff, mipsecoff; -extern struct emulation i386coff, i386elf, i386aout; -extern struct emulation crisaout, criself; - -static struct emulation *const emulations[] = { EMULATIONS }; -static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]); - -static void -select_emulation_mode (int argc, char **argv) -{ - int i; - char *p, *em = 0; - - for (i = 1; i < argc; i++) - if (!strncmp ("--em", argv[i], 4)) - break; - - if (i == argc) - goto do_default; - - p = strchr (argv[i], '='); - if (p) - p++; - else - p = argv[i + 1]; - - if (!p || !*p) - as_fatal (_("missing emulation mode name")); - em = p; - - do_default: - if (em == 0) - em = getenv (EMULATION_ENVIRON); - if (em == 0) - em = DEFAULT_EMULATION; - - if (em) - { - for (i = 0; i < n_emulations; i++) - if (!strcmp (emulations[i]->name, em)) - break; - if (i == n_emulations) - as_fatal (_("unrecognized emulation name `%s'"), em); - this_emulation = emulations[i]; - } - else - this_emulation = emulations[0]; - - this_emulation->init (); -} - -const char * -default_emul_bfd_name (void) -{ - abort (); - return NULL; -} - -void -common_emul_init (void) -{ - this_format = this_emulation->format; - - if (this_emulation->leading_underscore == 2) - this_emulation->leading_underscore = this_format->dfl_leading_underscore; - - if (this_emulation->default_endian != 2) - target_big_endian = this_emulation->default_endian; - - if (this_emulation->fake_label_name == 0) - { - if (this_emulation->leading_underscore) - this_emulation->fake_label_name = "L0\001"; - else - /* What other parameters should we test? */ - this_emulation->fake_label_name = ".L0\001"; - } -} -#endif - -void -print_version_id (void) -{ - static int printed; - - if (printed) - return; - printed = 1; - - fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s\n"), - VERSION, TARGET_ALIAS, BFD_VERSION_STRING); -} - -static void -show_usage (FILE * stream) -{ - fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname); - - fprintf (stream, _("\ -Options:\n\ - -a[sub-option...] turn on listings\n\ - Sub-options [default hls]:\n\ - c omit false conditionals\n\ - d omit debugging directives\n\ - g include general info\n\ - h include high-level source\n\ - l include assembly\n\ - m include macro expansions\n\ - n omit forms processing\n\ - s include symbols\n\ - =FILE list to FILE (must be last sub-option)\n")); - - fprintf (stream, _("\ - --alternate initially turn on alternate macro syntax\n")); -#ifdef HAVE_ZLIB_H - fprintf (stream, _("\ - --compress-debug-sections\n\ - compress DWARF debug sections using zlib\n")); - fprintf (stream, _("\ - --nocompress-debug-sections\n\ - don't compress DWARF debug sections\n")); -#endif /* HAVE_ZLIB_H */ - fprintf (stream, _("\ - -D produce assembler debugging messages\n")); - fprintf (stream, _("\ - --debug-prefix-map OLD=NEW\n\ - map OLD to NEW in debug information\n")); - fprintf (stream, _("\ - --defsym SYM=VAL define symbol SYM to given value\n")); -#ifdef USE_EMULATIONS - { - int i; - char *def_em; - - fprintf (stream, "\ - --em=["); - for (i = 0; i < n_emulations - 1; i++) - fprintf (stream, "%s | ", emulations[i]->name); - fprintf (stream, "%s]\n", emulations[i]->name); - - def_em = getenv (EMULATION_ENVIRON); - if (!def_em) - def_em = DEFAULT_EMULATION; - fprintf (stream, _("\ - emulate output (default %s)\n"), def_em); - } -#endif -#if defined OBJ_ELF || defined OBJ_MAYBE_ELF - fprintf (stream, _("\ - --execstack require executable stack for this object\n")); - fprintf (stream, _("\ - --noexecstack don't require executable stack for this object\n")); - fprintf (stream, _("\ - --size-check=[error|warning]\n\ - ELF .size directive check (default --size-check=error)\n")); -#endif - fprintf (stream, _("\ - -f skip whitespace and comment preprocessing\n")); - fprintf (stream, _("\ - -g --gen-debug generate debugging information\n")); - fprintf (stream, _("\ - --gstabs generate STABS debugging information\n")); - fprintf (stream, _("\ - --gstabs+ generate STABS debug info with GNU extensions\n")); - fprintf (stream, _("\ - --gdwarf-2 generate DWARF2 debugging information\n")); - fprintf (stream, _("\ - --hash-size= set the hash table size close to \n")); - fprintf (stream, _("\ - --help show this message and exit\n")); - fprintf (stream, _("\ - --target-help show target specific options\n")); - fprintf (stream, _("\ - -I DIR add DIR to search list for .include directives\n")); - fprintf (stream, _("\ - -J don't warn about signed overflow\n")); - fprintf (stream, _("\ - -K warn when differences altered for long displacements\n")); - fprintf (stream, _("\ - -L,--keep-locals keep local symbols (e.g. starting with `L')\n")); - fprintf (stream, _("\ - -M,--mri assemble in MRI compatibility mode\n")); - fprintf (stream, _("\ - --MD FILE write dependency information in FILE (default none)\n")); - fprintf (stream, _("\ - -nocpp ignored\n")); - fprintf (stream, _("\ - -o OBJFILE name the object-file output OBJFILE (default a.out)\n")); - fprintf (stream, _("\ - -R fold data section into text section\n")); - fprintf (stream, _("\ - --reduce-memory-overheads \n\ - prefer smaller memory use at the cost of longer\n\ - assembly times\n")); - fprintf (stream, _("\ - --statistics print various measured statistics from execution\n")); - fprintf (stream, _("\ - --strip-local-absolute strip local absolute symbols\n")); - fprintf (stream, _("\ - --traditional-format Use same format as native assembler when possible\n")); - fprintf (stream, _("\ - --version print assembler version number and exit\n")); - fprintf (stream, _("\ - -W --no-warn suppress warnings\n")); - fprintf (stream, _("\ - --warn don't suppress warnings\n")); - fprintf (stream, _("\ - --fatal-warnings treat warnings as errors\n")); -#ifdef HAVE_ITBL_CPU - fprintf (stream, _("\ - --itbl INSTTBL extend instruction set to include instructions\n\ - matching the specifications defined in file INSTTBL\n")); -#endif - fprintf (stream, _("\ - -w ignored\n")); - fprintf (stream, _("\ - -X ignored\n")); - fprintf (stream, _("\ - -Z generate object file even after errors\n")); - fprintf (stream, _("\ - --listing-lhs-width set the width in words of the output data column of\n\ - the listing\n")); - fprintf (stream, _("\ - --listing-lhs-width2 set the width in words of the continuation lines\n\ - of the output data column; ignored if smaller than\n\ - the width of the first line\n")); - fprintf (stream, _("\ - --listing-rhs-width set the max width in characters of the lines from\n\ - the source file\n")); - fprintf (stream, _("\ - --listing-cont-lines set the maximum number of continuation lines used\n\ - for the output data column of the listing\n")); - fprintf (stream, _("\ - @FILE read options from FILE\n")); - - md_show_usage (stream); - - fputc ('\n', stream); - - if (REPORT_BUGS_TO[0] && stream == stdout) - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); -} - -/* Since it is easy to do here we interpret the special arg "-" - to mean "use stdin" and we set that argv[] pointing to "". - After we have munged argv[], the only things left are source file - name(s) and ""(s) denoting stdin. These file names are used - (perhaps more than once) later. - - check for new machine-dep cmdline options in - md_parse_option definitions in config/tc-*.c. */ - -static void -parse_args (int * pargc, char *** pargv) -{ - int old_argc; - int new_argc; - char ** old_argv; - char ** new_argv; - /* Starting the short option string with '-' is for programs that - expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. */ - char *shortopts; - extern const char *md_shortopts; - static const char std_shortopts[] = - { - '-', 'J', -#ifndef WORKING_DOT_WORD - /* -K is not meaningful if .word is not being hacked. */ - 'K', -#endif - 'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'g', ':',':', 'I', ':', 'o', ':', -#ifndef VMS - /* -v takes an argument on VMS, so we don't make it a generic - option. */ - 'v', -#endif - 'w', 'X', -#ifdef HAVE_ITBL_CPU - /* New option for extending instruction set (see also --itbl below). */ - 't', ':', -#endif - '\0' - }; - struct option *longopts; - extern struct option md_longopts[]; - extern size_t md_longopts_size; - /* Codes used for the long options with no short synonyms. */ - enum option_values - { - OPTION_HELP = OPTION_STD_BASE, - OPTION_NOCPP, - OPTION_STATISTICS, - OPTION_VERSION, - OPTION_DUMPCONFIG, - OPTION_VERBOSE, - OPTION_EMULATION, - OPTION_DEBUG_PREFIX_MAP, - OPTION_DEFSYM, - OPTION_LISTING_LHS_WIDTH, - OPTION_LISTING_LHS_WIDTH2, - OPTION_LISTING_RHS_WIDTH, - OPTION_LISTING_CONT_LINES, - OPTION_DEPFILE, - OPTION_GSTABS, - OPTION_GSTABS_PLUS, - OPTION_GDWARF2, - OPTION_STRIP_LOCAL_ABSOLUTE, - OPTION_TRADITIONAL_FORMAT, - OPTION_WARN, - OPTION_TARGET_HELP, - OPTION_EXECSTACK, - OPTION_NOEXECSTACK, - OPTION_SIZE_CHECK, - OPTION_ALTERNATE, - OPTION_AL, - OPTION_HASH_TABLE_SIZE, - OPTION_REDUCE_MEMORY_OVERHEADS, - OPTION_WARN_FATAL, - OPTION_COMPRESS_DEBUG, - OPTION_NOCOMPRESS_DEBUG - /* When you add options here, check that they do - not collide with OPTION_MD_BASE. See as.h. */ - }; - - static const struct option std_longopts[] = - { - /* Note: commas are placed at the start of the line rather than - the end of the preceding line so that it is simpler to - selectively add and remove lines from this list. */ - {"alternate", no_argument, NULL, OPTION_ALTERNATE} - /* The entry for "a" is here to prevent getopt_long_only() from - considering that -a is an abbreviation for --alternate. This is - necessary because -a= is a valid switch but getopt would - normally reject it since --alternate does not take an argument. */ - ,{"a", optional_argument, NULL, 'a'} - /* Handle -al=. */ - ,{"al", optional_argument, NULL, OPTION_AL} - ,{"compress-debug-sections", no_argument, NULL, OPTION_COMPRESS_DEBUG} - ,{"nocompress-debug-sections", no_argument, NULL, OPTION_NOCOMPRESS_DEBUG} - ,{"debug-prefix-map", required_argument, NULL, OPTION_DEBUG_PREFIX_MAP} - ,{"defsym", required_argument, NULL, OPTION_DEFSYM} - ,{"dump-config", no_argument, NULL, OPTION_DUMPCONFIG} - ,{"emulation", required_argument, NULL, OPTION_EMULATION} -#if defined OBJ_ELF || defined OBJ_MAYBE_ELF - ,{"execstack", no_argument, NULL, OPTION_EXECSTACK} - ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK} - ,{"size-check", required_argument, NULL, OPTION_SIZE_CHECK} -#endif - ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL} - ,{"gdwarf-2", no_argument, NULL, OPTION_GDWARF2} - /* GCC uses --gdwarf-2 but GAS uses to use --gdwarf2, - so we keep it here for backwards compatibility. */ - ,{"gdwarf2", no_argument, NULL, OPTION_GDWARF2} - ,{"gen-debug", no_argument, NULL, 'g'} - ,{"gstabs", no_argument, NULL, OPTION_GSTABS} - ,{"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS} - ,{"hash-size", required_argument, NULL, OPTION_HASH_TABLE_SIZE} - ,{"help", no_argument, NULL, OPTION_HELP} -#ifdef HAVE_ITBL_CPU - /* New option for extending instruction set (see also -t above). - The "-t file" or "--itbl file" option extends the basic set of - valid instructions by reading "file", a text file containing a - list of instruction formats. The additional opcodes and their - formats are added to the built-in set of instructions, and - mnemonics for new registers may also be defined. */ - ,{"itbl", required_argument, NULL, 't'} -#endif - /* getopt allows abbreviations, so we do this to stop it from - treating -k as an abbreviation for --keep-locals. Some - ports use -k to enable PIC assembly. */ - ,{"keep-locals", no_argument, NULL, 'L'} - ,{"keep-locals", no_argument, NULL, 'L'} - ,{"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH} - ,{"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2} - ,{"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH} - ,{"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES} - ,{"MD", required_argument, NULL, OPTION_DEPFILE} - ,{"mri", no_argument, NULL, 'M'} - ,{"nocpp", no_argument, NULL, OPTION_NOCPP} - ,{"no-warn", no_argument, NULL, 'W'} - ,{"reduce-memory-overheads", no_argument, NULL, OPTION_REDUCE_MEMORY_OVERHEADS} - ,{"statistics", no_argument, NULL, OPTION_STATISTICS} - ,{"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE} - ,{"version", no_argument, NULL, OPTION_VERSION} - ,{"verbose", no_argument, NULL, OPTION_VERBOSE} - ,{"target-help", no_argument, NULL, OPTION_TARGET_HELP} - ,{"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT} - ,{"warn", no_argument, NULL, OPTION_WARN} - }; - - /* Construct the option lists from the standard list and the target - dependent list. Include space for an extra NULL option and - always NULL terminate. */ - shortopts = concat (std_shortopts, md_shortopts, (char *) NULL); - longopts = (struct option *) xmalloc (sizeof (std_longopts) - + md_longopts_size + sizeof (struct option)); - memcpy (longopts, std_longopts, sizeof (std_longopts)); - memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size); - memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size, - 0, sizeof (struct option)); - - /* Make a local copy of the old argv. */ - old_argc = *pargc; - old_argv = *pargv; - - /* Initialize a new argv that contains no options. */ - new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1)); - new_argv[0] = old_argv[0]; - new_argc = 1; - new_argv[new_argc] = NULL; - - while (1) - { - /* getopt_long_only is like getopt_long, but '-' as well as '--' can - indicate a long option. */ - int longind; - int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts, - &longind); - - if (optc == -1) - break; - - switch (optc) - { - default: - /* md_parse_option should return 1 if it recognizes optc, - 0 if not. */ - if (md_parse_option (optc, optarg) != 0) - break; - /* `-v' isn't included in the general short_opts list, so check for - it explicitly here before deciding we've gotten a bad argument. */ - if (optc == 'v') - { -#ifdef VMS - /* Telling getopt to treat -v's value as optional can result - in it picking up a following filename argument here. The - VMS code in md_parse_option can return 0 in that case, - but it has no way of pushing the filename argument back. */ - if (optarg && *optarg) - new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL; - else -#else - case 'v': -#endif - case OPTION_VERBOSE: - print_version_id (); - verbose = 1; - break; - } - else - as_bad (_("unrecognized option -%c%s"), optc, optarg ? optarg : ""); - /* Fall through. */ - - case '?': - exit (EXIT_FAILURE); - - case 1: /* File name. */ - if (!strcmp (optarg, "-")) - optarg = ""; - new_argv[new_argc++] = optarg; - new_argv[new_argc] = NULL; - break; - - case OPTION_TARGET_HELP: - md_show_usage (stdout); - exit (EXIT_SUCCESS); - - case OPTION_HELP: - show_usage (stdout); - exit (EXIT_SUCCESS); - - case OPTION_NOCPP: - break; - - case OPTION_STATISTICS: - flag_print_statistics = 1; - break; - - case OPTION_STRIP_LOCAL_ABSOLUTE: - flag_strip_local_absolute = 1; - break; - - case OPTION_TRADITIONAL_FORMAT: - flag_traditional_format = 1; - break; - - case OPTION_VERSION: - /* This output is intended to follow the GNU standards document. */ - printf (_("GNU assembler %s\n"), BFD_VERSION_STRING); - printf (_("Copyright 2011 Free Software Foundation, Inc.\n")); - printf (_("\ -This program is free software; you may redistribute it under the terms of\n\ -the GNU General Public License version 3 or later.\n\ -This program has absolutely no warranty.\n")); - printf (_("This assembler was configured for a target of `%s'.\n"), - TARGET_ALIAS); - exit (EXIT_SUCCESS); - - case OPTION_EMULATION: -#ifdef USE_EMULATIONS - if (strcmp (optarg, this_emulation->name)) - as_fatal (_("multiple emulation names specified")); -#else - as_fatal (_("emulations not handled in this configuration")); -#endif - break; - - case OPTION_DUMPCONFIG: - fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS); - fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL); - fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU); -#ifdef TARGET_OBJ_FORMAT - fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT); -#endif -#ifdef TARGET_FORMAT - fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT); -#endif - exit (EXIT_SUCCESS); - - case OPTION_COMPRESS_DEBUG: -#ifdef HAVE_ZLIB_H - flag_compress_debug = 1; -#else - as_warn (_("cannot compress debug sections (zlib not installed)")); -#endif /* HAVE_ZLIB_H */ - break; - - case OPTION_NOCOMPRESS_DEBUG: - flag_compress_debug = 0; - break; - - case OPTION_DEBUG_PREFIX_MAP: - add_debug_prefix_map (optarg); - break; - - case OPTION_DEFSYM: - { - char *s; - valueT i; - struct defsym_list *n; - - for (s = optarg; *s != '\0' && *s != '='; s++) - ; - if (*s == '\0') - as_fatal (_("bad defsym; format is --defsym name=value")); - *s++ = '\0'; - i = bfd_scan_vma (s, (const char **) NULL, 0); - n = (struct defsym_list *) xmalloc (sizeof *n); - n->next = defsyms; - n->name = optarg; - n->value = i; - defsyms = n; - } - break; - -#ifdef HAVE_ITBL_CPU - case 't': - { - /* optarg is the name of the file containing the instruction - formats, opcodes, register names, etc. */ - struct itbl_file_list *n; - - if (optarg == NULL) - { - as_warn (_("no file name following -t option")); - break; - } - - n = xmalloc (sizeof * n); - n->next = itbl_files; - n->name = optarg; - itbl_files = n; - - /* Parse the file and add the new instructions to our internal - table. If multiple instruction tables are specified, the - information from this table gets appended onto the existing - internal table. */ - itbl_files->name = xstrdup (optarg); - if (itbl_parse (itbl_files->name) != 0) - as_fatal (_("failed to read instruction table %s\n"), - itbl_files->name); - } - break; -#endif - - case OPTION_DEPFILE: - start_dependencies (optarg); - break; - - case 'g': - /* Some backends, eg Alpha and Mips, use the -g switch for their - own purposes. So we check here for an explicit -g and allow - the backend to decide if it wants to process it. */ - if ( old_argv[optind - 1][1] == 'g' - && md_parse_option (optc, optarg)) - continue; - - if (md_debug_format_selector) - debug_type = md_debug_format_selector (& use_gnu_debug_info_extensions); - else if (IS_ELF) - debug_type = DEBUG_DWARF2; - else - debug_type = DEBUG_STABS; - break; - - case OPTION_GSTABS_PLUS: - use_gnu_debug_info_extensions = 1; - /* Fall through. */ - case OPTION_GSTABS: - debug_type = DEBUG_STABS; - break; - - case OPTION_GDWARF2: - debug_type = DEBUG_DWARF2; - break; - - case 'J': - flag_signed_overflow_ok = 1; - break; - -#ifndef WORKING_DOT_WORD - case 'K': - flag_warn_displacement = 1; - break; -#endif - case 'L': - flag_keep_locals = 1; - break; - - case OPTION_LISTING_LHS_WIDTH: - listing_lhs_width = atoi (optarg); - if (listing_lhs_width_second < listing_lhs_width) - listing_lhs_width_second = listing_lhs_width; - break; - case OPTION_LISTING_LHS_WIDTH2: - { - int tmp = atoi (optarg); - - if (tmp > listing_lhs_width) - listing_lhs_width_second = tmp; - } - break; - case OPTION_LISTING_RHS_WIDTH: - listing_rhs_width = atoi (optarg); - break; - case OPTION_LISTING_CONT_LINES: - listing_lhs_cont_lines = atoi (optarg); - break; - - case 'M': - flag_mri = 1; -#ifdef TC_M68K - flag_m68k_mri = 1; -#endif - break; - - case 'R': - flag_readonly_data_in_text = 1; - break; - - case 'W': - flag_no_warnings = 1; - break; - - case OPTION_WARN: - flag_no_warnings = 0; - flag_fatal_warnings = 0; - break; - - case OPTION_WARN_FATAL: - flag_no_warnings = 0; - flag_fatal_warnings = 1; - break; - -#if defined OBJ_ELF || defined OBJ_MAYBE_ELF - case OPTION_EXECSTACK: - flag_execstack = 1; - flag_noexecstack = 0; - break; - - case OPTION_NOEXECSTACK: - flag_noexecstack = 1; - flag_execstack = 0; - break; - - case OPTION_SIZE_CHECK: - if (strcasecmp (optarg, "error") == 0) - flag_size_check = size_check_error; - else if (strcasecmp (optarg, "warning") == 0) - flag_size_check = size_check_warning; - else - as_fatal (_("Invalid --size-check= option: `%s'"), optarg); - break; -#endif - case 'Z': - flag_always_generate_output = 1; - break; - - case OPTION_AL: - listing |= LISTING_LISTING; - if (optarg) - listing_filename = xstrdup (optarg); - break; - - case OPTION_ALTERNATE: - optarg = old_argv [optind - 1]; - while (* optarg == '-') - optarg ++; - - if (strcmp (optarg, "alternate") == 0) - { - flag_macro_alternate = 1; - break; - } - optarg ++; - /* Fall through. */ - - case 'a': - if (optarg) - { - if (optarg != old_argv[optind] && optarg[-1] == '=') - --optarg; - - if (md_parse_option (optc, optarg) != 0) - break; - - while (*optarg) - { - switch (*optarg) - { - case 'c': - listing |= LISTING_NOCOND; - break; - case 'd': - listing |= LISTING_NODEBUG; - break; - case 'g': - listing |= LISTING_GENERAL; - break; - case 'h': - listing |= LISTING_HLL; - break; - case 'l': - listing |= LISTING_LISTING; - break; - case 'm': - listing |= LISTING_MACEXP; - break; - case 'n': - listing |= LISTING_NOFORM; - break; - case 's': - listing |= LISTING_SYMBOLS; - break; - case '=': - listing_filename = xstrdup (optarg + 1); - optarg += strlen (listing_filename); - break; - default: - as_fatal (_("invalid listing option `%c'"), *optarg); - break; - } - optarg++; - } - } - if (!listing) - listing = LISTING_DEFAULT; - break; - - case 'D': - /* DEBUG is implemented: it debugs different - things from other people's assemblers. */ - flag_debug = 1; - break; - - case 'f': - flag_no_comments = 1; - break; - - case 'I': - { /* Include file directory. */ - char *temp = xstrdup (optarg); - - add_include_dir (temp); - break; - } - - case 'o': - out_file_name = xstrdup (optarg); - break; - - case 'w': - break; - - case 'X': - /* -X means treat warnings as errors. */ - break; - - case OPTION_REDUCE_MEMORY_OVERHEADS: - /* The only change we make at the moment is to reduce - the size of the hash tables that we use. */ - set_gas_hash_table_size (4051); - break; - - case OPTION_HASH_TABLE_SIZE: - { - unsigned long new_size; - - new_size = strtoul (optarg, NULL, 0); - if (new_size) - set_gas_hash_table_size (new_size); - else - as_fatal (_("--hash-size needs a numeric argument")); - break; - } - } - } - - free (shortopts); - free (longopts); - - *pargc = new_argc; - *pargv = new_argv; - -#ifdef md_after_parse_args - md_after_parse_args (); -#endif -} - -static void -dump_statistics (void) -{ -#ifdef HAVE_SBRK - char *lim = (char *) sbrk (0); -#endif - long run_time = get_run_time () - start_time; - - fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"), - myname, run_time / 1000000, run_time % 1000000); -#ifdef HAVE_SBRK - fprintf (stderr, _("%s: data size %ld\n"), - myname, (long) (lim - (char *) &environ)); -#endif - - subsegs_print_statistics (stderr); - write_print_statistics (stderr); - symbol_print_statistics (stderr); - read_print_statistics (stderr); - -#ifdef tc_print_statistics - tc_print_statistics (stderr); -#endif - -#ifdef obj_print_statistics - obj_print_statistics (stderr); -#endif -} - -static void -close_output_file (void) -{ - output_file_close (out_file_name); - if (!keep_it) - unlink_if_ordinary (out_file_name); -} - -/* The interface between the macro code and gas expression handling. */ - -static int -macro_expr (const char *emsg, int idx, sb *in, int *val) -{ - char *hold; - expressionS ex; - - sb_terminate (in); - - hold = input_line_pointer; - input_line_pointer = in->ptr + idx; - expression_and_evaluate (&ex); - idx = input_line_pointer - in->ptr; - input_line_pointer = hold; - - if (ex.X_op != O_constant) - as_bad ("%s", emsg); - - *val = (int) ex.X_add_number; - - return idx; -} - -/* Here to attempt 1 pass over each input file. - We scan argv[*] looking for filenames or exactly "" which is - shorthand for stdin. Any argv that is NULL is not a file-name. - We set need_pass_2 TRUE if, after this, we still have unresolved - expressions of the form (unknown value)+-(unknown value). - - Note the un*x semantics: there is only 1 logical input file, but it - may be a catenation of many 'physical' input files. */ - -static void -perform_an_assembly_pass (int argc, char ** argv) -{ - int saw_a_file = 0; - flagword applicable; - - need_pass_2 = 0; - - /* Create the standard sections, and those the assembler uses - internally. */ - text_section = subseg_new (TEXT_SECTION_NAME, 0); - data_section = subseg_new (DATA_SECTION_NAME, 0); - bss_section = subseg_new (BSS_SECTION_NAME, 0); - /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed - to have relocs, otherwise we don't find out in time. */ - applicable = bfd_applicable_section_flags (stdoutput); - bfd_set_section_flags (stdoutput, text_section, - applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC - | SEC_CODE | SEC_READONLY)); - bfd_set_section_flags (stdoutput, data_section, - applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC - | SEC_DATA)); - bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC); - seg_info (bss_section)->bss = 1; - subseg_new (BFD_ABS_SECTION_NAME, 0); - subseg_new (BFD_UND_SECTION_NAME, 0); - reg_section = subseg_new ("*GAS `reg' section*", 0); - expr_section = subseg_new ("*GAS `expr' section*", 0); - - subseg_set (text_section, 0); - - /* This may add symbol table entries, which requires having an open BFD, - and sections already created. */ - md_begin (); - -#ifdef USING_CGEN - gas_cgen_begin (); -#endif -#ifdef obj_begin - obj_begin (); -#endif - - /* Skip argv[0]. */ - argv++; - argc--; - - while (argc--) - { - if (*argv) - { /* Is it a file-name argument? */ - PROGRESS (1); - saw_a_file++; - /* argv->"" if stdin desired, else->filename. */ - read_a_source_file (*argv); - } - argv++; /* Completed that argv. */ - } - if (!saw_a_file) - read_a_source_file (""); -} - -#ifdef OBJ_ELF -static void -create_obj_attrs_section (void) -{ - segT s; - char *p; - offsetT size; - const char *name; - - size = bfd_elf_obj_attr_size (stdoutput); - if (size) - { - name = get_elf_backend_data (stdoutput)->obj_attrs_section; - if (!name) - name = ".gnu.attributes"; - s = subseg_new (name, 0); - elf_section_type (s) - = get_elf_backend_data (stdoutput)->obj_attrs_section_type; - bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA); - frag_now_fix (); - p = frag_more (size); - bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size); - } -} -#endif - - -int -main (int argc, char ** argv) -{ - char ** argv_orig = argv; - - int macro_strip_at; - - start_time = get_run_time (); - -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) - setlocale (LC_MESSAGES, ""); -#endif -#if defined (HAVE_SETLOCALE) - setlocale (LC_CTYPE, ""); -#endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - if (debug_memory) - chunksize = 64; - -#ifdef HOST_SPECIAL_INIT - HOST_SPECIAL_INIT (argc, argv); -#endif - - myname = argv[0]; - xmalloc_set_program_name (myname); - - expandargv (&argc, &argv); - - START_PROGRESS (myname, 0); - -#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME -#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out" -#endif - - out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME; - - hex_init (); - bfd_init (); - bfd_set_error_program_name (myname); - -#ifdef USE_EMULATIONS - select_emulation_mode (argc, argv); -#endif - - PROGRESS (1); - /* Call parse_args before any of the init/begin functions - so that switches like --hash-size can be honored. */ - parse_args (&argc, &argv); - symbol_begin (); - frag_init (); - subsegs_begin (); - read_begin (); - input_scrub_begin (); - expr_begin (); - - /* It has to be called after dump_statistics (). */ - xatexit (close_output_file); - - if (flag_print_statistics) - xatexit (dump_statistics); - - macro_strip_at = 0; -#ifdef TC_I960 - macro_strip_at = flag_mri; -#endif - - macro_init (flag_macro_alternate, flag_mri, macro_strip_at, macro_expr); - - PROGRESS (1); - - output_file_create (out_file_name); - gas_assert (stdoutput != 0); - - dot_symbol_init (); - -#ifdef tc_init_after_args - tc_init_after_args (); -#endif - - itbl_init (); - - dwarf2_init (); - - local_symbol_make (".gasversion.", absolute_section, - BFD_VERSION / 10000UL, &predefined_address_frag); - - /* Now that we have fully initialized, and have created the output - file, define any symbols requested by --defsym command line - arguments. */ - while (defsyms != NULL) - { - symbolS *sym; - struct defsym_list *next; - - sym = symbol_new (defsyms->name, absolute_section, defsyms->value, - &zero_address_frag); - /* Make symbols defined on the command line volatile, so that they - can be redefined inside a source file. This makes this assembler's - behaviour compatible with earlier versions, but it may not be - completely intuitive. */ - S_SET_VOLATILE (sym); - symbol_table_insert (sym); - next = defsyms->next; - free (defsyms); - defsyms = next; - } - - PROGRESS (1); - - /* Assemble it. */ - perform_an_assembly_pass (argc, argv); - - cond_finish_check (-1); - -#ifdef md_end - md_end (); -#endif - -#ifdef OBJ_ELF - if (IS_ELF) - create_obj_attrs_section (); -#endif - -#if defined OBJ_ELF || defined OBJ_MAYBE_ELF - if ((flag_execstack || flag_noexecstack) - && OUTPUT_FLAVOR == bfd_target_elf_flavour) - { - segT gnustack; - - gnustack = subseg_new (".note.GNU-stack", 0); - bfd_set_section_flags (stdoutput, gnustack, - SEC_READONLY | (flag_execstack ? SEC_CODE : 0)); - - } -#endif - - /* If we've been collecting dwarf2 .debug_line info, either for - assembly debugging or on behalf of the compiler, emit it now. */ - dwarf2_finish (); - - /* If we constructed dwarf2 .eh_frame info, either via .cfi - directives from the user or by the backend, emit it now. */ - cfi_finish (); - - if (seen_at_least_1_file () - && (flag_always_generate_output || had_errors () == 0)) - keep_it = 1; - else - keep_it = 0; - - /* This used to be done at the start of write_object_file in - write.c, but that caused problems when doing listings when - keep_it was zero. This could probably be moved above md_end, but - I didn't want to risk the change. */ - subsegs_finish (); - - if (keep_it) - write_object_file (); - - fflush (stderr); - -#ifndef NO_LISTING - listing_print (listing_filename, argv_orig); -#endif - - if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0) - as_bad (_("%d warnings, treating warnings as errors"), had_warnings ()); - - if (had_errors () > 0 && ! flag_always_generate_output) - keep_it = 0; - - input_scrub_end (); - - END_PROGRESS (myname); - - /* Use xexit instead of return, because under VMS environments they - may not place the same interpretation on the value given. */ - if (had_errors () > 0) - xexit (EXIT_FAILURE); - - /* Only generate dependency file if assembler was successful. */ - print_dependencies (); - - xexit (EXIT_SUCCESS); -} diff --git a/contrib/binutils-2.22/gas/as.h b/contrib/binutils-2.22/gas/as.h deleted file mode 100644 index 5408e1a96e..0000000000 --- a/contrib/binutils-2.22/gas/as.h +++ /dev/null @@ -1,628 +0,0 @@ -/* as.h - global header file - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef GAS -#define GAS 1 -/* I think this stuff is largely out of date. xoxorich. - - CAPITALISED names are #defined. - "lowercaseH" is #defined if "lowercase.h" has been #include-d. - "lowercaseT" is a typedef of "lowercase" objects. - "lowercaseP" is type "pointer to object of type 'lowercase'". - "lowercaseS" is typedef struct ... lowercaseS. - - #define DEBUG to enable all the "know" assertion tests. - #define SUSPECT when debugging hash code. - #define COMMON as "extern" for all modules except one, where you #define - COMMON as "". - If TEST is #defined, then we are testing a module: #define COMMON as "". */ - -#include "alloca-conf.h" - -/* Now, tend to the rest of the configuration. */ - -/* System include files first... */ -#include -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -/* for size_t, pid_t */ -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include - -#include "getopt.h" -/* The first getopt value for machine-independent long options. - 150 isn't special; it's just an arbitrary non-ASCII char value. */ -#define OPTION_STD_BASE 150 -/* The first getopt value for machine-dependent long options. - 190 gives the standard options room to grow. */ -#define OPTION_MD_BASE 190 - -#ifdef DEBUG -#undef NDEBUG -#endif -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) -#define __PRETTY_FUNCTION__ ((char *) NULL) -#endif -#define gas_assert(P) \ - ((void) ((P) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))) -#undef abort -#define abort() as_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) - -/* Now GNU header files... */ -#include "ansidecl.h" -#include "bfd.h" -#include "libiberty.h" - -/* Define the standard progress macros. */ -#include "progress.h" - -/* This doesn't get taken care of anywhere. */ -#ifndef __MWERKS__ /* Metrowerks C chokes on the "defined (inline)" */ -#if !defined (__GNUC__) && !defined (inline) -#define inline -#endif -#endif /* !__MWERKS__ */ - -/* Other stuff from config.h. */ -#ifdef NEED_DECLARATION_ENVIRON -extern char **environ; -#endif -#ifdef NEED_DECLARATION_ERRNO -extern int errno; -#endif -#ifdef NEED_DECLARATION_FFS -extern int ffs (int); -#endif -#ifdef NEED_DECLARATION_FREE -extern void free (); -#endif -#ifdef NEED_DECLARATION_MALLOC -extern void *malloc (); -extern void *realloc (); -#endif -#ifdef NEED_DECLARATION_STRSTR -extern char *strstr (); -#endif - -#if !HAVE_DECL_MEMPCPY -void *mempcpy(void *, const void *, size_t); -#endif - -#if !HAVE_DECL_VSNPRINTF -extern int vsnprintf(char *, size_t, const char *, va_list); -#endif - -/* This is needed for VMS. */ -#if ! defined (HAVE_UNLINK) && defined (HAVE_REMOVE) -#define unlink remove -#endif - -/* Hack to make "gcc -Wall" not complain about obstack macros. */ -#if !defined (memcpy) && !defined (bcopy) -#define bcopy(src,dest,size) memcpy (dest, src, size) -#endif - -/* Make Saber happier on obstack.h. */ -#ifdef SABER -#undef __PTR_TO_INT -#define __PTR_TO_INT(P) ((int) (P)) -#undef __INT_TO_PTR -#define __INT_TO_PTR(P) ((char *) (P)) -#endif - -#ifndef __LINE__ -#define __LINE__ "unknown" -#endif /* __LINE__ */ - -#ifndef __FILE__ -#define __FILE__ "unknown" -#endif /* __FILE__ */ - -#ifndef FOPEN_WB -#ifdef USE_BINARY_FOPEN -#include "fopen-bin.h" -#else -#include "fopen-same.h" -#endif -#endif - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free xfree - -#define xfree free - -#include "asintl.h" - -#define BAD_CASE(val) \ - { \ - as_fatal (_("Case value %ld unexpected at line %d of file \"%s\"\n"), \ - (long) val, __LINE__, __FILE__); \ - } - -#include "flonum.h" - -/* These are assembler-wide concepts */ - -extern bfd *stdoutput; -typedef bfd_vma addressT; -typedef bfd_signed_vma offsetT; - -/* Type of symbol value, etc. For use in prototypes. */ -typedef addressT valueT; - -#ifndef COMMON -#ifdef TEST -#define COMMON /* Declare our COMMONs storage here. */ -#else -#define COMMON extern /* Our commons live elsewhere. */ -#endif -#endif -/* COMMON now defined */ - -#ifndef ENABLE_CHECKING -#define ENABLE_CHECKING 0 -#endif - -#if ENABLE_CHECKING || defined (DEBUG) -#ifndef know -#define know(p) gas_assert(p) /* Verify our assumptions! */ -#endif /* not yet defined */ -#else -#define know(p) do {} while (0) /* know() checks are no-op.ed */ -#endif - -/* input_scrub.c */ - -/* Supplies sanitised buffers to read.c. - Also understands printing line-number part of error messages. */ - -/* subsegs.c Sub-segments. Also, segment(=expression type)s.*/ - -typedef asection *segT; -#define SEG_NORMAL(SEG) ( (SEG) != absolute_section \ - && (SEG) != undefined_section \ - && (SEG) != reg_section \ - && (SEG) != expr_section) -typedef int subsegT; - -/* What subseg we are accessing now? */ -COMMON subsegT now_subseg; - -/* Segment our instructions emit to. */ -COMMON segT now_seg; - -#define segment_name(SEG) bfd_get_section_name (stdoutput, SEG) - -extern segT reg_section, expr_section; -/* Shouldn't these be eliminated someday? */ -extern segT text_section, data_section, bss_section; -#define absolute_section bfd_abs_section_ptr -#define undefined_section bfd_und_section_ptr - -enum _relax_state -{ - /* Dummy frag used by listing code. */ - rs_dummy = 0, - - /* Variable chars to be repeated fr_offset times. - Fr_symbol unused. Used with fr_offset == 0 for a - constant length frag. */ - rs_fill, - - /* Align. The fr_offset field holds the power of 2 to which to - align. The fr_var field holds the number of characters in the - fill pattern. The fr_subtype field holds the maximum number of - bytes to skip when aligning, or 0 if there is no maximum. */ - rs_align, - - /* Align code. The fr_offset field holds the power of 2 to which - to align. This type is only generated by machine specific - code, which is normally responsible for handling the fill - pattern. The fr_subtype field holds the maximum number of - bytes to skip when aligning, or 0 if there is no maximum. */ - rs_align_code, - - /* Test for alignment. Like rs_align, but used by several targets - to warn if data is not properly aligned. */ - rs_align_test, - - /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill - character. */ - rs_org, - -#ifndef WORKING_DOT_WORD - /* JF: gunpoint */ - rs_broken_word, -#endif - - /* Machine specific relaxable (or similarly alterable) instruction. */ - rs_machine_dependent, - - /* .space directive with expression operand that needs to be computed - later. Similar to rs_org, but different. - fr_symbol: operand - 1 variable char: fill character */ - rs_space, - - /* A DWARF leb128 value; only ELF uses this. The subtype is 0 for - unsigned, 1 for signed. */ - rs_leb128, - - /* Exception frame information which we may be able to optimize. */ - rs_cfa, - - /* Cross-fragment dwarf2 line number optimization. */ - rs_dwarf2dbg -}; - -typedef enum _relax_state relax_stateT; - -/* This type is used in prototypes, so it can't be a type that will be - widened for argument passing. */ -typedef unsigned int relax_substateT; - -/* Enough bits for address, but still an integer type. - Could be a problem, cross-assembling for 64-bit machines. */ -typedef addressT relax_addressT; - -struct relax_type -{ - /* Forward reach. Signed number. > 0. */ - offsetT rlx_forward; - /* Backward reach. Signed number. < 0. */ - offsetT rlx_backward; - - /* Bytes length of this address. */ - unsigned char rlx_length; - - /* Next longer relax-state. 0 means there is no 'next' relax-state. */ - relax_substateT rlx_more; -}; - -typedef struct relax_type relax_typeS; - -/* main program "as.c" (command arguments etc). */ - -COMMON unsigned char flag_no_comments; /* -f */ -COMMON unsigned char flag_debug; /* -D */ -COMMON unsigned char flag_signed_overflow_ok; /* -J */ -#ifndef WORKING_DOT_WORD -COMMON unsigned char flag_warn_displacement; /* -K */ -#endif - -/* True if local symbols should be retained. */ -COMMON int flag_keep_locals; /* -L */ - -/* True if we are assembling in MRI mode. */ -COMMON int flag_mri; - -/* Should the data section be made read-only and appended to the text - section? */ -COMMON unsigned char flag_readonly_data_in_text; /* -R */ - -/* True if warnings should be inhibited. */ -COMMON int flag_no_warnings; /* -W */ - -/* True if warnings count as errors. */ -COMMON int flag_fatal_warnings; /* --fatal-warnings */ - -/* True if we should attempt to generate output even if non-fatal errors - are detected. */ -COMMON unsigned char flag_always_generate_output; /* -Z */ - -/* This is true if the assembler should output time and space usage. */ -COMMON unsigned char flag_print_statistics; - -/* True if local absolute symbols are to be stripped. */ -COMMON int flag_strip_local_absolute; - -/* True if we should generate a traditional format object file. */ -COMMON int flag_traditional_format; - -/* TRUE if debug sections should be compressed. */ -COMMON int flag_compress_debug; - -/* TRUE if .note.GNU-stack section with SEC_CODE should be created */ -COMMON int flag_execstack; - -/* TRUE if .note.GNU-stack section with SEC_CODE should be created */ -COMMON int flag_noexecstack; - -/* name of emitted object file */ -COMMON char *out_file_name; - -/* name of file defining extensions to the basic instruction set */ -COMMON char *insttbl_file_name; - -/* TRUE if we need a second pass. */ -COMMON int need_pass_2; - -/* TRUE if we should do no relaxing, and - leave lots of padding. */ -COMMON int linkrelax; - -/* TRUE if we should produce a listing. */ -extern int listing; - -/* Type of debugging information we should generate. We currently support - stabs, ECOFF, and DWARF2. - - NOTE! This means debug information about the assembly source code itself - and _not_ about possible debug information from a high-level language. - This is especially relevant to DWARF2, since the compiler may emit line - number directives that the assembler resolves. */ - -enum debug_info_type -{ - DEBUG_UNSPECIFIED, - DEBUG_NONE, - DEBUG_STABS, - DEBUG_ECOFF, - DEBUG_DWARF, - DEBUG_DWARF2 -}; - -extern enum debug_info_type debug_type; -extern int use_gnu_debug_info_extensions; - -/* Maximum level of macro nesting. */ -extern int max_macro_nest; - -/* Verbosity level. */ -extern int verbose; - -/* Obstack chunk size. Keep large for efficient space use, make small to - increase malloc calls for monitoring memory allocation. */ -extern int chunksize; - -struct _pseudo_type -{ - /* assembler mnemonic, lower case, no '.' */ - const char *poc_name; - /* Do the work */ - void (*poc_handler) (int); - /* Value to pass to handler */ - int poc_val; -}; - -typedef struct _pseudo_type pseudo_typeS; - -#if (__GNUC__ >= 2) && !defined(VMS) -/* for use with -Wformat */ - -#if __GNUC__ == 2 && __GNUC_MINOR__ < 6 -/* Support for double underscores in attribute names was added in gcc - 2.6, so avoid them if we are using an earlier version. */ -#define __printf__ printf -#define __format__ format -#endif - -#define PRINTF_LIKE(FCN) \ - void FCN (const char *format, ...) \ - __attribute__ ((__format__ (__printf__, 1, 2))) -#define PRINTF_WHERE_LIKE(FCN) \ - void FCN (char *file, unsigned int line, const char *format, ...) \ - __attribute__ ((__format__ (__printf__, 3, 4))) - -#else /* __GNUC__ < 2 || defined(VMS) */ - -#define PRINTF_LIKE(FCN) void FCN (const char *format, ...) -#define PRINTF_WHERE_LIKE(FCN) void FCN (char *file, \ - unsigned int line, \ - const char *format, ...) - -#endif /* __GNUC__ < 2 || defined(VMS) */ - -PRINTF_LIKE (as_bad); -PRINTF_LIKE (as_fatal) ATTRIBUTE_NORETURN; -PRINTF_LIKE (as_tsktsk); -PRINTF_LIKE (as_warn); -PRINTF_WHERE_LIKE (as_bad_where); -PRINTF_WHERE_LIKE (as_warn_where); - -void as_assert (const char *, int, const char *); -void as_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; -void sprint_value (char *, addressT); -int had_errors (void); -int had_warnings (void); -void as_warn_value_out_of_range (char *, offsetT, offsetT, offsetT, char *, unsigned); -void as_bad_value_out_of_range (char *, offsetT, offsetT, offsetT, char *, unsigned); -void print_version_id (void); -char * app_push (void); -char * atof_ieee (char *, int, LITTLENUM_TYPE *); -char * ieee_md_atof (int, char *, int *, bfd_boolean); -char * vax_md_atof (int, char *, int *); -char * input_scrub_include_file (char *, char *); -void input_scrub_insert_line (const char *); -void input_scrub_insert_file (char *); -char * input_scrub_new_file (char *); -char * input_scrub_next_buffer (char **bufp); -int do_scrub_chars (int (*get) (char *, int), char *, int); -int gen_to_words (LITTLENUM_TYPE *, int, long); -int had_err (void); -int ignore_input (void); -void cond_finish_check (int); -void cond_exit_macro (int); -int seen_at_least_1_file (void); -void app_pop (char *); -void as_where (char **, unsigned int *); -void bump_line_counters (void); -void do_scrub_begin (int); -void input_scrub_begin (void); -void input_scrub_close (void); -void input_scrub_end (void); -int new_logical_line (char *, int); -int new_logical_line_flags (char *, int, int); -void subsegs_begin (void); -void subseg_change (segT, int); -segT subseg_new (const char *, subsegT); -segT subseg_force_new (const char *, subsegT); -void subseg_set (segT, subsegT); -int subseg_text_p (segT); -int seg_not_empty_p (segT); -void start_dependencies (char *); -void register_dependency (char *); -void print_dependencies (void); -segT subseg_get (const char *, int); - -const char *remap_debug_filename (const char *); -void add_debug_prefix_map (const char *); - -struct expressionS; -struct fix; -typedef struct symbol symbolS; -typedef struct frag fragS; - -/* literal.c */ -valueT add_to_literal_pool (symbolS *, valueT, segT, int); - -int check_eh_frame (struct expressionS *, unsigned int *); -int eh_frame_estimate_size_before_relax (fragS *); -int eh_frame_relax_frag (fragS *); -void eh_frame_convert_frag (fragS *); -int generic_force_reloc (struct fix *); - -#include "expr.h" /* Before targ-*.h */ - -/* This one starts the chain of target dependant headers. */ -#include "targ-env.h" - -#ifdef OBJ_MAYBE_ELF -#define IS_ELF (OUTPUT_FLAVOR == bfd_target_elf_flavour) -#else -#ifdef OBJ_ELF -#define IS_ELF 1 -#else -#define IS_ELF 0 -#endif -#endif - -#include "write.h" -#include "frags.h" -#include "hash.h" -#include "read.h" -#include "symbols.h" - -#include "tc.h" -#include "obj.h" - -#ifdef USE_EMULATIONS -#include "emul.h" -#endif -#include "listing.h" - -#ifdef H_TICK_HEX -extern int enable_h_tick_hex; -#endif - -#ifdef TC_M68K -/* True if we are assembling in m68k MRI mode. */ -COMMON int flag_m68k_mri; -#define DOLLAR_AMBIGU flag_m68k_mri -#else -#define flag_m68k_mri 0 -#endif - -#ifdef WARN_COMMENTS -COMMON int warn_comment; -COMMON unsigned int found_comment; -COMMON char * found_comment_file; -#endif - -#if defined OBJ_ELF || defined OBJ_MAYBE_ELF -/* If .size directive failure should be error or warning. */ -COMMON enum - { - size_check_error = 0, - size_check_warning - } -flag_size_check; -#endif - -#ifndef DOLLAR_AMBIGU -#define DOLLAR_AMBIGU 0 -#endif - -#ifndef NUMBERS_WITH_SUFFIX -#define NUMBERS_WITH_SUFFIX 0 -#endif - -#ifndef LOCAL_LABELS_DOLLAR -#define LOCAL_LABELS_DOLLAR 0 -#endif - -#ifndef LOCAL_LABELS_FB -#define LOCAL_LABELS_FB 0 -#endif - -#ifndef LABELS_WITHOUT_COLONS -#define LABELS_WITHOUT_COLONS 0 -#endif - -#ifndef NO_PSEUDO_DOT -#define NO_PSEUDO_DOT 0 -#endif - -#ifndef TEXT_SECTION_NAME -#define TEXT_SECTION_NAME ".text" -#define DATA_SECTION_NAME ".data" -#define BSS_SECTION_NAME ".bss" -#endif - -#ifndef OCTETS_PER_BYTE_POWER -#define OCTETS_PER_BYTE_POWER 0 -#endif -#ifndef OCTETS_PER_BYTE -#define OCTETS_PER_BYTE (1< - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifdef HAVE_LOCALE_H -# ifndef ENABLE_NLS - /* The Solaris version of locale.h always includes libintl.h. If we have - been configured with --disable-nls then ENABLE_NLS will not be defined - and the dummy definitions of bindtextdomain (et al) below will conflict - with the defintions in libintl.h. So we define these values to prevent - the bogus inclusion of libintl.h. */ -# define _LIBINTL_H -# define _LIBGETTEXT_H -# endif -# include -#endif - -#ifdef ENABLE_NLS -# include -# define _(String) gettext (String) -# ifdef gettext_noop -# define N_(String) gettext_noop (String) -# else -# define N_(String) (String) -# endif -#else -# define gettext(Msgid) (Msgid) -# define dgettext(Domainname, Msgid) (Msgid) -# define dcgettext(Domainname, Msgid, Category) (Msgid) -# define textdomain(Domainname) while (0) /* nothing */ -# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ -# define _(String) (String) -# define N_(String) (String) -#endif diff --git a/contrib/binutils-2.22/gas/atof-generic.c b/contrib/binutils-2.22/gas/atof-generic.c deleted file mode 100644 index 40a9ff0492..0000000000 --- a/contrib/binutils-2.22/gas/atof-generic.c +++ /dev/null @@ -1,614 +0,0 @@ -/* atof_generic.c - turn a string of digits into a Flonum - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, - 2001, 2003, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "as.h" -#include "safe-ctype.h" - -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (1) -#endif - -#ifdef TRACE -static void flonum_print (const FLONUM_TYPE *); -#endif - -#define ASSUME_DECIMAL_MARK_IS_DOT - -/***********************************************************************\ - * * - * Given a string of decimal digits , with optional decimal * - * mark and optional decimal exponent (place value) of the * - * lowest_order decimal digit: produce a floating point * - * number. The number is 'generic' floating point: our * - * caller will encode it for a specific machine architecture. * - * * - * Assumptions * - * uses base (radix) 2 * - * this machine uses 2's complement binary integers * - * target flonums use " " " " * - * target flonums exponents fit in a long * - * * - \***********************************************************************/ - -/* - - Syntax: - - ::= - ::= '+' | '-' | {empty} - ::= - | - | - | - - ::= {empty} - | - - ::= | - ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' - ::= {one character from "string_of_decimal_exponent_marks"} - ::= {one character from "string_of_decimal_marks"} - - */ - -int -atof_generic (/* return pointer to just AFTER number we read. */ - char **address_of_string_pointer, - /* At most one per number. */ - const char *string_of_decimal_marks, - const char *string_of_decimal_exponent_marks, - FLONUM_TYPE *address_of_generic_floating_point_number) -{ - int return_value; /* 0 means OK. */ - char *first_digit; - unsigned int number_of_digits_before_decimal; - unsigned int number_of_digits_after_decimal; - long decimal_exponent; - unsigned int number_of_digits_available; - char digits_sign_char; - - /* - * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent. - * It would be simpler to modify the string, but we don't; just to be nice - * to caller. - * We need to know how many digits we have, so we can allocate space for - * the digits' value. - */ - - char *p; - char c; - int seen_significant_digit; - -#ifdef ASSUME_DECIMAL_MARK_IS_DOT - gas_assert (string_of_decimal_marks[0] == '.' - && string_of_decimal_marks[1] == 0); -#define IS_DECIMAL_MARK(c) ((c) == '.') -#else -#define IS_DECIMAL_MARK(c) (0 != strchr (string_of_decimal_marks, (c))) -#endif - - first_digit = *address_of_string_pointer; - c = *first_digit; - - if (c == '-' || c == '+') - { - digits_sign_char = c; - first_digit++; - } - else - digits_sign_char = '+'; - - switch (first_digit[0]) - { - case 'n': - case 'N': - if (!strncasecmp ("nan", first_digit, 3)) - { - address_of_generic_floating_point_number->sign = 0; - address_of_generic_floating_point_number->exponent = 0; - address_of_generic_floating_point_number->leader = - address_of_generic_floating_point_number->low; - *address_of_string_pointer = first_digit + 3; - return 0; - } - break; - - case 'i': - case 'I': - if (!strncasecmp ("inf", first_digit, 3)) - { - address_of_generic_floating_point_number->sign = - digits_sign_char == '+' ? 'P' : 'N'; - address_of_generic_floating_point_number->exponent = 0; - address_of_generic_floating_point_number->leader = - address_of_generic_floating_point_number->low; - - first_digit += 3; - if (!strncasecmp ("inity", first_digit, 5)) - first_digit += 5; - - *address_of_string_pointer = first_digit; - - return 0; - } - break; - } - - number_of_digits_before_decimal = 0; - number_of_digits_after_decimal = 0; - decimal_exponent = 0; - seen_significant_digit = 0; - for (p = first_digit; - (((c = *p) != '\0') - && (!c || !IS_DECIMAL_MARK (c)) - && (!c || !strchr (string_of_decimal_exponent_marks, c))); - p++) - { - if (ISDIGIT (c)) - { - if (seen_significant_digit || c > '0') - { - ++number_of_digits_before_decimal; - seen_significant_digit = 1; - } - else - { - first_digit++; - } - } - else - { - break; /* p -> char after pre-decimal digits. */ - } - } /* For each digit before decimal mark. */ - -#ifndef OLD_FLOAT_READS - /* Ignore trailing 0's after the decimal point. The original code here - * (ifdef'd out) does not do this, and numbers like - * 4.29496729600000000000e+09 (2**31) - * come out inexact for some reason related to length of the digit - * string. - */ - if (c && IS_DECIMAL_MARK (c)) - { - unsigned int zeros = 0; /* Length of current string of zeros */ - - for (p++; (c = *p) && ISDIGIT (c); p++) - { - if (c == '0') - { - zeros++; - } - else - { - number_of_digits_after_decimal += 1 + zeros; - zeros = 0; - } - } - } -#else - if (c && IS_DECIMAL_MARK (c)) - { - for (p++; - (((c = *p) != '\0') - && (!c || !strchr (string_of_decimal_exponent_marks, c))); - p++) - { - if (ISDIGIT (c)) - { - /* This may be retracted below. */ - number_of_digits_after_decimal++; - - if ( /* seen_significant_digit || */ c > '0') - { - seen_significant_digit = TRUE; - } - } - else - { - if (!seen_significant_digit) - { - number_of_digits_after_decimal = 0; - } - break; - } - } /* For each digit after decimal mark. */ - } - - while (number_of_digits_after_decimal - && first_digit[number_of_digits_before_decimal - + number_of_digits_after_decimal] == '0') - --number_of_digits_after_decimal; -#endif - - if (flag_m68k_mri) - { - while (c == '_') - c = *++p; - } - if (c && strchr (string_of_decimal_exponent_marks, c)) - { - char digits_exponent_sign_char; - - c = *++p; - if (flag_m68k_mri) - { - while (c == '_') - c = *++p; - } - if (c && strchr ("+-", c)) - { - digits_exponent_sign_char = c; - c = *++p; - } - else - { - digits_exponent_sign_char = '+'; - } - - for (; (c); c = *++p) - { - if (ISDIGIT (c)) - { - decimal_exponent = decimal_exponent * 10 + c - '0'; - /* - * BUG! If we overflow here, we lose! - */ - } - else - { - break; - } - } - - if (digits_exponent_sign_char == '-') - { - decimal_exponent = -decimal_exponent; - } - } - - *address_of_string_pointer = p; - - number_of_digits_available = - number_of_digits_before_decimal + number_of_digits_after_decimal; - return_value = 0; - if (number_of_digits_available == 0) - { - address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */ - address_of_generic_floating_point_number->leader - = -1 + address_of_generic_floating_point_number->low; - address_of_generic_floating_point_number->sign = digits_sign_char; - /* We have just concocted (+/-)0.0E0 */ - - } - else - { - int count; /* Number of useful digits left to scan. */ - - LITTLENUM_TYPE *digits_binary_low; - unsigned int precision; - unsigned int maximum_useful_digits; - unsigned int number_of_digits_to_use; - unsigned int more_than_enough_bits_for_digits; - unsigned int more_than_enough_littlenums_for_digits; - unsigned int size_of_digits_in_littlenums; - unsigned int size_of_digits_in_chars; - FLONUM_TYPE power_of_10_flonum; - FLONUM_TYPE digits_flonum; - - precision = (address_of_generic_floating_point_number->high - - address_of_generic_floating_point_number->low - + 1); /* Number of destination littlenums. */ - - /* Includes guard bits (two littlenums worth) */ - maximum_useful_digits = (((precision - 2)) - * ( (LITTLENUM_NUMBER_OF_BITS)) - * 1000000 / 3321928) - + 2; /* 2 :: guard digits. */ - - if (number_of_digits_available > maximum_useful_digits) - { - number_of_digits_to_use = maximum_useful_digits; - } - else - { - number_of_digits_to_use = number_of_digits_available; - } - - /* Cast these to SIGNED LONG first, otherwise, on systems with - LONG wider than INT (such as Alpha OSF/1), unsignedness may - cause unexpected results. */ - decimal_exponent += ((long) number_of_digits_before_decimal - - (long) number_of_digits_to_use); - - more_than_enough_bits_for_digits - = (number_of_digits_to_use * 3321928 / 1000000 + 1); - - more_than_enough_littlenums_for_digits - = (more_than_enough_bits_for_digits - / LITTLENUM_NUMBER_OF_BITS) - + 2; - - /* Compute (digits) part. In "12.34E56" this is the "1234" part. - Arithmetic is exact here. If no digits are supplied then this - part is a 0 valued binary integer. Allocate room to build up - the binary number as littlenums. We want this memory to - disappear when we leave this function. Assume no alignment - problems => (room for n objects) == n * (room for 1 - object). */ - - size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits; - size_of_digits_in_chars = size_of_digits_in_littlenums - * sizeof (LITTLENUM_TYPE); - - digits_binary_low = (LITTLENUM_TYPE *) - alloca (size_of_digits_in_chars); - - memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars); - - /* Digits_binary_low[] is allocated and zeroed. */ - - /* - * Parse the decimal digits as if * digits_low was in the units position. - * Emit a binary number into digits_binary_low[]. - * - * Use a large-precision version of: - * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit - */ - - for (p = first_digit, count = number_of_digits_to_use; count; p++, --count) - { - c = *p; - if (ISDIGIT (c)) - { - /* - * Multiply by 10. Assume can never overflow. - * Add this digit to digits_binary_low[]. - */ - - long carry; - LITTLENUM_TYPE *littlenum_pointer; - LITTLENUM_TYPE *littlenum_limit; - - littlenum_limit = digits_binary_low - + more_than_enough_littlenums_for_digits - - 1; - - carry = c - '0'; /* char -> binary */ - - for (littlenum_pointer = digits_binary_low; - littlenum_pointer <= littlenum_limit; - littlenum_pointer++) - { - long work; - - work = carry + 10 * (long) (*littlenum_pointer); - *littlenum_pointer = work & LITTLENUM_MASK; - carry = work >> LITTLENUM_NUMBER_OF_BITS; - } - - if (carry != 0) - { - /* - * We have a GROSS internal error. - * This should never happen. - */ - as_fatal (_("failed sanity check")); - } - } - else - { - ++count; /* '.' doesn't alter digits used count. */ - } - } - - /* - * Digits_binary_low[] properly encodes the value of the digits. - * Forget about any high-order littlenums that are 0. - */ - while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0 - && size_of_digits_in_littlenums >= 2) - size_of_digits_in_littlenums--; - - digits_flonum.low = digits_binary_low; - digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1; - digits_flonum.leader = digits_flonum.high; - digits_flonum.exponent = 0; - /* - * The value of digits_flonum . sign should not be important. - * We have already decided the output's sign. - * We trust that the sign won't influence the other parts of the number! - * So we give it a value for these reasons: - * (1) courtesy to humans reading/debugging - * these numbers so they don't get excited about strange values - * (2) in future there may be more meaning attached to sign, - * and what was - * harmless noise may become disruptive, ill-conditioned (or worse) - * input. - */ - digits_flonum.sign = '+'; - - { - /* - * Compute the mantssa (& exponent) of the power of 10. - * If successful, then multiply the power of 10 by the digits - * giving return_binary_mantissa and return_binary_exponent. - */ - - LITTLENUM_TYPE *power_binary_low; - int decimal_exponent_is_negative; - /* This refers to the "-56" in "12.34E-56". */ - /* FALSE: decimal_exponent is positive (or 0) */ - /* TRUE: decimal_exponent is negative */ - FLONUM_TYPE temporary_flonum; - LITTLENUM_TYPE *temporary_binary_low; - unsigned int size_of_power_in_littlenums; - unsigned int size_of_power_in_chars; - - size_of_power_in_littlenums = precision; - /* Precision has a built-in fudge factor so we get a few guard bits. */ - - decimal_exponent_is_negative = decimal_exponent < 0; - if (decimal_exponent_is_negative) - { - decimal_exponent = -decimal_exponent; - } - - /* From now on: the decimal exponent is > 0. Its sign is separate. */ - - size_of_power_in_chars = size_of_power_in_littlenums - * sizeof (LITTLENUM_TYPE) + 2; - - power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars); - temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars); - memset ((char *) power_binary_low, '\0', size_of_power_in_chars); - *power_binary_low = 1; - power_of_10_flonum.exponent = 0; - power_of_10_flonum.low = power_binary_low; - power_of_10_flonum.leader = power_binary_low; - power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1; - power_of_10_flonum.sign = '+'; - temporary_flonum.low = temporary_binary_low; - temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1; - /* - * (power) == 1. - * Space for temporary_flonum allocated. - */ - - /* - * ... - * - * WHILE more bits - * DO find next bit (with place value) - * multiply into power mantissa - * OD - */ - { - int place_number_limit; - /* Any 10^(2^n) whose "n" exceeds this */ - /* value will fall off the end of */ - /* flonum_XXXX_powers_of_ten[]. */ - int place_number; - const FLONUM_TYPE *multiplicand; /* -> 10^(2^n) */ - - place_number_limit = table_size_of_flonum_powers_of_ten; - - multiplicand = (decimal_exponent_is_negative - ? flonum_negative_powers_of_ten - : flonum_positive_powers_of_ten); - - for (place_number = 1;/* Place value of this bit of exponent. */ - decimal_exponent;/* Quit when no more 1 bits in exponent. */ - decimal_exponent >>= 1, place_number++) - { - if (decimal_exponent & 1) - { - if (place_number > place_number_limit) - { - /* The decimal exponent has a magnitude so great - that our tables can't help us fragment it. - Although this routine is in error because it - can't imagine a number that big, signal an - error as if it is the user's fault for - presenting such a big number. */ - return_value = ERROR_EXPONENT_OVERFLOW; - /* quit out of loop gracefully */ - decimal_exponent = 0; - } - else - { -#ifdef TRACE - printf ("before multiply, place_number = %d., power_of_10_flonum:\n", - place_number); - - flonum_print (&power_of_10_flonum); - (void) putchar ('\n'); -#endif -#ifdef TRACE - printf ("multiplier:\n"); - flonum_print (multiplicand + place_number); - (void) putchar ('\n'); -#endif - flonum_multip (multiplicand + place_number, - &power_of_10_flonum, &temporary_flonum); -#ifdef TRACE - printf ("after multiply:\n"); - flonum_print (&temporary_flonum); - (void) putchar ('\n'); -#endif - flonum_copy (&temporary_flonum, &power_of_10_flonum); -#ifdef TRACE - printf ("after copy:\n"); - flonum_print (&power_of_10_flonum); - (void) putchar ('\n'); -#endif - } /* If this bit of decimal_exponent was computable.*/ - } /* If this bit of decimal_exponent was set. */ - } /* For each bit of binary representation of exponent */ -#ifdef TRACE - printf ("after computing power_of_10_flonum:\n"); - flonum_print (&power_of_10_flonum); - (void) putchar ('\n'); -#endif - } - - } - - /* - * power_of_10_flonum is power of ten in binary (mantissa) , (exponent). - * It may be the number 1, in which case we don't NEED to multiply. - * - * Multiply (decimal digits) by power_of_10_flonum. - */ - - flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number); - /* Assert sign of the number we made is '+'. */ - address_of_generic_floating_point_number->sign = digits_sign_char; - - } - return return_value; -} - -#ifdef TRACE -static void -flonum_print (f) - const FLONUM_TYPE *f; -{ - LITTLENUM_TYPE *lp; - char littlenum_format[10]; - sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2); -#define print_littlenum(LP) (printf (littlenum_format, LP)) - printf ("flonum @%p %c e%ld", f, f->sign, f->exponent); - if (f->low < f->high) - for (lp = f->high; lp >= f->low; lp--) - print_littlenum (*lp); - else - for (lp = f->low; lp <= f->high; lp++) - print_littlenum (*lp); - printf ("\n"); - fflush (stdout); -} -#endif - -/* end of atof_generic.c */ diff --git a/contrib/binutils-2.22/gas/bignum.h b/contrib/binutils-2.22/gas/bignum.h deleted file mode 100644 index 41c3559988..0000000000 --- a/contrib/binutils-2.22/gas/bignum.h +++ /dev/null @@ -1,42 +0,0 @@ -/* bignum.h-arbitrary precision integers - Copyright 1987, 1992, 2003, 2005, 2007 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/***********************************************************************\ - * * - * Arbitrary-precision integer arithmetic. * - * For speed, we work in groups of bits, even though this * - * complicates algorithms. * - * Each group of bits is called a 'littlenum'. * - * A bunch of littlenums representing a (possibly large) * - * integer is called a 'bignum'. * - * Bignums are >= 0. * - * * - \***********************************************************************/ - -#define LITTLENUM_NUMBER_OF_BITS (16) -#define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS) -#define LITTLENUM_MASK (0xFFFF) -#define LITTLENUM_SHIFT (1) -#define CHARS_PER_LITTLENUM (1 << LITTLENUM_SHIFT) -#ifndef BITS_PER_CHAR -#define BITS_PER_CHAR (8) -#endif - -typedef unsigned short LITTLENUM_TYPE; diff --git a/contrib/binutils-2.22/gas/bit_fix.h b/contrib/binutils-2.22/gas/bit_fix.h deleted file mode 100644 index a83bddc3f0..0000000000 --- a/contrib/binutils-2.22/gas/bit_fix.h +++ /dev/null @@ -1,48 +0,0 @@ -/* bit_fix.h - Copyright 1987, 1992, 2000, 2001, 2003, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* The bit_fix was implemented to support machines that need variables - to be inserted in bitfields other than 1, 2 and 4 bytes. - Furthermore it gives us a possibility to mask in bits in the symbol - when it's fixed in the objectcode and check the symbols limits. - - The or-mask is used to set the huffman bits in displacements for the - ns32k port. - The acbi, addqi, movqi, cmpqi instruction requires an assembler that - can handle bitfields. Ie. handle an expression, evaluate it and insert - the result in some bitfield. (eg: 5 bits in a short field of an opcode). */ - -#ifndef __bit_fix_h__ -#define __bit_fix_h__ - -struct bit_fix { - int fx_bit_size; /* Length of bitfield */ - int fx_bit_offset; /* Bit offset to bitfield */ - long fx_bit_base; /* Where do we apply the bitfix. - If this is zero, default is assumed. */ - long fx_bit_base_adj; /* Adjustment of base */ - long fx_bit_max; /* Signextended max for bitfield */ - long fx_bit_min; /* Signextended min for bitfield */ - long fx_bit_add; /* Or mask, used for huffman prefix */ -}; -typedef struct bit_fix bit_fixS; - -#endif /* __bit_fix_h__ */ diff --git a/contrib/binutils-2.22/gas/compress-debug.c b/contrib/binutils-2.22/gas/compress-debug.c deleted file mode 100644 index 09076002d7..0000000000 --- a/contrib/binutils-2.22/gas/compress-debug.c +++ /dev/null @@ -1,117 +0,0 @@ -/* compress-debug.c - compress debug sections - Copyright 2010 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "config.h" -#include -#include "ansidecl.h" -#include "compress-debug.h" - -#ifdef HAVE_ZLIB_H -#include -#endif - -/* Initialize the compression engine. */ - -struct z_stream_s * -compress_init (void) -{ -#ifndef HAVE_ZLIB_H - return NULL; -#else - static struct z_stream_s strm; - - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - deflateInit (&strm, Z_DEFAULT_COMPRESSION); - return &strm; -#endif /* HAVE_ZLIB_H */ -} - -/* Stream the contents of a frag to the compression engine. Output - from the engine goes into the current frag on the obstack. */ - -int -compress_data (struct z_stream_s *strm ATTRIBUTE_UNUSED, - const char **next_in ATTRIBUTE_UNUSED, - int *avail_in ATTRIBUTE_UNUSED, - char **next_out ATTRIBUTE_UNUSED, - int *avail_out ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - return -1; -#else - int out_size = 0; - int x; - - strm->next_in = (Bytef *) (*next_in); - strm->avail_in = *avail_in; - strm->next_out = (Bytef *) (*next_out); - strm->avail_out = *avail_out; - - x = deflate (strm, Z_NO_FLUSH); - if (x != Z_OK) - return -1; - - out_size = *avail_out - strm->avail_out; - *next_in = (char *) (strm->next_in); - *avail_in = strm->avail_in; - *next_out = (char *) (strm->next_out); - *avail_out = strm->avail_out; - - return out_size; -#endif /* HAVE_ZLIB_H */ -} - -/* Finish the compression and consume the remaining compressed output. - Returns -1 for error, 0 when done, 1 when more output buffer is - needed. */ - -int -compress_finish (struct z_stream_s *strm ATTRIBUTE_UNUSED, - char **next_out ATTRIBUTE_UNUSED, - int *avail_out ATTRIBUTE_UNUSED, - int *out_size ATTRIBUTE_UNUSED) -{ -#ifndef HAVE_ZLIB_H - return -1; -#else - int x; - - strm->avail_in = 0; - strm->next_out = (Bytef *) (*next_out); - strm->avail_out = *avail_out; - - x = deflate (strm, Z_FINISH); - - *out_size = *avail_out - strm->avail_out; - *next_out = (char *) (strm->next_out); - *avail_out = strm->avail_out; - - if (x == Z_STREAM_END) - { - deflateEnd (strm); - return 0; - } - if (strm->avail_out != 0) - return -1; - return 1; -#endif /* HAVE_ZLIB_H */ -} diff --git a/contrib/binutils-2.22/gas/compress-debug.h b/contrib/binutils-2.22/gas/compress-debug.h deleted file mode 100644 index 9d821e9155..0000000000 --- a/contrib/binutils-2.22/gas/compress-debug.h +++ /dev/null @@ -1,39 +0,0 @@ -/* compress-debug.h - Header file for compressed debug sections. - Copyright 2010 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef COMPRESS_DEBUG_H -#define COMPRESS_DEBUG_H - -struct z_stream_s; - -/* Initialize the compression engine. */ -extern struct z_stream_s * -compress_init (void); - -/* Stream the contents of a frag to the compression engine. Output - from the engine goes into the current frag on the obstack. */ -extern int -compress_data (struct z_stream_s *, const char **, int *, char **, int *); - -/* Finish the compression and consume the remaining compressed output. */ -extern int -compress_finish (struct z_stream_s *, char **, int *, int *); - -#endif /* COMPRESS_DEBUG_H */ diff --git a/contrib/binutils-2.22/gas/cond.c b/contrib/binutils-2.22/gas/cond.c deleted file mode 100644 index 4b6326f463..0000000000 --- a/contrib/binutils-2.22/gas/cond.c +++ /dev/null @@ -1,577 +0,0 @@ -/* cond.c - conditional assembly pseudo-ops, and .include - Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 2000, 2001, 2002, - 2003, 2005, 2006, 2007 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "as.h" -#include "sb.h" -#include "macro.h" - -#include "obstack.h" - -/* This is allocated to grow and shrink as .ifdef/.endif pairs are - scanned. */ -struct obstack cond_obstack; - -struct file_line { - char *file; - unsigned int line; -}; - -/* We push one of these structures for each .if, and pop it at the - .endif. */ - -struct conditional_frame { - /* The source file & line number of the "if". */ - struct file_line if_file_line; - /* The source file & line of the "else". */ - struct file_line else_file_line; - /* The previous conditional. */ - struct conditional_frame *previous_cframe; - /* Have we seen an else yet? */ - int else_seen; - /* Whether we are currently ignoring input. */ - int ignoring; - /* Whether a conditional at a higher level is ignoring input. - Set also when a branch of an "if .. elseif .." tree has matched - to prevent further matches. */ - int dead_tree; - /* Macro nesting level at which this conditional was created. */ - int macro_nest; -}; - -static void initialize_cframe (struct conditional_frame *cframe); -static char *get_mri_string (int, int *); - -static struct conditional_frame *current_cframe = NULL; - -/* Performs the .ifdef (test_defined == 1) and - the .ifndef (test_defined == 0) pseudo op. */ - -void -s_ifdef (int test_defined) -{ - /* Points to name of symbol. */ - char *name; - /* Points to symbol. */ - symbolS *symbolP; - struct conditional_frame cframe; - char c; - - /* Leading whitespace is part of operand. */ - SKIP_WHITESPACE (); - name = input_line_pointer; - - if (!is_name_beginner (*name)) - { - as_bad (_("invalid identifier for \".ifdef\"")); - obstack_1grow (&cond_obstack, 0); - ignore_rest_of_line (); - return; - } - - c = get_symbol_end (); - symbolP = symbol_find (name); - *input_line_pointer = c; - - initialize_cframe (&cframe); - - if (cframe.dead_tree) - cframe.ignoring = 1; - else - { - int is_defined; - - /* Use the same definition of 'defined' as .equiv so that a symbol - which has been referenced but not yet given a value/address is - considered to be undefined. */ - is_defined = - symbolP != NULL - && (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) - && S_GET_SEGMENT (symbolP) != reg_section; - - cframe.ignoring = ! (test_defined ^ is_defined); - } - - current_cframe = ((struct conditional_frame *) - obstack_copy (&cond_obstack, &cframe, - sizeof (cframe))); - - if (LISTING_SKIP_COND () - && cframe.ignoring - && (cframe.previous_cframe == NULL - || ! cframe.previous_cframe->ignoring)) - listing_list (2); - - demand_empty_rest_of_line (); -} - -void -s_if (int arg) -{ - expressionS operand; - struct conditional_frame cframe; - int t; - char *stop = NULL; - char stopc; - - if (flag_mri) - stop = mri_comment_field (&stopc); - - /* Leading whitespace is part of operand. */ - SKIP_WHITESPACE (); - - if (current_cframe != NULL && current_cframe->ignoring) - { - operand.X_add_number = 0; - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - } - else - { - expression_and_evaluate (&operand); - if (operand.X_op != O_constant) - as_bad (_("non-constant expression in \".if\" statement")); - } - - switch ((operatorT) arg) - { - case O_eq: t = operand.X_add_number == 0; break; - case O_ne: t = operand.X_add_number != 0; break; - case O_lt: t = operand.X_add_number < 0; break; - case O_le: t = operand.X_add_number <= 0; break; - case O_ge: t = operand.X_add_number >= 0; break; - case O_gt: t = operand.X_add_number > 0; break; - default: - abort (); - return; - } - - /* If the above error is signaled, this will dispatch - using an undefined result. No big deal. */ - initialize_cframe (&cframe); - cframe.ignoring = cframe.dead_tree || ! t; - current_cframe = ((struct conditional_frame *) - obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); - - if (LISTING_SKIP_COND () - && cframe.ignoring - && (cframe.previous_cframe == NULL - || ! cframe.previous_cframe->ignoring)) - listing_list (2); - - if (flag_mri) - mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); -} - -/* Performs the .ifb (test_blank == 1) and - the .ifnb (test_blank == 0) pseudo op. */ - -void -s_ifb (int test_blank) -{ - struct conditional_frame cframe; - - initialize_cframe (&cframe); - - if (cframe.dead_tree) - cframe.ignoring = 1; - else - { - int is_eol; - - SKIP_WHITESPACE (); - is_eol = is_end_of_line[(unsigned char) *input_line_pointer]; - cframe.ignoring = (test_blank == !is_eol); - } - - current_cframe = ((struct conditional_frame *) - obstack_copy (&cond_obstack, &cframe, - sizeof (cframe))); - - if (LISTING_SKIP_COND () - && cframe.ignoring - && (cframe.previous_cframe == NULL - || ! cframe.previous_cframe->ignoring)) - listing_list (2); - - ignore_rest_of_line (); -} - -/* Get a string for the MRI IFC or IFNC pseudo-ops. */ - -static char * -get_mri_string (int terminator, int *len) -{ - char *ret; - char *s; - - SKIP_WHITESPACE (); - s = ret = input_line_pointer; - if (*input_line_pointer == '\'') - { - ++s; - ++input_line_pointer; - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - { - *s++ = *input_line_pointer++; - if (s[-1] == '\'') - { - if (*input_line_pointer != '\'') - break; - ++input_line_pointer; - } - } - SKIP_WHITESPACE (); - } - else - { - while (*input_line_pointer != terminator - && ! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - s = input_line_pointer; - while (s > ret && (s[-1] == ' ' || s[-1] == '\t')) - --s; - } - - *len = s - ret; - return ret; -} - -/* The MRI IFC and IFNC pseudo-ops. */ - -void -s_ifc (int arg) -{ - char *stop = NULL; - char stopc; - char *s1, *s2; - int len1, len2; - int res; - struct conditional_frame cframe; - - if (flag_mri) - stop = mri_comment_field (&stopc); - - s1 = get_mri_string (',', &len1); - - if (*input_line_pointer != ',') - as_bad (_("bad format for ifc or ifnc")); - else - ++input_line_pointer; - - s2 = get_mri_string (';', &len2); - - res = len1 == len2 && strncmp (s1, s2, len1) == 0; - - initialize_cframe (&cframe); - cframe.ignoring = cframe.dead_tree || ! (res ^ arg); - current_cframe = ((struct conditional_frame *) - obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); - - if (LISTING_SKIP_COND () - && cframe.ignoring - && (cframe.previous_cframe == NULL - || ! cframe.previous_cframe->ignoring)) - listing_list (2); - - if (flag_mri) - mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); -} - -void -s_elseif (int arg) -{ - if (current_cframe == NULL) - { - as_bad (_("\".elseif\" without matching \".if\"")); - } - else if (current_cframe->else_seen) - { - as_bad (_("\".elseif\" after \".else\"")); - as_bad_where (current_cframe->else_file_line.file, - current_cframe->else_file_line.line, - _("here is the previous \".else\"")); - as_bad_where (current_cframe->if_file_line.file, - current_cframe->if_file_line.line, - _("here is the previous \".if\"")); - } - else - { - as_where (¤t_cframe->else_file_line.file, - ¤t_cframe->else_file_line.line); - - current_cframe->dead_tree |= !current_cframe->ignoring; - current_cframe->ignoring = current_cframe->dead_tree; - } - - if (current_cframe == NULL || current_cframe->ignoring) - { - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - - if (current_cframe == NULL) - return; - } - else - { - expressionS operand; - int t; - - /* Leading whitespace is part of operand. */ - SKIP_WHITESPACE (); - - expression_and_evaluate (&operand); - if (operand.X_op != O_constant) - as_bad (_("non-constant expression in \".elseif\" statement")); - - switch ((operatorT) arg) - { - case O_eq: t = operand.X_add_number == 0; break; - case O_ne: t = operand.X_add_number != 0; break; - case O_lt: t = operand.X_add_number < 0; break; - case O_le: t = operand.X_add_number <= 0; break; - case O_ge: t = operand.X_add_number >= 0; break; - case O_gt: t = operand.X_add_number > 0; break; - default: - abort (); - return; - } - - current_cframe->ignoring = current_cframe->dead_tree || ! t; - } - - if (LISTING_SKIP_COND () - && (current_cframe->previous_cframe == NULL - || ! current_cframe->previous_cframe->ignoring)) - { - if (! current_cframe->ignoring) - listing_list (1); - else - listing_list (2); - } - - demand_empty_rest_of_line (); -} - -void -s_endif (int arg ATTRIBUTE_UNUSED) -{ - struct conditional_frame *hold; - - if (current_cframe == NULL) - { - as_bad (_("\".endif\" without \".if\"")); - } - else - { - if (LISTING_SKIP_COND () - && current_cframe->ignoring - && (current_cframe->previous_cframe == NULL - || ! current_cframe->previous_cframe->ignoring)) - listing_list (1); - - hold = current_cframe; - current_cframe = current_cframe->previous_cframe; - obstack_free (&cond_obstack, hold); - } /* if one pop too many */ - - if (flag_mri) - { - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - } - - demand_empty_rest_of_line (); -} - -void -s_else (int arg ATTRIBUTE_UNUSED) -{ - if (current_cframe == NULL) - { - as_bad (_("\".else\" without matching \".if\"")); - } - else if (current_cframe->else_seen) - { - as_bad (_("duplicate \".else\"")); - as_bad_where (current_cframe->else_file_line.file, - current_cframe->else_file_line.line, - _("here is the previous \".else\"")); - as_bad_where (current_cframe->if_file_line.file, - current_cframe->if_file_line.line, - _("here is the previous \".if\"")); - } - else - { - as_where (¤t_cframe->else_file_line.file, - ¤t_cframe->else_file_line.line); - - current_cframe->ignoring = - current_cframe->dead_tree | !current_cframe->ignoring; - - if (LISTING_SKIP_COND () - && (current_cframe->previous_cframe == NULL - || ! current_cframe->previous_cframe->ignoring)) - { - if (! current_cframe->ignoring) - listing_list (1); - else - listing_list (2); - } - - current_cframe->else_seen = 1; - } - - if (flag_mri) - { - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - ++input_line_pointer; - } - - demand_empty_rest_of_line (); -} - -void -s_ifeqs (int arg) -{ - char *s1, *s2; - int len1, len2; - int res; - struct conditional_frame cframe; - - s1 = demand_copy_C_string (&len1); - - SKIP_WHITESPACE (); - if (*input_line_pointer != ',') - { - as_bad (_(".ifeqs syntax error")); - ignore_rest_of_line (); - return; - } - - ++input_line_pointer; - - s2 = demand_copy_C_string (&len2); - - res = len1 == len2 && strncmp (s1, s2, len1) == 0; - - initialize_cframe (&cframe); - cframe.ignoring = cframe.dead_tree || ! (res ^ arg); - current_cframe = ((struct conditional_frame *) - obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); - - if (LISTING_SKIP_COND () - && cframe.ignoring - && (cframe.previous_cframe == NULL - || ! cframe.previous_cframe->ignoring)) - listing_list (2); - - demand_empty_rest_of_line (); -} - -int -ignore_input (void) -{ - char *s; - - s = input_line_pointer; - - if (NO_PSEUDO_DOT || flag_m68k_mri) - { - if (s[-1] != '.') - --s; - } - else - { - if (s[-1] != '.') - return (current_cframe != NULL) && (current_cframe->ignoring); - } - - /* We cannot ignore certain pseudo ops. */ - if (((s[0] == 'i' - || s[0] == 'I') - && (!strncasecmp (s, "if", 2) - || !strncasecmp (s, "ifdef", 5) - || !strncasecmp (s, "ifndef", 6))) - || ((s[0] == 'e' - || s[0] == 'E') - && (!strncasecmp (s, "else", 4) - || !strncasecmp (s, "endif", 5) - || !strncasecmp (s, "endc", 4)))) - return 0; - - return (current_cframe != NULL) && (current_cframe->ignoring); -} - -static void -initialize_cframe (struct conditional_frame *cframe) -{ - memset (cframe, 0, sizeof (*cframe)); - as_where (&cframe->if_file_line.file, - &cframe->if_file_line.line); - cframe->previous_cframe = current_cframe; - cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring; - cframe->macro_nest = macro_nest; -} - -/* Give an error if a conditional is unterminated inside a macro or - the assembly as a whole. If NEST is non negative, we are being - called because of the end of a macro expansion. If NEST is - negative, we are being called at the of the input files. */ - -void -cond_finish_check (int nest) -{ - if (current_cframe != NULL && current_cframe->macro_nest >= nest) - { - if (nest >= 0) - as_bad (_("end of macro inside conditional")); - else - as_bad (_("end of file inside conditional")); - as_bad_where (current_cframe->if_file_line.file, - current_cframe->if_file_line.line, - _("here is the start of the unterminated conditional")); - if (current_cframe->else_seen) - as_bad_where (current_cframe->else_file_line.file, - current_cframe->else_file_line.line, - _("here is the \"else\" of the unterminated conditional")); - } -} - -/* This function is called when we exit out of a macro. We assume - that any conditionals which began within the macro are correctly - nested, and just pop them off the stack. */ - -void -cond_exit_macro (int nest) -{ - while (current_cframe != NULL && current_cframe->macro_nest >= nest) - { - struct conditional_frame *hold; - - hold = current_cframe; - current_cframe = current_cframe->previous_cframe; - obstack_free (&cond_obstack, hold); - } -} diff --git a/contrib/binutils-2.22/gas/config/atof-ieee.c b/contrib/binutils-2.22/gas/config/atof-ieee.c deleted file mode 100644 index 4ceb0b9537..0000000000 --- a/contrib/binutils-2.22/gas/config/atof-ieee.c +++ /dev/null @@ -1,813 +0,0 @@ -/* atof_ieee.c - turn a Flonum into an IEEE floating point number - Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005, - 2007, 2009 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "as.h" - -/* Flonums returned here. */ -extern FLONUM_TYPE generic_floating_point_number; - -extern const char EXP_CHARS[]; -/* Precision in LittleNums. */ -/* Don't count the gap in the m68k extended precision format. */ -#define MAX_PRECISION 5 -#define F_PRECISION 2 -#define D_PRECISION 4 -#define X_PRECISION 5 -#define P_PRECISION 5 - -/* Length in LittleNums of guard bits. */ -#define GUARD 2 - -#ifndef TC_LARGEST_EXPONENT_IS_NORMAL -#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0 -#endif - -static const unsigned long mask[] = -{ - 0x00000000, - 0x00000001, - 0x00000003, - 0x00000007, - 0x0000000f, - 0x0000001f, - 0x0000003f, - 0x0000007f, - 0x000000ff, - 0x000001ff, - 0x000003ff, - 0x000007ff, - 0x00000fff, - 0x00001fff, - 0x00003fff, - 0x00007fff, - 0x0000ffff, - 0x0001ffff, - 0x0003ffff, - 0x0007ffff, - 0x000fffff, - 0x001fffff, - 0x003fffff, - 0x007fffff, - 0x00ffffff, - 0x01ffffff, - 0x03ffffff, - 0x07ffffff, - 0x0fffffff, - 0x1fffffff, - 0x3fffffff, - 0x7fffffff, - 0xffffffff, -}; - -static int bits_left_in_littlenum; -static int littlenums_left; -static LITTLENUM_TYPE *littlenum_pointer; - -static int -next_bits (int number_of_bits) -{ - int return_value; - - if (!littlenums_left) - return 0; - - if (number_of_bits >= bits_left_in_littlenum) - { - return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; - number_of_bits -= bits_left_in_littlenum; - return_value <<= number_of_bits; - - if (--littlenums_left) - { - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; - --littlenum_pointer; - return_value |= - (*littlenum_pointer >> bits_left_in_littlenum) - & mask[number_of_bits]; - } - } - else - { - bits_left_in_littlenum -= number_of_bits; - return_value = - mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum); - } - return return_value; -} - -/* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */ - -static void -unget_bits (int num) -{ - if (!littlenums_left) - { - ++littlenum_pointer; - ++littlenums_left; - bits_left_in_littlenum = num; - } - else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) - { - bits_left_in_littlenum = - num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); - ++littlenum_pointer; - ++littlenums_left; - } - else - bits_left_in_littlenum += num; -} - -static void -make_invalid_floating_point_number (LITTLENUM_TYPE *words) -{ - as_bad (_("cannot create floating-point number")); - /* Zero the leftmost bit. */ - words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; - words[1] = (LITTLENUM_TYPE) -1; - words[2] = (LITTLENUM_TYPE) -1; - words[3] = (LITTLENUM_TYPE) -1; - words[4] = (LITTLENUM_TYPE) -1; - words[5] = (LITTLENUM_TYPE) -1; -} - -/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to - figure out any alignment problems and to conspire for the - bytes/word to be emitted in the right order. Bigendians beware! */ - -/* Note that atof-ieee always has X and P precisions enabled. it is up - to md_atof to filter them out if the target machine does not support - them. */ - -/* Returns pointer past text consumed. */ - -char * -atof_ieee (char *str, /* Text to convert to binary. */ - int what_kind, /* 'd', 'f', 'x', 'p'. */ - LITTLENUM_TYPE *words) /* Build the binary here. */ -{ - /* Extra bits for zeroed low-order bits. - The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ - static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; - char *return_value; - /* Number of 16-bit words in the format. */ - int precision; - long exponent_bits; - FLONUM_TYPE save_gen_flonum; - - /* We have to save the generic_floating_point_number because it - contains storage allocation about the array of LITTLENUMs where - the value is actually stored. We will allocate our own array of - littlenums below, but have to restore the global one on exit. */ - save_gen_flonum = generic_floating_point_number; - - return_value = str; - generic_floating_point_number.low = bits + MAX_PRECISION; - generic_floating_point_number.high = NULL; - generic_floating_point_number.leader = NULL; - generic_floating_point_number.exponent = 0; - generic_floating_point_number.sign = '\0'; - - /* Use more LittleNums than seems necessary: the highest flonum may - have 15 leading 0 bits, so could be useless. */ - - memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); - - switch (what_kind) - { - case 'f': - case 'F': - case 's': - case 'S': - precision = F_PRECISION; - exponent_bits = 8; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - precision = D_PRECISION; - exponent_bits = 11; - break; - - case 'x': - case 'X': - case 'e': - case 'E': - precision = X_PRECISION; - exponent_bits = 15; - break; - - case 'p': - case 'P': - precision = P_PRECISION; - exponent_bits = -1; - break; - - default: - make_invalid_floating_point_number (words); - return (NULL); - } - - generic_floating_point_number.high - = generic_floating_point_number.low + precision - 1 + GUARD; - - if (atof_generic (&return_value, ".", EXP_CHARS, - &generic_floating_point_number)) - { - make_invalid_floating_point_number (words); - return NULL; - } - gen_to_words (words, precision, exponent_bits); - - /* Restore the generic_floating_point_number's storage alloc (and - everything else). */ - generic_floating_point_number = save_gen_flonum; - - return return_value; -} - -/* Turn generic_floating_point_number into a real float/double/extended. */ - -int -gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits) -{ - int return_value = 0; - - long exponent_1; - long exponent_2; - long exponent_3; - long exponent_4; - int exponent_skippage; - LITTLENUM_TYPE word1; - LITTLENUM_TYPE *lp; - LITTLENUM_TYPE *words_end; - - words_end = words + precision; -#ifdef TC_M68K - if (precision == X_PRECISION) - /* On the m68k the extended precision format has a gap of 16 bits - between the exponent and the mantissa. */ - words_end++; -#endif - - if (generic_floating_point_number.low > generic_floating_point_number.leader) - { - /* 0.0e0 seen. */ - if (generic_floating_point_number.sign == '+') - words[0] = 0x0000; - else - words[0] = 0x8000; - memset (&words[1], '\0', - (words_end - words - 1) * sizeof (LITTLENUM_TYPE)); - return return_value; - } - - /* NaN: Do the right thing. */ - if (generic_floating_point_number.sign == 0) - { - if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) - as_warn (_("NaNs are not supported by this target\n")); - if (precision == F_PRECISION) - { - words[0] = 0x7fff; - words[1] = 0xffff; - } - else if (precision == X_PRECISION) - { -#ifdef TC_M68K - words[0] = 0x7fff; - words[1] = 0; - words[2] = 0xffff; - words[3] = 0xffff; - words[4] = 0xffff; - words[5] = 0xffff; -#else /* ! TC_M68K */ -#ifdef TC_I386 - words[0] = 0xffff; - words[1] = 0xc000; - words[2] = 0; - words[3] = 0; - words[4] = 0; -#else /* ! TC_I386 */ - abort (); -#endif /* ! TC_I386 */ -#endif /* ! TC_M68K */ - } - else - { - words[0] = 0x7fff; - words[1] = 0xffff; - words[2] = 0xffff; - words[3] = 0xffff; - } - return return_value; - } - else if (generic_floating_point_number.sign == 'P') - { - if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) - as_warn (_("Infinities are not supported by this target\n")); - - /* +INF: Do the right thing. */ - if (precision == F_PRECISION) - { - words[0] = 0x7f80; - words[1] = 0; - } - else if (precision == X_PRECISION) - { -#ifdef TC_M68K - words[0] = 0x7fff; - words[1] = 0; - words[2] = 0; - words[3] = 0; - words[4] = 0; - words[5] = 0; -#else /* ! TC_M68K */ -#ifdef TC_I386 - words[0] = 0x7fff; - words[1] = 0x8000; - words[2] = 0; - words[3] = 0; - words[4] = 0; -#else /* ! TC_I386 */ - abort (); -#endif /* ! TC_I386 */ -#endif /* ! TC_M68K */ - } - else - { - words[0] = 0x7ff0; - words[1] = 0; - words[2] = 0; - words[3] = 0; - } - return return_value; - } - else if (generic_floating_point_number.sign == 'N') - { - if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) - as_warn (_("Infinities are not supported by this target\n")); - - /* Negative INF. */ - if (precision == F_PRECISION) - { - words[0] = 0xff80; - words[1] = 0x0; - } - else if (precision == X_PRECISION) - { -#ifdef TC_M68K - words[0] = 0xffff; - words[1] = 0; - words[2] = 0; - words[3] = 0; - words[4] = 0; - words[5] = 0; -#else /* ! TC_M68K */ -#ifdef TC_I386 - words[0] = 0xffff; - words[1] = 0x8000; - words[2] = 0; - words[3] = 0; - words[4] = 0; -#else /* ! TC_I386 */ - abort (); -#endif /* ! TC_I386 */ -#endif /* ! TC_M68K */ - } - else - { - words[0] = 0xfff0; - words[1] = 0x0; - words[2] = 0x0; - words[3] = 0x0; - } - return return_value; - } - - /* The floating point formats we support have: - Bit 15 is sign bit. - Bits 14:n are excess-whatever exponent. - Bits n-1:0 (if any) are most significant bits of fraction. - Bits 15:0 of the next word(s) are the next most significant bits. - - So we need: number of bits of exponent, number of bits of - mantissa. */ - bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; - littlenum_pointer = generic_floating_point_number.leader; - littlenums_left = (1 - + generic_floating_point_number.leader - - generic_floating_point_number.low); - - /* Seek (and forget) 1st significant bit. */ - for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);; - exponent_1 = (generic_floating_point_number.exponent - + generic_floating_point_number.leader - + 1 - - generic_floating_point_number.low); - - /* Radix LITTLENUM_RADIX, point just higher than - generic_floating_point_number.leader. */ - exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; - - /* Radix 2. */ - exponent_3 = exponent_2 - exponent_skippage; - - /* Forget leading zeros, forget 1st bit. */ - exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); - - /* Offset exponent. */ - lp = words; - - /* Word 1. Sign, exponent and perhaps high bits. */ - word1 = ((generic_floating_point_number.sign == '+') - ? 0 - : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); - - /* Assume 2's complement integers. */ - if (exponent_4 <= 0) - { - int prec_bits; - int num_bits; - - unget_bits (1); - num_bits = -exponent_4; - prec_bits = - LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits); -#ifdef TC_I386 - if (precision == X_PRECISION && exponent_bits == 15) - { - /* On the i386 a denormalized extended precision float is - shifted down by one, effectively decreasing the exponent - bias by one. */ - prec_bits -= 1; - num_bits += 1; - } -#endif - - if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) - { - /* Bigger than one littlenum. */ - num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; - *lp++ = word1; - if (num_bits + exponent_bits + 1 - > precision * LITTLENUM_NUMBER_OF_BITS) - { - /* Exponent overflow. */ - make_invalid_floating_point_number (words); - return return_value; - } -#ifdef TC_M68K - if (precision == X_PRECISION && exponent_bits == 15) - *lp++ = 0; -#endif - while (num_bits >= LITTLENUM_NUMBER_OF_BITS) - { - num_bits -= LITTLENUM_NUMBER_OF_BITS; - *lp++ = 0; - } - if (num_bits) - *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits)); - } - else - { - if (precision == X_PRECISION && exponent_bits == 15) - { - *lp++ = word1; -#ifdef TC_M68K - *lp++ = 0; -#endif - *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits); - } - else - { - word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - - (exponent_bits + num_bits)); - *lp++ = word1; - } - } - while (lp < words_end) - *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); - - /* Round the mantissa up, but don't change the number. */ - if (next_bits (1)) - { - --lp; - if (prec_bits >= LITTLENUM_NUMBER_OF_BITS) - { - int n = 0; - int tmp_bits; - - n = 0; - tmp_bits = prec_bits; - while (tmp_bits > LITTLENUM_NUMBER_OF_BITS) - { - if (lp[n] != (LITTLENUM_TYPE) - 1) - break; - --n; - tmp_bits -= LITTLENUM_NUMBER_OF_BITS; - } - if (tmp_bits > LITTLENUM_NUMBER_OF_BITS - || (lp[n] & mask[tmp_bits]) != mask[tmp_bits] - || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS - - exponent_bits - 1) -#ifdef TC_I386 - /* An extended precision float with only the integer - bit set would be invalid. That must be converted - to the smallest normalized number. */ - && !(precision == X_PRECISION - && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS - - exponent_bits - 2)) -#endif - )) - { - unsigned long carry; - - for (carry = 1; carry && (lp >= words); lp--) - { - carry = *lp + carry; - *lp = carry; - carry >>= LITTLENUM_NUMBER_OF_BITS; - } - } - else - { - /* This is an overflow of the denormal numbers. We - need to forget what we have produced, and instead - generate the smallest normalized number. */ - lp = words; - word1 = ((generic_floating_point_number.sign == '+') - ? 0 - : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); - word1 |= (1 - << ((LITTLENUM_NUMBER_OF_BITS - 1) - - exponent_bits)); - *lp++ = word1; -#ifdef TC_I386 - /* Set the integer bit in the extended precision format. - This cannot happen on the m68k where the mantissa - just overflows into the integer bit above. */ - if (precision == X_PRECISION) - *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1); -#endif - while (lp < words_end) - *lp++ = 0; - } - } - else - *lp += 1; - } - - return return_value; - } - else if ((unsigned long) exponent_4 > mask[exponent_bits] - || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision) - && (unsigned long) exponent_4 == mask[exponent_bits])) - { - /* Exponent overflow. Lose immediately. */ - - /* We leave return_value alone: admit we read the - number, but return a floating exception - because we can't encode the number. */ - make_invalid_floating_point_number (words); - return return_value; - } - else - { - word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits)) - | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits); - } - - *lp++ = word1; - - /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the - middle. Either way, it is then followed by a 1 bit. */ - if (exponent_bits == 15 && precision == X_PRECISION) - { -#ifdef TC_M68K - *lp++ = 0; -#endif - *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1) - | next_bits (LITTLENUM_NUMBER_OF_BITS - 1)); - } - - /* The rest of the words are just mantissa bits. */ - while (lp < words_end) - *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); - - if (next_bits (1)) - { - unsigned long carry; - /* Since the NEXT bit is a 1, round UP the mantissa. - The cunning design of these hidden-1 floats permits - us to let the mantissa overflow into the exponent, and - it 'does the right thing'. However, we lose if the - highest-order bit of the lowest-order word flips. - Is that clear? */ - - /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) - Please allow at least 1 more bit in carry than is in a LITTLENUM. - We need that extra bit to hold a carry during a LITTLENUM carry - propagation. Another extra bit (kept 0) will assure us that we - don't get a sticky sign bit after shifting right, and that - permits us to propagate the carry without any masking of bits. - #endif */ - for (carry = 1, lp--; carry; lp--) - { - carry = *lp + carry; - *lp = carry; - carry >>= LITTLENUM_NUMBER_OF_BITS; - if (lp == words) - break; - } - if (precision == X_PRECISION && exponent_bits == 15) - { - /* Extended precision numbers have an explicit integer bit - that we may have to restore. */ - if (lp == words) - { -#ifdef TC_M68K - /* On the m68k there is a gap of 16 bits. We must - explicitly propagate the carry into the exponent. */ - words[0] += words[1]; - words[1] = 0; - lp++; -#endif - /* Put back the integer bit. */ - lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1); - } - } - if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) - { - /* We leave return_value alone: admit we read the number, - but return a floating exception because we can't encode - the number. */ - *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); - } - } - return return_value; -} - -#ifdef TEST -char * -print_gen (gen) - FLONUM_TYPE *gen; -{ - FLONUM_TYPE f; - LITTLENUM_TYPE arr[10]; - double dv; - float fv; - static char sbuf[40]; - - if (gen) - { - f = generic_floating_point_number; - generic_floating_point_number = *gen; - } - gen_to_words (&arr[0], 4, 11); - memcpy (&dv, &arr[0], sizeof (double)); - sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); - gen_to_words (&arr[0], 2, 8); - memcpy (&fv, &arr[0], sizeof (float)); - sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv); - - if (gen) - generic_floating_point_number = f; - - return (sbuf); -} -#endif - -extern const char FLT_CHARS[]; -#define MAX_LITTLENUMS 6 - -/* This is a utility function called from various tc-*.c files. It - is here in order to reduce code duplication. - - Turn a string at input_line_pointer into a floating point constant - of type TYPE (a character found in the FLT_CHARS macro), and store - it as LITTLENUMS in the bytes buffer LITP. The number of chars - emitted is stored in *SIZEP. BIG_WORDIAN is TRUE if the littlenums - should be emitted most significant littlenum first. - - An error message is returned, or a NULL pointer if everything went OK. */ - -char * -ieee_md_atof (int type, - char *litP, - int *sizeP, - bfd_boolean big_wordian) -{ - LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *wordP; - char *t; - int prec = 0; - - if (strchr (FLT_CHARS, type) != NULL) - { - switch (type) - { - case 'f': - case 'F': - case 's': - case 'S': - prec = F_PRECISION; - break; - - case 'd': - case 'D': - case 'r': - case 'R': - prec = D_PRECISION; - break; - - case 't': - case 'T': - prec = X_PRECISION; - type = 'x'; /* This is what atof_ieee() understands. */ - break; - - case 'x': - case 'X': - case 'p': - case 'P': -#ifdef TC_M68K - /* Note: on the m68k there is a gap of 16 bits (one littlenum) - between the exponent and mantissa. Hence the precision is - 6 and not 5. */ - prec = P_PRECISION + 1; -#else - prec = P_PRECISION; -#endif - break; - - default: - break; - } - } - /* The 'f' and 'd' types are always recognised, even if the target has - not put them into the FLT_CHARS macro. This is because the 'f' type - can come from the .dc.s, .dcb.s, .float or .single pseudo-ops and the - 'd' type from the .dc.d, .dbc.d or .double pseudo-ops. - - The 'x' type is not implicitly recongised however, even though it can - be generated by the .dc.x and .dbc.x pseudo-ops because not all targets - can support floating point values that big. ie the target has to - explicitly allow them by putting them into FLT_CHARS. */ - else if (type == 'f') - prec = F_PRECISION; - else if (type == 'd') - prec = D_PRECISION; - - if (prec == 0) - { - *sizeP = 0; - return _("Unrecognized or unsupported floating point constant"); - } - - gas_assert (prec <= MAX_LITTLENUMS); - - t = atof_ieee (input_line_pointer, type, words); - if (t) - input_line_pointer = t; - - *sizeP = prec * sizeof (LITTLENUM_TYPE); - - if (big_wordian) - { - for (wordP = words; prec --;) - { - md_number_to_chars (litP, (valueT) (* wordP ++), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - } - else - { - for (wordP = words + prec; prec --;) - { - md_number_to_chars (litP, (valueT) (* -- wordP), sizeof (LITTLENUM_TYPE)); - litP += sizeof (LITTLENUM_TYPE); - } - } - - return NULL; -} diff --git a/contrib/binutils-2.22/gas/config/obj-elf.c b/contrib/binutils-2.22/gas/config/obj-elf.c deleted file mode 100644 index 6e16a62629..0000000000 --- a/contrib/binutils-2.22/gas/config/obj-elf.c +++ /dev/null @@ -1,2473 +0,0 @@ -/* ELF object file format - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, - or (at your option) any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#define OBJ_HEADER "obj-elf.h" -#include "as.h" -#include "safe-ctype.h" -#include "subsegs.h" -#include "obstack.h" -#include "struc-symbol.h" -#include "dwarf2dbg.h" - -#ifndef ECOFF_DEBUGGING -#define ECOFF_DEBUGGING 0 -#else -#define NEED_ECOFF_DEBUG -#endif - -#ifdef NEED_ECOFF_DEBUG -#include "ecoff.h" -#endif - -#ifdef TC_ALPHA -#include "elf/alpha.h" -#endif - -#ifdef TC_MIPS -#include "elf/mips.h" -#endif - -#ifdef TC_PPC -#include "elf/ppc.h" -#endif - -#ifdef TC_I370 -#include "elf/i370.h" -#endif - -#ifdef TC_I386 -#include "elf/x86-64.h" -#endif - -#ifdef TC_MEP -#include "elf/mep.h" -#endif - -static void obj_elf_line (int); -static void obj_elf_size (int); -static void obj_elf_type (int); -static void obj_elf_ident (int); -static void obj_elf_weak (int); -static void obj_elf_local (int); -static void obj_elf_visibility (int); -static void obj_elf_symver (int); -static void obj_elf_subsection (int); -static void obj_elf_popsection (int); -static void obj_elf_tls_common (int); -static void obj_elf_lcomm (int); -static void obj_elf_struct (int); - -static const pseudo_typeS elf_pseudo_table[] = -{ - {"comm", obj_elf_common, 0}, - {"common", obj_elf_common, 1}, - {"ident", obj_elf_ident, 0}, - {"lcomm", obj_elf_lcomm, 0}, - {"local", obj_elf_local, 0}, - {"previous", obj_elf_previous, 0}, - {"section", obj_elf_section, 0}, - {"section.s", obj_elf_section, 0}, - {"sect", obj_elf_section, 0}, - {"sect.s", obj_elf_section, 0}, - {"pushsection", obj_elf_section, 1}, - {"popsection", obj_elf_popsection, 0}, - {"size", obj_elf_size, 0}, - {"type", obj_elf_type, 0}, - {"version", obj_elf_version, 0}, - {"weak", obj_elf_weak, 0}, - - /* These define symbol visibility. */ - {"internal", obj_elf_visibility, STV_INTERNAL}, - {"hidden", obj_elf_visibility, STV_HIDDEN}, - {"protected", obj_elf_visibility, STV_PROTECTED}, - - /* These are used for stabs-in-elf configurations. */ - {"line", obj_elf_line, 0}, - - /* This is a GNU extension to handle symbol versions. */ - {"symver", obj_elf_symver, 0}, - - /* A GNU extension to change subsection only. */ - {"subsection", obj_elf_subsection, 0}, - - /* These are GNU extensions to aid in garbage collecting C++ vtables. */ - {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0}, - {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0}, - - /* These are used for dwarf. */ - {"2byte", cons, 2}, - {"4byte", cons, 4}, - {"8byte", cons, 8}, - /* These are used for dwarf2. */ - { "file", (void (*) (int)) dwarf2_directive_file, 0 }, - { "loc", dwarf2_directive_loc, 0 }, - { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 }, - - /* We need to trap the section changing calls to handle .previous. */ - {"data", obj_elf_data, 0}, - {"offset", obj_elf_struct, 0}, - {"struct", obj_elf_struct, 0}, - {"text", obj_elf_text, 0}, - - {"tls_common", obj_elf_tls_common, 0}, - - /* End sentinel. */ - {NULL, NULL, 0}, -}; - -static const pseudo_typeS ecoff_debug_pseudo_table[] = -{ -#ifdef NEED_ECOFF_DEBUG - /* COFF style debugging information for ECOFF. .ln is not used; .loc - is used instead. */ - { "def", ecoff_directive_def, 0 }, - { "dim", ecoff_directive_dim, 0 }, - { "endef", ecoff_directive_endef, 0 }, - { "file", ecoff_directive_file, 0 }, - { "scl", ecoff_directive_scl, 0 }, - { "tag", ecoff_directive_tag, 0 }, - { "val", ecoff_directive_val, 0 }, - - /* COFF debugging requires pseudo-ops .size and .type, but ELF - already has meanings for those. We use .esize and .etype - instead. These are only generated by gcc anyhow. */ - { "esize", ecoff_directive_size, 0 }, - { "etype", ecoff_directive_type, 0 }, - - /* ECOFF specific debugging information. */ - { "begin", ecoff_directive_begin, 0 }, - { "bend", ecoff_directive_bend, 0 }, - { "end", ecoff_directive_end, 0 }, - { "ent", ecoff_directive_ent, 0 }, - { "fmask", ecoff_directive_fmask, 0 }, - { "frame", ecoff_directive_frame, 0 }, - { "loc", ecoff_directive_loc, 0 }, - { "mask", ecoff_directive_mask, 0 }, - - /* Other ECOFF directives. */ - { "extern", ecoff_directive_extern, 0 }, - - /* These are used on Irix. I don't know how to implement them. */ - { "alias", s_ignore, 0 }, - { "bgnb", s_ignore, 0 }, - { "endb", s_ignore, 0 }, - { "lab", s_ignore, 0 }, - { "noalias", s_ignore, 0 }, - { "verstamp", s_ignore, 0 }, - { "vreg", s_ignore, 0 }, -#endif - - {NULL, NULL, 0} /* end sentinel */ -}; - -#undef NO_RELOC -#include "aout/aout64.h" - -/* This is called when the assembler starts. */ - -asection *elf_com_section_ptr; - -void -elf_begin (void) -{ - asection *s; - - /* Add symbols for the known sections to the symbol table. */ - s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME); - symbol_table_insert (section_symbol (s)); - s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME); - symbol_table_insert (section_symbol (s)); - s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME); - symbol_table_insert (section_symbol (s)); - elf_com_section_ptr = bfd_com_section_ptr; -} - -void -elf_pop_insert (void) -{ - pop_insert (elf_pseudo_table); - if (ECOFF_DEBUGGING) - pop_insert (ecoff_debug_pseudo_table); -} - -static bfd_vma -elf_s_get_size (symbolS *sym) -{ - return S_GET_SIZE (sym); -} - -static void -elf_s_set_size (symbolS *sym, bfd_vma sz) -{ - S_SET_SIZE (sym, sz); -} - -static bfd_vma -elf_s_get_align (symbolS *sym) -{ - return S_GET_ALIGN (sym); -} - -static void -elf_s_set_align (symbolS *sym, bfd_vma align) -{ - S_SET_ALIGN (sym, align); -} - -int -elf_s_get_other (symbolS *sym) -{ - return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other; -} - -static void -elf_s_set_other (symbolS *sym, int other) -{ - S_SET_OTHER (sym, other); -} - -static int -elf_sec_sym_ok_for_reloc (asection *sec) -{ - return obj_sec_sym_ok_for_reloc (sec); -} - -void -elf_file_symbol (const char *s, int appfile) -{ - if (!appfile - || symbol_rootP == NULL - || symbol_rootP->bsym == NULL - || (symbol_rootP->bsym->flags & BSF_FILE) == 0) - { - symbolS *sym; - unsigned int name_length; - - sym = symbol_new (s, absolute_section, 0, NULL); - symbol_set_frag (sym, &zero_address_frag); - - name_length = strlen (s); - if (name_length > strlen (S_GET_NAME (sym))) - { - obstack_grow (¬es, s, name_length + 1); - S_SET_NAME (sym, (const char *) obstack_finish (¬es)); - } - else - strcpy ((char *) S_GET_NAME (sym), s); - - symbol_get_bfdsym (sym)->flags |= BSF_FILE; - - if (symbol_rootP != sym) - { - symbol_remove (sym, &symbol_rootP, &symbol_lastP); - symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP); -#ifdef DEBUG - verify_symbol_chain (symbol_rootP, symbol_lastP); -#endif - } - } - -#ifdef NEED_ECOFF_DEBUG - ecoff_new_file (s, appfile); -#endif -} - -/* Called from read.c:s_comm after we've parsed .comm symbol, size. - Parse a possible alignment value. */ - -symbolS * -elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) -{ - addressT align = 0; - int is_local = symbol_get_obj (symbolP)->local; - - if (*input_line_pointer == ',') - { - char *save = input_line_pointer; - - input_line_pointer++; - SKIP_WHITESPACE (); - - if (*input_line_pointer == '"') - { - /* For sparc. Accept .common symbol, length, "bss" */ - input_line_pointer++; - /* Some use the dot, some don't. */ - if (*input_line_pointer == '.') - input_line_pointer++; - /* Some say data, some say bss. */ - if (strncmp (input_line_pointer, "bss\"", 4) == 0) - input_line_pointer += 4; - else if (strncmp (input_line_pointer, "data\"", 5) == 0) - input_line_pointer += 5; - else - { - char *p = input_line_pointer; - char c; - - while (*--p != '"') - ; - while (!is_end_of_line[(unsigned char) *input_line_pointer]) - if (*input_line_pointer++ == '"') - break; - c = *input_line_pointer; - *input_line_pointer = '\0'; - as_bad (_("bad .common segment %s"), p); - *input_line_pointer = c; - ignore_rest_of_line (); - return NULL; - } - /* ??? Don't ask me why these are always global. */ - is_local = 0; - } - else - { - input_line_pointer = save; - align = parse_align (is_local); - if (align == (addressT) -1) - return NULL; - } - } - - if (is_local) - { - bss_alloc (symbolP, size, align); - S_CLEAR_EXTERNAL (symbolP); - } - else - { - S_SET_VALUE (symbolP, size); - S_SET_ALIGN (symbolP, align); - S_SET_EXTERNAL (symbolP); - S_SET_SEGMENT (symbolP, elf_com_section_ptr); - } - - symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; - - return symbolP; -} - -void -obj_elf_common (int is_common) -{ - if (flag_mri && is_common) - s_mri_common (0); - else - s_comm_internal (0, elf_common_parse); -} - -static void -obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED) -{ - symbolS *symbolP = s_comm_internal (0, elf_common_parse); - - if (symbolP) - symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL; -} - -static void -obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED) -{ - symbolS *symbolP = s_comm_internal (0, s_lcomm_internal); - - if (symbolP) - symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; -} - -static symbolS * -get_sym_from_input_line_and_check (void) -{ - char *name; - char c; - symbolS *sym; - - name = input_line_pointer; - c = get_symbol_end (); - sym = symbol_find_or_make (name); - *input_line_pointer = c; - SKIP_WHITESPACE (); - - /* There is no symbol name if input_line_pointer has not moved. */ - if (name == input_line_pointer) - as_bad (_("Missing symbol name in directive")); - return sym; -} - -static void -obj_elf_local (int ignore ATTRIBUTE_UNUSED) -{ - int c; - symbolS *symbolP; - - do - { - symbolP = get_sym_from_input_line_and_check (); - c = *input_line_pointer; - S_CLEAR_EXTERNAL (symbolP); - symbol_get_obj (symbolP)->local = 1; - if (c == ',') - { - input_line_pointer++; - SKIP_WHITESPACE (); - if (*input_line_pointer == '\n') - c = '\n'; - } - } - while (c == ','); - demand_empty_rest_of_line (); -} - -static void -obj_elf_weak (int ignore ATTRIBUTE_UNUSED) -{ - int c; - symbolS *symbolP; - - do - { - symbolP = get_sym_from_input_line_and_check (); - c = *input_line_pointer; - S_SET_WEAK (symbolP); - symbol_get_obj (symbolP)->local = 1; - if (c == ',') - { - input_line_pointer++; - SKIP_WHITESPACE (); - if (*input_line_pointer == '\n') - c = '\n'; - } - } - while (c == ','); - demand_empty_rest_of_line (); -} - -static void -obj_elf_visibility (int visibility) -{ - int c; - symbolS *symbolP; - asymbol *bfdsym; - elf_symbol_type *elfsym; - - do - { - symbolP = get_sym_from_input_line_and_check (); - - bfdsym = symbol_get_bfdsym (symbolP); - elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); - - gas_assert (elfsym); - - elfsym->internal_elf_sym.st_other &= ~3; - elfsym->internal_elf_sym.st_other |= visibility; - - c = *input_line_pointer; - if (c == ',') - { - input_line_pointer ++; - - SKIP_WHITESPACE (); - - if (*input_line_pointer == '\n') - c = '\n'; - } - } - while (c == ','); - - demand_empty_rest_of_line (); -} - -static segT previous_section; -static int previous_subsection; - -struct section_stack -{ - struct section_stack *next; - segT seg, prev_seg; - int subseg, prev_subseg; -}; - -static struct section_stack *section_stack; - -static bfd_boolean -get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) -{ - const char *gname = (const char *) inf; - const char *group_name = elf_group_name (sec); - - return (group_name == gname - || (group_name != NULL - && gname != NULL - && strcmp (group_name, gname) == 0)); -} - -/* Handle the .section pseudo-op. This code supports two different - syntaxes. - - The first is found on Solaris, and looks like - .section ".sec1",#alloc,#execinstr,#write - Here the names after '#' are the SHF_* flags to turn on for the - section. I'm not sure how it determines the SHT_* type (BFD - doesn't really give us control over the type, anyhow). - - The second format is found on UnixWare, and probably most SVR4 - machines, and looks like - .section .sec1,"a",@progbits - The quoted string may contain any combination of a, w, x, and - represents the SHF_* flags to turn on for the section. The string - beginning with '@' can be progbits or nobits. There should be - other possibilities, but I don't know what they are. In any case, - BFD doesn't really let us set the section type. */ - -void -obj_elf_change_section (const char *name, - int type, - bfd_vma attr, - int entsize, - const char *group_name, - int linkonce, - int push) -{ - asection *old_sec; - segT sec; - flagword flags; - const struct elf_backend_data *bed; - const struct bfd_elf_special_section *ssect; - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - /* Switch to the section, creating it if necessary. */ - if (push) - { - struct section_stack *elt; - elt = (struct section_stack *) xmalloc (sizeof (struct section_stack)); - elt->next = section_stack; - elt->seg = now_seg; - elt->prev_seg = previous_section; - elt->subseg = now_subseg; - elt->prev_subseg = previous_subsection; - section_stack = elt; - } - previous_section = now_seg; - previous_subsection = now_subseg; - - old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section, - (void *) group_name); - if (old_sec) - { - sec = old_sec; - subseg_set (sec, 0); - } - else - sec = subseg_force_new (name, 0); - - bed = get_elf_backend_data (stdoutput); - ssect = (*bed->get_sec_type_attr) (stdoutput, sec); - - if (ssect != NULL) - { - bfd_boolean override = FALSE; - - if (type == SHT_NULL) - type = ssect->type; - else if (type != ssect->type) - { - if (old_sec == NULL - /* Some older versions of gcc will emit - - .section .init_array,"aw",@progbits - - for __attribute__ ((section (".init_array"))). - "@progbits" is incorrect. Also for x86-64 large bss - sections, some older versions of gcc will emit - - .section .lbss,"aw",@progbits - - "@progbits" is incorrect. */ -#ifdef TC_I386 - && (bed->s->arch_size != 64 - || !(ssect->attr & SHF_X86_64_LARGE)) -#endif - && ssect->type != SHT_INIT_ARRAY - && ssect->type != SHT_FINI_ARRAY - && ssect->type != SHT_PREINIT_ARRAY) - { - /* We allow to specify any type for a .note section. */ - if (ssect->type != SHT_NOTE) - as_warn (_("setting incorrect section type for %s"), - name); - } - else - { - as_warn (_("ignoring incorrect section type for %s"), - name); - type = ssect->type; - } - } - - if (old_sec == NULL && (attr & ~ssect->attr) != 0) - { - /* As a GNU extension, we permit a .note section to be - allocatable. If the linker sees an allocatable .note - section, it will create a PT_NOTE segment in the output - file. We also allow "x" for .note.GNU-stack. */ - if (ssect->type == SHT_NOTE - && (attr == SHF_ALLOC || attr == SHF_EXECINSTR)) - ; - /* Allow different SHF_MERGE and SHF_STRINGS if we have - something like .rodata.str. */ - else if (ssect->suffix_length == -2 - && name[ssect->prefix_length] == '.' - && (attr - & ~ssect->attr - & ~SHF_MERGE - & ~SHF_STRINGS) == 0) - ; - /* .interp, .strtab and .symtab can have SHF_ALLOC. */ - else if (attr == SHF_ALLOC - && (strcmp (name, ".interp") == 0 - || strcmp (name, ".strtab") == 0 - || strcmp (name, ".symtab") == 0)) - override = TRUE; - /* .note.GNU-stack can have SHF_EXECINSTR. */ - else if (attr == SHF_EXECINSTR - && strcmp (name, ".note.GNU-stack") == 0) - override = TRUE; -#ifdef TC_ALPHA - /* A section on Alpha may have SHF_ALPHA_GPREL. */ - else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL) - override = TRUE; -#endif - else - { - if (group_name == NULL) - as_warn (_("setting incorrect section attributes for %s"), - name); - override = TRUE; - } - } - if (!override && old_sec == NULL) - attr |= ssect->attr; - } - - /* Convert ELF type and flags to BFD flags. */ - flags = (SEC_RELOC - | ((attr & SHF_WRITE) ? 0 : SEC_READONLY) - | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0) - | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0) - | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0) - | ((attr & SHF_MERGE) ? SEC_MERGE : 0) - | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0) - | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0) - | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0)); -#ifdef md_elf_section_flags - flags = md_elf_section_flags (flags, attr, type); -#endif - - if (linkonce) - flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - - if (old_sec == NULL) - { - symbolS *secsym; - - if (type == SHT_NULL) - type = bfd_elf_get_default_section_type (flags); - elf_section_type (sec) = type; - elf_section_flags (sec) = attr; - - /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ - if (type == SHT_NOBITS) - seg_info (sec)->bss = 1; - - bfd_set_section_flags (stdoutput, sec, flags); - if (flags & SEC_MERGE) - sec->entsize = entsize; - elf_group_name (sec) = group_name; - - /* Add a symbol for this section to the symbol table. */ - secsym = symbol_find (name); - if (secsym != NULL) - symbol_set_bfdsym (secsym, sec->symbol); - else - symbol_table_insert (section_symbol (sec)); - } - else - { - if (type != SHT_NULL - && (unsigned) type != elf_section_type (old_sec)) - as_warn (_("ignoring changed section type for %s"), name); - - if (attr != 0) - { - /* If section attributes are specified the second time we see a - particular section, then check that they are the same as we - saw the first time. */ - if (((old_sec->flags ^ flags) - & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE - | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS - | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD - | SEC_THREAD_LOCAL))) - as_warn (_("ignoring changed section attributes for %s"), name); - if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize) - as_warn (_("ignoring changed section entity size for %s"), name); - } - } - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -static bfd_vma -obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *clone) -{ - bfd_vma attr = 0; - *clone = FALSE; - - while (len > 0) - { - switch (*str) - { - case 'a': - attr |= SHF_ALLOC; - break; - case 'e': - attr |= SHF_EXCLUDE; - break; - case 'w': - attr |= SHF_WRITE; - break; - case 'x': - attr |= SHF_EXECINSTR; - break; - case 'M': - attr |= SHF_MERGE; - break; - case 'S': - attr |= SHF_STRINGS; - break; - case 'G': - attr |= SHF_GROUP; - break; - case 'T': - attr |= SHF_TLS; - break; - case '?': - *clone = TRUE; - break; - /* Compatibility. */ - case 'm': - if (*(str - 1) == 'a') - { - attr |= SHF_MERGE; - if (len > 1 && str[1] == 's') - { - attr |= SHF_STRINGS; - str++, len--; - } - break; - } - default: - { - char *bad_msg = _("unrecognized .section attribute: want a,e,w,x,M,S,G,T"); -#ifdef md_elf_section_letter - bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg); - if (md_attr != (bfd_vma) -1) - attr |= md_attr; - else -#endif - as_fatal ("%s", bad_msg); - } - break; - } - str++, len--; - } - - return attr; -} - -static int -obj_elf_section_type (char *str, size_t len, bfd_boolean warn) -{ - if (len == 8 && strncmp (str, "progbits", 8) == 0) - return SHT_PROGBITS; - if (len == 6 && strncmp (str, "nobits", 6) == 0) - return SHT_NOBITS; - if (len == 4 && strncmp (str, "note", 4) == 0) - return SHT_NOTE; - if (len == 10 && strncmp (str, "init_array", 10) == 0) - return SHT_INIT_ARRAY; - if (len == 10 && strncmp (str, "fini_array", 10) == 0) - return SHT_FINI_ARRAY; - if (len == 13 && strncmp (str, "preinit_array", 13) == 0) - return SHT_PREINIT_ARRAY; - -#ifdef md_elf_section_type - { - int md_type = md_elf_section_type (str, len); - if (md_type >= 0) - return md_type; - } -#endif - - if (warn) - as_warn (_("unrecognized section type")); - return 0; -} - -static bfd_vma -obj_elf_section_word (char *str, size_t len, int *type) -{ - int ret; - - if (len == 5 && strncmp (str, "write", 5) == 0) - return SHF_WRITE; - if (len == 5 && strncmp (str, "alloc", 5) == 0) - return SHF_ALLOC; - if (len == 9 && strncmp (str, "execinstr", 9) == 0) - return SHF_EXECINSTR; - if (len == 7 && strncmp (str, "exclude", 7) == 0) - return SHF_EXCLUDE; - if (len == 3 && strncmp (str, "tls", 3) == 0) - return SHF_TLS; - -#ifdef md_elf_section_word - { - bfd_vma md_attr = md_elf_section_word (str, len); - if (md_attr > 0) - return md_attr; - } -#endif - - ret = obj_elf_section_type (str, len, FALSE); - if (ret != 0) - *type = ret; - else - as_warn (_("unrecognized section attribute")); - - return 0; -} - -/* Get name of section. */ -char * -obj_elf_section_name (void) -{ - char *name; - - SKIP_WHITESPACE (); - if (*input_line_pointer == '"') - { - int dummy; - - name = demand_copy_C_string (&dummy); - if (name == NULL) - { - ignore_rest_of_line (); - return NULL; - } - } - else - { - char *end = input_line_pointer; - - while (0 == strchr ("\n\t,; ", *end)) - end++; - if (end == input_line_pointer) - { - as_bad (_("missing name")); - ignore_rest_of_line (); - return NULL; - } - - name = (char *) xmalloc (end - input_line_pointer + 1); - memcpy (name, input_line_pointer, end - input_line_pointer); - name[end - input_line_pointer] = '\0'; -#ifdef tc_canonicalize_section_name - name = tc_canonicalize_section_name (name); -#endif - input_line_pointer = end; - } - SKIP_WHITESPACE (); - return name; -} - -void -obj_elf_section (int push) -{ - char *name, *group_name, *beg; - int type, dummy; - bfd_vma attr; - int entsize; - int linkonce; - subsegT new_subsection = -1; - -#ifndef TC_I370 - if (flag_mri) - { - char mri_type; - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - previous_section = now_seg; - previous_subsection = now_subseg; - - s_mri_sect (&mri_type); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif - - return; - } -#endif /* ! defined (TC_I370) */ - - name = obj_elf_section_name (); - if (name == NULL) - return; - type = SHT_NULL; - attr = 0; - group_name = NULL; - entsize = 0; - linkonce = 0; - - if (*input_line_pointer == ',') - { - /* Skip the comma. */ - ++input_line_pointer; - SKIP_WHITESPACE (); - - if (push && ISDIGIT (*input_line_pointer)) - { - /* .pushsection has an optional subsection. */ - new_subsection = (subsegT) get_absolute_expression (); - - SKIP_WHITESPACE (); - - /* Stop if we don't see a comma. */ - if (*input_line_pointer != ',') - goto done; - - /* Skip the comma. */ - ++input_line_pointer; - SKIP_WHITESPACE (); - } - - if (*input_line_pointer == '"') - { - bfd_boolean clone; - - beg = demand_copy_C_string (&dummy); - if (beg == NULL) - { - ignore_rest_of_line (); - return; - } - attr |= obj_elf_parse_section_letters (beg, strlen (beg), &clone); - - SKIP_WHITESPACE (); - if (*input_line_pointer == ',') - { - char c; - char *save = input_line_pointer; - - ++input_line_pointer; - SKIP_WHITESPACE (); - c = *input_line_pointer; - if (c == '"') - { - beg = demand_copy_C_string (&dummy); - if (beg == NULL) - { - ignore_rest_of_line (); - return; - } - type = obj_elf_section_type (beg, strlen (beg), TRUE); - } - else if (c == '@' || c == '%') - { - beg = ++input_line_pointer; - c = get_symbol_end (); - *input_line_pointer = c; - type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE); - } - else - input_line_pointer = save; - } - - SKIP_WHITESPACE (); - if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',') - { - ++input_line_pointer; - SKIP_WHITESPACE (); - entsize = get_absolute_expression (); - SKIP_WHITESPACE (); - if (entsize < 0) - { - as_warn (_("invalid merge entity size")); - attr &= ~SHF_MERGE; - entsize = 0; - } - } - else if ((attr & SHF_MERGE) != 0) - { - as_warn (_("entity size for SHF_MERGE not specified")); - attr &= ~SHF_MERGE; - } - - if ((attr & SHF_GROUP) != 0 && clone) - { - as_warn (_("? section flag ignored with G present")); - clone = FALSE; - } - if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',') - { - ++input_line_pointer; - group_name = obj_elf_section_name (); - if (group_name == NULL) - attr &= ~SHF_GROUP; - else if (strncmp (input_line_pointer, ",comdat", 7) == 0) - { - input_line_pointer += 7; - linkonce = 1; - } - else if (strncmp (name, ".gnu.linkonce", 13) == 0) - linkonce = 1; - } - else if ((attr & SHF_GROUP) != 0) - { - as_warn (_("group name for SHF_GROUP not specified")); - attr &= ~SHF_GROUP; - } - - if (clone) - { - const char *now_group = elf_group_name (now_seg); - if (now_group != NULL) - { - group_name = xstrdup (now_group); - linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0; - } - } - } - else - { - do - { - char c; - - SKIP_WHITESPACE (); - if (*input_line_pointer != '#') - { - as_bad (_("character following name is not '#'")); - ignore_rest_of_line (); - return; - } - beg = ++input_line_pointer; - c = get_symbol_end (); - *input_line_pointer = c; - - attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type); - - SKIP_WHITESPACE (); - } - while (*input_line_pointer++ == ','); - --input_line_pointer; - } - } - -done: - demand_empty_rest_of_line (); - - obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push); - - if (push && new_subsection != -1) - subseg_set (now_seg, new_subsection); -} - -/* Change to the .data section. */ - -void -obj_elf_data (int i) -{ -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - previous_section = now_seg; - previous_subsection = now_subseg; - s_data (i); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -/* Change to the .text section. */ - -void -obj_elf_text (int i) -{ -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - previous_section = now_seg; - previous_subsection = now_subseg; - s_text (i); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -/* Change to the *ABS* section. */ - -void -obj_elf_struct (int i) -{ -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - previous_section = now_seg; - previous_subsection = now_subseg; - s_struct (i); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -static void -obj_elf_subsection (int ignore ATTRIBUTE_UNUSED) -{ - int temp; - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - previous_section = now_seg; - previous_subsection = now_subseg; - - temp = get_absolute_expression (); - subseg_set (now_seg, (subsegT) temp); - demand_empty_rest_of_line (); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -/* This can be called from the processor backends if they change - sections. */ - -void -obj_elf_section_change_hook (void) -{ - previous_section = now_seg; - previous_subsection = now_subseg; -} - -void -obj_elf_previous (int ignore ATTRIBUTE_UNUSED) -{ - segT new_section; - int new_subsection; - - if (previous_section == 0) - { - as_warn (_(".previous without corresponding .section; ignored")); - return; - } - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - new_section = previous_section; - new_subsection = previous_subsection; - previous_section = now_seg; - previous_subsection = now_subseg; - subseg_set (new_section, new_subsection); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -static void -obj_elf_popsection (int xxx ATTRIBUTE_UNUSED) -{ - struct section_stack *top = section_stack; - - if (top == NULL) - { - as_warn (_(".popsection without corresponding .pushsection; ignored")); - return; - } - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - section_stack = top->next; - previous_section = top->prev_seg; - previous_subsection = top->prev_subseg; - subseg_set (top->seg, top->subseg); - free (top); - -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif -} - -static void -obj_elf_line (int ignore ATTRIBUTE_UNUSED) -{ - /* Assume delimiter is part of expression. BSD4.2 as fails with - delightful bug, so we are not being incompatible here. */ - new_logical_line (NULL, get_absolute_expression ()); - demand_empty_rest_of_line (); -} - -/* This handles the .symver pseudo-op, which is used to specify a - symbol version. The syntax is ``.symver NAME,SYMVERNAME''. - SYMVERNAME may contain ELF_VER_CHR ('@') characters. This - pseudo-op causes the assembler to emit a symbol named SYMVERNAME - with the same value as the symbol NAME. */ - -static void -obj_elf_symver (int ignore ATTRIBUTE_UNUSED) -{ - char *name; - char c; - char old_lexat; - symbolS *sym; - - sym = get_sym_from_input_line_and_check (); - - if (*input_line_pointer != ',') - { - as_bad (_("expected comma after name in .symver")); - ignore_rest_of_line (); - return; - } - - ++input_line_pointer; - SKIP_WHITESPACE (); - name = input_line_pointer; - - /* Temporarily include '@' in symbol names. */ - old_lexat = lex_type[(unsigned char) '@']; - lex_type[(unsigned char) '@'] |= LEX_NAME; - c = get_symbol_end (); - lex_type[(unsigned char) '@'] = old_lexat; - - if (symbol_get_obj (sym)->versioned_name == NULL) - { - symbol_get_obj (sym)->versioned_name = xstrdup (name); - - *input_line_pointer = c; - - if (strchr (symbol_get_obj (sym)->versioned_name, - ELF_VER_CHR) == NULL) - { - as_bad (_("missing version name in `%s' for symbol `%s'"), - symbol_get_obj (sym)->versioned_name, - S_GET_NAME (sym)); - ignore_rest_of_line (); - return; - } - } - else - { - if (strcmp (symbol_get_obj (sym)->versioned_name, name)) - { - as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"), - name, symbol_get_obj (sym)->versioned_name, - S_GET_NAME (sym)); - ignore_rest_of_line (); - return; - } - - *input_line_pointer = c; - } - - demand_empty_rest_of_line (); -} - -/* This handles the .vtable_inherit pseudo-op, which is used to indicate - to the linker the hierarchy in which a particular table resides. The - syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */ - -struct fix * -obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED) -{ - char *cname, *pname; - symbolS *csym, *psym; - char c, bad = 0; - - if (*input_line_pointer == '#') - ++input_line_pointer; - - cname = input_line_pointer; - c = get_symbol_end (); - csym = symbol_find (cname); - - /* GCFIXME: should check that we don't have two .vtable_inherits for - the same child symbol. Also, we can currently only do this if the - child symbol is already exists and is placed in a fragment. */ - - if (csym == NULL || symbol_get_frag (csym) == NULL) - { - as_bad (_("expected `%s' to have already been set for .vtable_inherit"), - cname); - bad = 1; - } - - *input_line_pointer = c; - - SKIP_WHITESPACE (); - if (*input_line_pointer != ',') - { - as_bad (_("expected comma after name in .vtable_inherit")); - ignore_rest_of_line (); - return NULL; - } - - ++input_line_pointer; - SKIP_WHITESPACE (); - - if (*input_line_pointer == '#') - ++input_line_pointer; - - if (input_line_pointer[0] == '0' - && (input_line_pointer[1] == '\0' - || ISSPACE (input_line_pointer[1]))) - { - psym = section_symbol (absolute_section); - ++input_line_pointer; - } - else - { - pname = input_line_pointer; - c = get_symbol_end (); - psym = symbol_find_or_make (pname); - *input_line_pointer = c; - } - - demand_empty_rest_of_line (); - - if (bad) - return NULL; - - gas_assert (symbol_get_value_expression (csym)->X_op == O_constant); - return fix_new (symbol_get_frag (csym), - symbol_get_value_expression (csym)->X_add_number, - 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT); -} - -/* This handles the .vtable_entry pseudo-op, which is used to indicate - to the linker that a vtable slot was used. The syntax is - ".vtable_entry tablename, offset". */ - -struct fix * -obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED) -{ - symbolS *sym; - offsetT offset; - - if (*input_line_pointer == '#') - ++input_line_pointer; - - sym = get_sym_from_input_line_and_check (); - if (*input_line_pointer != ',') - { - as_bad (_("expected comma after name in .vtable_entry")); - ignore_rest_of_line (); - return NULL; - } - - ++input_line_pointer; - if (*input_line_pointer == '#') - ++input_line_pointer; - - offset = get_absolute_expression (); - - demand_empty_rest_of_line (); - - return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0, - BFD_RELOC_VTABLE_ENTRY); -} - -void -elf_obj_read_begin_hook (void) -{ -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - ecoff_read_begin_hook (); -#endif -} - -void -elf_obj_symbol_new_hook (symbolS *symbolP) -{ - struct elf_obj_sy *sy_obj; - - sy_obj = symbol_get_obj (symbolP); - sy_obj->size = NULL; - sy_obj->versioned_name = NULL; - -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - ecoff_symbol_new_hook (symbolP); -#endif -} - -/* When setting one symbol equal to another, by default we probably - want them to have the same "size", whatever it means in the current - context. */ - -void -elf_copy_symbol_attributes (symbolS *dest, symbolS *src) -{ - struct elf_obj_sy *srcelf = symbol_get_obj (src); - struct elf_obj_sy *destelf = symbol_get_obj (dest); - if (srcelf->size) - { - if (destelf->size == NULL) - destelf->size = (expressionS *) xmalloc (sizeof (expressionS)); - *destelf->size = *srcelf->size; - } - else - { - if (destelf->size != NULL) - free (destelf->size); - destelf->size = NULL; - } - S_SET_SIZE (dest, S_GET_SIZE (src)); - /* Don't copy visibility. */ - S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest)) - | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1)))); -} - -void -obj_elf_version (int ignore ATTRIBUTE_UNUSED) -{ - char *name; - unsigned int c; - char *p; - asection *seg = now_seg; - subsegT subseg = now_subseg; - Elf_Internal_Note i_note; - Elf_External_Note e_note; - asection *note_secp = NULL; - - SKIP_WHITESPACE (); - if (*input_line_pointer == '\"') - { - unsigned int len; - - ++input_line_pointer; /* -> 1st char of string. */ - name = input_line_pointer; - - while (is_a_char (c = next_char_of_string ())) - ; - c = *input_line_pointer; - *input_line_pointer = '\0'; - *(input_line_pointer - 1) = '\0'; - *input_line_pointer = c; - - /* Create the .note section. */ - note_secp = subseg_new (".note", 0); - bfd_set_section_flags (stdoutput, - note_secp, - SEC_HAS_CONTENTS | SEC_READONLY); - - /* Process the version string. */ - len = strlen (name) + 1; - - /* PR 3456: Although the name field is padded out to an 4-byte - boundary, the namesz field should not be adjusted. */ - i_note.namesz = len; - i_note.descsz = 0; /* No description. */ - i_note.type = NT_VERSION; - p = frag_more (sizeof (e_note.namesz)); - md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz)); - p = frag_more (sizeof (e_note.descsz)); - md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz)); - p = frag_more (sizeof (e_note.type)); - md_number_to_chars (p, i_note.type, sizeof (e_note.type)); - p = frag_more (len); - memcpy (p, name, len); - - frag_align (2, 0, 0); - - subseg_set (seg, subseg); - } - else - as_bad (_("expected quoted string")); - - demand_empty_rest_of_line (); -} - -static void -obj_elf_size (int ignore ATTRIBUTE_UNUSED) -{ - char *name = input_line_pointer; - char c = get_symbol_end (); - char *p; - expressionS exp; - symbolS *sym; - - p = input_line_pointer; - *p = c; - SKIP_WHITESPACE (); - if (*input_line_pointer != ',') - { - *p = 0; - as_bad (_("expected comma after name `%s' in .size directive"), name); - *p = c; - ignore_rest_of_line (); - return; - } - input_line_pointer++; - expression (&exp); - if (exp.X_op == O_absent) - { - as_bad (_("missing expression in .size directive")); - exp.X_op = O_constant; - exp.X_add_number = 0; - } - *p = 0; - sym = symbol_find_or_make (name); - *p = c; - if (exp.X_op == O_constant) - { - S_SET_SIZE (sym, exp.X_add_number); - if (symbol_get_obj (sym)->size) - { - xfree (symbol_get_obj (sym)->size); - symbol_get_obj (sym)->size = NULL; - } - } - else - { - symbol_get_obj (sym)->size = - (expressionS *) xmalloc (sizeof (expressionS)); - *symbol_get_obj (sym)->size = exp; - } - demand_empty_rest_of_line (); -} - -/* Handle the ELF .type pseudo-op. This sets the type of a symbol. - There are six syntaxes: - - The first (used on Solaris) is - .type SYM,#function - The second (used on UnixWare) is - .type SYM,@function - The third (reportedly to be used on Irix 6.0) is - .type SYM STT_FUNC - The fourth (used on NetBSD/Arm and Linux/ARM) is - .type SYM,%function - The fifth (used on SVR4/860) is - .type SYM,"function" - The sixth (emitted by recent SunPRO under Solaris) is - .type SYM,[0-9] - where the integer is the STT_* value. - */ - -static char * -obj_elf_type_name (char *cp) -{ - char *p; - - p = input_line_pointer; - if (*input_line_pointer >= '0' - && *input_line_pointer <= '9') - { - while (*input_line_pointer >= '0' - && *input_line_pointer <= '9') - ++input_line_pointer; - *cp = *input_line_pointer; - *input_line_pointer = '\0'; - } - else - *cp = get_symbol_end (); - - return p; -} - -static void -obj_elf_type (int ignore ATTRIBUTE_UNUSED) -{ - char c; - int type; - const char *type_name; - symbolS *sym; - elf_symbol_type *elfsym; - - sym = get_sym_from_input_line_and_check (); - c = *input_line_pointer; - elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym); - - if (*input_line_pointer == ',') - ++input_line_pointer; - - SKIP_WHITESPACE (); - if ( *input_line_pointer == '#' - || *input_line_pointer == '@' - || *input_line_pointer == '"' - || *input_line_pointer == '%') - ++input_line_pointer; - - type_name = obj_elf_type_name (& c); - - type = 0; - if (strcmp (type_name, "function") == 0 - || strcmp (type_name, "2") == 0 - || strcmp (type_name, "STT_FUNC") == 0) - type = BSF_FUNCTION; - else if (strcmp (type_name, "object") == 0 - || strcmp (type_name, "1") == 0 - || strcmp (type_name, "STT_OBJECT") == 0) - type = BSF_OBJECT; - else if (strcmp (type_name, "tls_object") == 0 - || strcmp (type_name, "6") == 0 - || strcmp (type_name, "STT_TLS") == 0) - type = BSF_OBJECT | BSF_THREAD_LOCAL; - else if (strcmp (type_name, "notype") == 0 - || strcmp (type_name, "0") == 0 - || strcmp (type_name, "STT_NOTYPE") == 0) - ; - else if (strcmp (type_name, "common") == 0 - || strcmp (type_name, "5") == 0 - || strcmp (type_name, "STT_COMMON") == 0) - { - type = BSF_OBJECT; - - if (! S_IS_COMMON (sym)) - { - if (S_IS_VOLATILE (sym)) - { - sym = symbol_clone (sym, 1); - S_SET_SEGMENT (sym, bfd_com_section_ptr); - S_SET_VALUE (sym, 0); - S_SET_EXTERNAL (sym); - symbol_set_frag (sym, &zero_address_frag); - S_CLEAR_VOLATILE (sym); - } - else if (S_IS_DEFINED (sym) || symbol_equated_p (sym)) - as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym)); - else - { - /* FIXME: Is it safe to just change the section ? */ - S_SET_SEGMENT (sym, bfd_com_section_ptr); - S_SET_VALUE (sym, 0); - S_SET_EXTERNAL (sym); - } - } - } - else if (strcmp (type_name, "gnu_indirect_function") == 0 - || strcmp (type_name, "10") == 0 - || strcmp (type_name, "STT_GNU_IFUNC") == 0) - { - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (stdoutput); - if (!(bed->elf_osabi == ELFOSABI_GNU - /* GNU is still using the default value 0. */ - || bed->elf_osabi == ELFOSABI_NONE)) - as_bad (_("symbol type \"%s\" is supported only by GNU targets"), - type_name); - type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION; - } - else if (strcmp (type_name, "gnu_unique_object") == 0) - { - struct elf_backend_data *bed; - - bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput); - if (!(bed->elf_osabi == ELFOSABI_GNU - /* GNU is still using the default value 0. */ - || bed->elf_osabi == ELFOSABI_NONE)) - as_bad (_("symbol type \"%s\" is supported only by GNU targets"), - type_name); - type = BSF_OBJECT | BSF_GNU_UNIQUE; - /* PR 10549: Always set OSABI field to GNU for objects containing unique symbols. */ - bed->elf_osabi = ELFOSABI_GNU; - } -#ifdef md_elf_symbol_type - else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1) - ; -#endif - else - as_bad (_("unrecognized symbol type \"%s\""), type_name); - - *input_line_pointer = c; - - if (*input_line_pointer == '"') - ++input_line_pointer; - - elfsym->symbol.flags |= type; - - demand_empty_rest_of_line (); -} - -static void -obj_elf_ident (int ignore ATTRIBUTE_UNUSED) -{ - static segT comment_section; - segT old_section = now_seg; - int old_subsection = now_subseg; - -#ifdef md_flush_pending_output - md_flush_pending_output (); -#endif - - if (!comment_section) - { - char *p; - comment_section = subseg_new (".comment", 0); - bfd_set_section_flags (stdoutput, comment_section, - SEC_READONLY | SEC_HAS_CONTENTS - | SEC_MERGE | SEC_STRINGS); - comment_section->entsize = 1; -#ifdef md_elf_section_change_hook - md_elf_section_change_hook (); -#endif - p = frag_more (1); - *p = 0; - } - else - subseg_set (comment_section, 0); - stringer (8 + 1); - subseg_set (old_section, old_subsection); -} - -#ifdef INIT_STAB_SECTION - -/* The first entry in a .stabs section is special. */ - -void -obj_elf_init_stab_section (segT seg) -{ - char *file; - char *p; - char *stabstr_name; - unsigned int stroff; - - /* Force the section to align to a longword boundary. Without this, - UnixWare ar crashes. */ - bfd_set_section_alignment (stdoutput, seg, 2); - - /* Make space for this first symbol. */ - p = frag_more (12); - /* Zero it out. */ - memset (p, 0, 12); - as_where (&file, NULL); - stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4); - strcpy (stabstr_name, segment_name (seg)); - strcat (stabstr_name, "str"); - stroff = get_stab_string_offset (file, stabstr_name); - know (stroff == 1 || (stroff == 0 && file[0] == '\0')); - md_number_to_chars (p, stroff, 4); - seg_info (seg)->stabu.p = p; -} - -#endif - -/* Fill in the counts in the first entry in a .stabs section. */ - -static void -adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) -{ - char *name; - asection *strsec; - char *p; - int strsz, nsyms; - - if (strncmp (".stab", sec->name, 5)) - return; - if (!strcmp ("str", sec->name + strlen (sec->name) - 3)) - return; - - name = (char *) alloca (strlen (sec->name) + 4); - strcpy (name, sec->name); - strcat (name, "str"); - strsec = bfd_get_section_by_name (abfd, name); - if (strsec) - strsz = bfd_section_size (abfd, strsec); - else - strsz = 0; - nsyms = bfd_section_size (abfd, sec) / 12 - 1; - - p = seg_info (sec)->stabu.p; - gas_assert (p != 0); - - bfd_h_put_16 (abfd, nsyms, p + 6); - bfd_h_put_32 (abfd, strsz, p + 8); -} - -#ifdef NEED_ECOFF_DEBUG - -/* This function is called by the ECOFF code. It is supposed to - record the external symbol information so that the backend can - write it out correctly. The ELF backend doesn't actually handle - this at the moment, so we do it ourselves. We save the information - in the symbol. */ - -#ifdef OBJ_MAYBE_ELF -static -#endif -void -elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext) -{ - symbol_get_bfdsym (sym)->udata.p = ext; -} - -/* This function is called by bfd_ecoff_debug_externals. It is - supposed to *EXT to the external symbol information, and return - whether the symbol should be used at all. */ - -static bfd_boolean -elf_get_extr (asymbol *sym, EXTR *ext) -{ - if (sym->udata.p == NULL) - return FALSE; - *ext = *(EXTR *) sym->udata.p; - return TRUE; -} - -/* This function is called by bfd_ecoff_debug_externals. It has - nothing to do for ELF. */ - -static void -elf_set_index (asymbol *sym ATTRIBUTE_UNUSED, - bfd_size_type indx ATTRIBUTE_UNUSED) -{ -} - -#endif /* NEED_ECOFF_DEBUG */ - -void -elf_frob_symbol (symbolS *symp, int *puntp) -{ - struct elf_obj_sy *sy_obj; - expressionS *size; - -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - ecoff_frob_symbol (symp); -#endif - - sy_obj = symbol_get_obj (symp); - - size = sy_obj->size; - if (size != NULL) - { - if (resolve_expression (size) - && size->X_op == O_constant) - S_SET_SIZE (symp, size->X_add_number); - else - { - if (flag_size_check == size_check_error) - as_bad (_(".size expression for %s " - "does not evaluate to a constant"), S_GET_NAME (symp)); - else - as_warn (_(".size expression for %s " - "does not evaluate to a constant"), S_GET_NAME (symp)); - } - free (sy_obj->size); - sy_obj->size = NULL; - } - - if (sy_obj->versioned_name != NULL) - { - char *p; - - p = strchr (sy_obj->versioned_name, ELF_VER_CHR); - know (p != NULL); - - /* This symbol was given a new name with the .symver directive. - - If this is an external reference, just rename the symbol to - include the version string. This will make the relocs be - against the correct versioned symbol. - - If this is a definition, add an alias. FIXME: Using an alias - will permit the debugging information to refer to the right - symbol. However, it's not clear whether it is the best - approach. */ - - if (! S_IS_DEFINED (symp)) - { - /* Verify that the name isn't using the @@ syntax--this is - reserved for definitions of the default version to link - against. */ - if (p[1] == ELF_VER_CHR) - { - as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"), - sy_obj->versioned_name); - *puntp = TRUE; - } - S_SET_NAME (symp, sy_obj->versioned_name); - } - else - { - if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR) - { - size_t l; - - /* The @@@ syntax is a special case. It renames the - symbol name to versioned_name with one `@' removed. */ - l = strlen (&p[3]) + 1; - memmove (&p[2], &p[3], l); - S_SET_NAME (symp, sy_obj->versioned_name); - } - else - { - symbolS *symp2; - - /* FIXME: Creating a new symbol here is risky. We're - in the final loop over the symbol table. We can - get away with it only because the symbol goes to - the end of the list, where the loop will still see - it. It would probably be better to do this in - obj_frob_file_before_adjust. */ - - symp2 = symbol_find_or_make (sy_obj->versioned_name); - - /* Now we act as though we saw symp2 = sym. */ - - S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp)); - - /* Subtracting out the frag address here is a hack - because we are in the middle of the final loop. */ - S_SET_VALUE (symp2, - (S_GET_VALUE (symp) - - symbol_get_frag (symp)->fr_address)); - - symbol_set_frag (symp2, symbol_get_frag (symp)); - - /* This will copy over the size information. */ - copy_symbol_attributes (symp2, symp); - - S_SET_OTHER (symp2, S_GET_OTHER (symp)); - - if (S_IS_WEAK (symp)) - S_SET_WEAK (symp2); - - if (S_IS_EXTERNAL (symp)) - S_SET_EXTERNAL (symp2); - } - } - } - - /* Double check weak symbols. */ - if (S_IS_WEAK (symp)) - { - if (S_IS_COMMON (symp)) - as_bad (_("symbol `%s' can not be both weak and common"), - S_GET_NAME (symp)); - } - -#ifdef TC_MIPS - /* The Irix 5 and 6 assemblers set the type of any common symbol and - any undefined non-function symbol to STT_OBJECT. We try to be - compatible, since newer Irix 5 and 6 linkers care. However, we - only set undefined symbols to be STT_OBJECT if we are on Irix, - because that is the only time gcc will generate the necessary - .global directives to mark functions. */ - - if (S_IS_COMMON (symp)) - symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; - - if (strstr (TARGET_OS, "irix") != NULL - && ! S_IS_DEFINED (symp) - && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0) - symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; -#endif -} - -struct group_list -{ - asection **head; /* Section lists. */ - unsigned int *elt_count; /* Number of sections in each list. */ - unsigned int num_group; /* Number of lists. */ - struct hash_control *indexes; /* Maps group name to index in head array. */ -}; - -/* Called via bfd_map_over_sections. If SEC is a member of a group, - add it to a list of sections belonging to the group. INF is a - pointer to a struct group_list, which is where we store the head of - each list. */ - -static void -build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) -{ - struct group_list *list = (struct group_list *) inf; - const char *group_name = elf_group_name (sec); - unsigned int i; - unsigned int *elem_idx; - unsigned int *idx_ptr; - - if (group_name == NULL) - return; - - /* If this group already has a list, add the section to the head of - the list. */ - elem_idx = (unsigned int *) hash_find (list->indexes, group_name); - if (elem_idx != NULL) - { - elf_next_in_group (sec) = list->head[*elem_idx]; - list->head[*elem_idx] = sec; - list->elt_count[*elem_idx] += 1; - return; - } - - /* New group. Make the arrays bigger in chunks to minimize calls to - realloc. */ - i = list->num_group; - if ((i & 127) == 0) - { - unsigned int newsize = i + 128; - list->head = (asection **) xrealloc (list->head, - newsize * sizeof (*list->head)); - list->elt_count = (unsigned int *) - xrealloc (list->elt_count, newsize * sizeof (*list->elt_count)); - } - list->head[i] = sec; - list->elt_count[i] = 1; - list->num_group += 1; - - /* Add index to hash. */ - idx_ptr = (unsigned int *) xmalloc (sizeof (unsigned int)); - *idx_ptr = i; - hash_insert (list->indexes, group_name, idx_ptr); -} - -static void free_section_idx (const char *key ATTRIBUTE_UNUSED, void *val) -{ - free ((unsigned int *) val); -} - -void -elf_adjust_symtab (void) -{ - struct group_list list; - unsigned int i; - - /* Go find section groups. */ - list.num_group = 0; - list.head = NULL; - list.elt_count = NULL; - list.indexes = hash_new (); - bfd_map_over_sections (stdoutput, build_group_lists, &list); - - /* Make the SHT_GROUP sections that describe each section group. We - can't set up the section contents here yet, because elf section - indices have yet to be calculated. elf.c:set_group_contents does - the rest of the work. */ - for (i = 0; i < list.num_group; i++) - { - const char *group_name = elf_group_name (list.head[i]); - const char *sec_name; - asection *s; - flagword flags; - struct symbol *sy; - bfd_size_type size; - - flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP; - for (s = list.head[i]; s != NULL; s = elf_next_in_group (s)) - if ((s->flags ^ flags) & SEC_LINK_ONCE) - { - flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; - if (s != list.head[i]) - { - as_warn (_("assuming all members of group `%s' are COMDAT"), - group_name); - break; - } - } - - sec_name = ".group"; - s = subseg_force_new (sec_name, 0); - if (s == NULL - || !bfd_set_section_flags (stdoutput, s, flags) - || !bfd_set_section_alignment (stdoutput, s, 2)) - { - as_fatal (_("can't create group: %s"), - bfd_errmsg (bfd_get_error ())); - } - elf_section_type (s) = SHT_GROUP; - - /* Pass a pointer to the first section in this group. */ - elf_next_in_group (s) = list.head[i]; - /* Make sure that the signature symbol for the group has the - name of the group. */ - sy = symbol_find_exact (group_name); - if (!sy - || (sy != symbol_lastP - && (sy->sy_next == NULL - || sy->sy_next->sy_previous != sy))) - { - /* Create the symbol now. */ - sy = symbol_new (group_name, now_seg, (valueT) 0, frag_now); -#ifdef TE_SOLARIS - /* Before Solaris 11 build 154, Sun ld rejects local group - signature symbols, so make them weak hidden instead. */ - symbol_get_bfdsym (sy)->flags |= BSF_WEAK; - S_SET_OTHER (sy, STV_HIDDEN); -#else - symbol_get_obj (sy)->local = 1; -#endif - symbol_table_insert (sy); - } - elf_group_id (s) = symbol_get_bfdsym (sy); - - size = 4 * (list.elt_count[i] + 1); - bfd_set_section_size (stdoutput, s, size); - s->contents = (unsigned char *) frag_more (size); - frag_now->fr_fix = frag_now_fix_octets (); - frag_wane (frag_now); - } - - /* Cleanup hash. */ - hash_traverse (list.indexes, free_section_idx); - hash_die (list.indexes); -} - -void -elf_frob_file (void) -{ - bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL); - -#ifdef elf_tc_final_processing - elf_tc_final_processing (); -#endif -} - -/* It removes any unneeded versioned symbols from the symbol table. */ - -void -elf_frob_file_before_adjust (void) -{ - if (symbol_rootP) - { - symbolS *symp; - - for (symp = symbol_rootP; symp; symp = symbol_next (symp)) - if (!S_IS_DEFINED (symp)) - { - if (symbol_get_obj (symp)->versioned_name) - { - char *p; - - /* The @@@ syntax is a special case. If the symbol is - not defined, 2 `@'s will be removed from the - versioned_name. */ - - p = strchr (symbol_get_obj (symp)->versioned_name, - ELF_VER_CHR); - know (p != NULL); - if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR) - { - size_t l = strlen (&p[3]) + 1; - memmove (&p[1], &p[3], l); - } - if (symbol_used_p (symp) == 0 - && symbol_used_in_reloc_p (symp) == 0) - symbol_remove (symp, &symbol_rootP, &symbol_lastP); - } - - /* If there was .weak foo, but foo was neither defined nor - used anywhere, remove it. */ - - else if (S_IS_WEAK (symp) - && symbol_used_p (symp) == 0 - && symbol_used_in_reloc_p (symp) == 0) - symbol_remove (symp, &symbol_rootP, &symbol_lastP); - } - } -} - -/* It is required that we let write_relocs have the opportunity to - optimize away fixups before output has begun, since it is possible - to eliminate all fixups for a section and thus we never should - have generated the relocation section. */ - -void -elf_frob_file_after_relocs (void) -{ -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - /* Generate the ECOFF debugging information. */ - { - const struct ecoff_debug_swap *debug_swap; - struct ecoff_debug_info debug; - char *buf; - asection *sec; - - debug_swap - = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap; - know (debug_swap != NULL); - ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap); - - /* Set up the pointers in debug. */ -#define SET(ptr, offset, type) \ - debug.ptr = (type) (buf + debug.symbolic_header.offset) - - SET (line, cbLineOffset, unsigned char *); - SET (external_dnr, cbDnOffset, void *); - SET (external_pdr, cbPdOffset, void *); - SET (external_sym, cbSymOffset, void *); - SET (external_opt, cbOptOffset, void *); - SET (external_aux, cbAuxOffset, union aux_ext *); - SET (ss, cbSsOffset, char *); - SET (external_fdr, cbFdOffset, void *); - SET (external_rfd, cbRfdOffset, void *); - /* ssext and external_ext are set up just below. */ - -#undef SET - - /* Set up the external symbols. */ - debug.ssext = debug.ssext_end = NULL; - debug.external_ext = debug.external_ext_end = NULL; - if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, TRUE, - elf_get_extr, elf_set_index)) - as_fatal (_("failed to set up debugging information: %s"), - bfd_errmsg (bfd_get_error ())); - - sec = bfd_get_section_by_name (stdoutput, ".mdebug"); - gas_assert (sec != NULL); - - know (!stdoutput->output_has_begun); - - /* We set the size of the section, call bfd_set_section_contents - to force the ELF backend to allocate a file position, and then - write out the data. FIXME: Is this really the best way to do - this? */ - bfd_set_section_size - (stdoutput, sec, bfd_ecoff_debug_size (stdoutput, &debug, debug_swap)); - - /* Pass BUF to bfd_set_section_contents because this will - eventually become a call to fwrite, and ISO C prohibits - passing a NULL pointer to a stdio function even if the - pointer will not be used. */ - if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0)) - as_fatal (_("can't start writing .mdebug section: %s"), - bfd_errmsg (bfd_get_error ())); - - know (stdoutput->output_has_begun); - know (sec->filepos != 0); - - if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap, - sec->filepos)) - as_fatal (_("could not write .mdebug section: %s"), - bfd_errmsg (bfd_get_error ())); - } -#endif /* NEED_ECOFF_DEBUG */ -} - -#ifdef SCO_ELF - -/* Heavily plagiarized from obj_elf_version. The idea is to emit the - SCO specific identifier in the .notes section to satisfy the SCO - linker. - - This looks more complicated than it really is. As opposed to the - "obvious" solution, this should handle the cross dev cases - correctly. (i.e, hosting on a 64 bit big endian processor, but - generating SCO Elf code) Efficiency isn't a concern, as there - should be exactly one of these sections per object module. - - SCO OpenServer 5 identifies it's ELF modules with a standard ELF - .note section. - - int_32 namesz = 4 ; Name size - int_32 descsz = 12 ; Descriptive information - int_32 type = 1 ; - char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL - int_32 version = (major ver # << 16) | version of tools ; - int_32 source = (tool_id << 16 ) | 1 ; - int_32 info = 0 ; These are set by the SCO tools, but we - don't know enough about the source - environment to set them. SCO ld currently - ignores them, and recommends we set them - to zero. */ - -#define SCO_MAJOR_VERSION 0x1 -#define SCO_MINOR_VERSION 0x1 - -void -sco_id (void) -{ - - char *name; - unsigned int c; - char ch; - char *p; - asection *seg = now_seg; - subsegT subseg = now_subseg; - Elf_Internal_Note i_note; - Elf_External_Note e_note; - asection *note_secp = NULL; - int i, len; - - /* create the .note section */ - - note_secp = subseg_new (".note", 0); - bfd_set_section_flags (stdoutput, - note_secp, - SEC_HAS_CONTENTS | SEC_READONLY); - - /* process the version string */ - - i_note.namesz = 4; - i_note.descsz = 12; /* 12 descriptive bytes */ - i_note.type = NT_VERSION; /* Contains a version string */ - - p = frag_more (sizeof (i_note.namesz)); - md_number_to_chars (p, i_note.namesz, 4); - - p = frag_more (sizeof (i_note.descsz)); - md_number_to_chars (p, i_note.descsz, 4); - - p = frag_more (sizeof (i_note.type)); - md_number_to_chars (p, i_note.type, 4); - - p = frag_more (4); - strcpy (p, "SCO"); - - /* Note: this is the version number of the ELF we're representing */ - p = frag_more (4); - md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4); - - /* Here, we pick a magic number for ourselves (yes, I "registered" - it with SCO. The bottom bit shows that we are compat with the - SCO ABI. */ - p = frag_more (4); - md_number_to_chars (p, 0x4c520000 | 0x0001, 4); - - /* If we knew (or cared) what the source language options were, we'd - fill them in here. SCO has given us permission to ignore these - and just set them to zero. */ - p = frag_more (4); - md_number_to_chars (p, 0x0000, 4); - - frag_align (2, 0, 0); - - /* We probably can't restore the current segment, for there likely - isn't one yet... */ - if (seg && subseg) - subseg_set (seg, subseg); - -} - -#endif /* SCO_ELF */ - -static void -elf_generate_asm_lineno (void) -{ -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - ecoff_generate_asm_lineno (); -#endif -} - -static void -elf_process_stab (segT sec ATTRIBUTE_UNUSED, - int what ATTRIBUTE_UNUSED, - const char *string ATTRIBUTE_UNUSED, - int type ATTRIBUTE_UNUSED, - int other ATTRIBUTE_UNUSED, - int desc ATTRIBUTE_UNUSED) -{ -#ifdef NEED_ECOFF_DEBUG - if (ECOFF_DEBUGGING) - ecoff_stab (sec, what, string, type, other, desc); -#endif -} - -static int -elf_separate_stab_sections (void) -{ -#ifdef NEED_ECOFF_DEBUG - return (!ECOFF_DEBUGGING); -#else - return 1; -#endif -} - -static void -elf_init_stab_section (segT seg) -{ -#ifdef NEED_ECOFF_DEBUG - if (!ECOFF_DEBUGGING) -#endif - obj_elf_init_stab_section (seg); -} - -const struct format_ops elf_format_ops = -{ - bfd_target_elf_flavour, - 0, /* dfl_leading_underscore */ - 1, /* emit_section_symbols */ - elf_begin, - elf_file_symbol, - elf_frob_symbol, - elf_frob_file, - elf_frob_file_before_adjust, - 0, /* obj_frob_file_before_fix */ - elf_frob_file_after_relocs, - elf_s_get_size, elf_s_set_size, - elf_s_get_align, elf_s_set_align, - elf_s_get_other, - elf_s_set_other, - 0, /* s_get_desc */ - 0, /* s_set_desc */ - 0, /* s_get_type */ - 0, /* s_set_type */ - elf_copy_symbol_attributes, - elf_generate_asm_lineno, - elf_process_stab, - elf_separate_stab_sections, - elf_init_stab_section, - elf_sec_sym_ok_for_reloc, - elf_pop_insert, -#ifdef NEED_ECOFF_DEBUG - elf_ecoff_set_ext, -#else - 0, /* ecoff_set_ext */ -#endif - elf_obj_read_begin_hook, - elf_obj_symbol_new_hook, - 0, - elf_adjust_symtab -}; diff --git a/contrib/binutils-2.22/gas/config/obj-elf.h b/contrib/binutils-2.22/gas/config/obj-elf.h deleted file mode 100644 index 0721654c04..0000000000 --- a/contrib/binutils-2.22/gas/config/obj-elf.h +++ /dev/null @@ -1,251 +0,0 @@ -/* ELF object file format. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* HP PA-RISC support was contributed by the Center for Software Science - at the University of Utah. */ - -#ifndef _OBJ_ELF_H -#define _OBJ_ELF_H - -#define OBJ_ELF 1 - -/* Note that all macros in this file should be wrapped in #ifndef, for - sake of obj-multi.h which includes this file. */ - -#ifndef OUTPUT_FLAVOR -#define OUTPUT_FLAVOR bfd_target_elf_flavour -#endif - -#define BYTES_IN_WORD 4 /* for now */ -#include "bfd/elf-bfd.h" - -#include "targ-cpu.h" - -#ifdef TC_ALPHA -#define ECOFF_DEBUGGING (alpha_flag_mdebug > 0) -extern int alpha_flag_mdebug; -#endif - -/* For now, always set ECOFF_DEBUGGING for a MIPS target. */ -#ifdef TC_MIPS -#define ECOFF_DEBUGGING mips_flag_mdebug -extern int mips_flag_mdebug; -#endif /* TC_MIPS */ - -#ifdef OBJ_MAYBE_ECOFF -#ifndef ECOFF_DEBUGGING -#define ECOFF_DEBUGGING 1 -#endif -#endif - -/* Additional information we keep for each symbol. */ -struct elf_obj_sy -{ - /* Whether the symbol has been marked as local. */ - int local; - - /* Use this to keep track of .size expressions that involve - differences that we can't compute yet. */ - expressionS *size; - - /* The name specified by the .symver directive. */ - char *versioned_name; - -#ifdef ECOFF_DEBUGGING - /* If we are generating ECOFF debugging information, we need some - additional fields for each symbol. */ - struct efdr *ecoff_file; - struct localsym *ecoff_symbol; - valueT ecoff_extern_size; -#endif -}; - -#define OBJ_SYMFIELD_TYPE struct elf_obj_sy - -#ifndef FALSE -#define FALSE 0 -#define TRUE !FALSE -#endif - -#ifndef obj_begin -#define obj_begin() elf_begin () -#endif -extern void elf_begin (void); - -#ifndef LOCAL_LABEL_PREFIX -#define LOCAL_LABEL_PREFIX '.' -#endif - -/* should be conditional on address size! */ -#define elf_symbol(asymbol) ((elf_symbol_type *) (&(asymbol)->the_bfd)) - -#ifndef S_GET_SIZE -#define S_GET_SIZE(S) \ - (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size) -#endif -#ifndef S_SET_SIZE -#define S_SET_SIZE(S,V) \ - (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_size = (V)) -#endif - -#ifndef S_GET_ALIGN -#define S_GET_ALIGN(S) \ - (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value) -#endif -#ifndef S_SET_ALIGN -#define S_SET_ALIGN(S,V) \ - (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_value = (V)) -#endif - -int elf_s_get_other (symbolS *); -#ifndef S_GET_OTHER -#define S_GET_OTHER(S) (elf_s_get_other (S)) -#endif -#ifndef S_SET_OTHER -#define S_SET_OTHER(S,V) \ - (elf_symbol (symbol_get_bfdsym (S))->internal_elf_sym.st_other = (V)) -#endif - -extern asection *gdb_section; - -#ifndef obj_frob_file -#define obj_frob_file elf_frob_file -#endif -extern void elf_frob_file (void); - -#ifndef obj_frob_file_before_adjust -#define obj_frob_file_before_adjust elf_frob_file_before_adjust -#endif -extern void elf_frob_file_before_adjust (void); - -#ifndef obj_frob_file_after_relocs -#define obj_frob_file_after_relocs elf_frob_file_after_relocs -#endif -extern void elf_frob_file_after_relocs (void); - -/* If the target doesn't have special processing for labels, take care of - dwarf2 output at the object file level. */ -#ifndef tc_frob_label -#include "dwarf2dbg.h" -#define obj_frob_label dwarf2_emit_label -#endif - -#ifndef obj_app_file -#define obj_app_file elf_file_symbol -#endif -extern void elf_file_symbol (const char *, int); - -extern void obj_elf_section_change_hook (void); - -extern void obj_elf_section (int); -extern char * obj_elf_section_name (void); -extern void obj_elf_previous (int); -extern void obj_elf_version (int); -extern void obj_elf_common (int); -extern void obj_elf_data (int); -extern void obj_elf_text (int); -extern void obj_elf_change_section - (const char *, int, bfd_vma, int, const char *, int, int); -extern struct fix *obj_elf_vtable_inherit (int); -extern struct fix *obj_elf_vtable_entry (int); - -/* BFD wants to write the udata field, which is a no-no for the - predefined section symbols in bfd/section.c. They are read-only. */ -#ifndef obj_sec_sym_ok_for_reloc -#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0) -#endif - -void elf_obj_read_begin_hook (void); -#ifndef obj_read_begin_hook -#define obj_read_begin_hook elf_obj_read_begin_hook -#endif - -void elf_obj_symbol_new_hook (symbolS *); -#ifndef obj_symbol_new_hook -#define obj_symbol_new_hook elf_obj_symbol_new_hook -#endif - -void elf_copy_symbol_attributes (symbolS *, symbolS *); -#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES -#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \ - (elf_copy_symbol_attributes (DEST, SRC)) -#endif - -void elf_adjust_symtab (void); -#ifndef obj_adjust_symtab -#define obj_adjust_symtab elf_adjust_symtab -#endif - -#ifndef SEPARATE_STAB_SECTIONS -/* Avoid ifndef each separate macro setting by wrapping the whole of the - stab group on the assumption that whoever sets SEPARATE_STAB_SECTIONS - caters to ECOFF_DEBUGGING and the right setting of INIT_STAB_SECTIONS - and OBJ_PROCESS_STAB too, without needing the tweaks below. */ - -/* Stabs go in a separate section. */ -#define SEPARATE_STAB_SECTIONS 1 - -/* We need 12 bytes at the start of the section to hold some initial - information. */ -extern void obj_elf_init_stab_section (segT); -#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg) - -#ifdef ECOFF_DEBUGGING -/* We smuggle stabs in ECOFF rather than using a separate section. - The Irix linker can not handle a separate stabs section. */ - -#undef SEPARATE_STAB_SECTIONS -#define SEPARATE_STAB_SECTIONS (!ECOFF_DEBUGGING) - -#undef INIT_STAB_SECTION -#define INIT_STAB_SECTION(seg) \ - ((void) (ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (seg), 0))) - -#undef OBJ_PROCESS_STAB -#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \ - if (ECOFF_DEBUGGING) \ - ecoff_stab ((seg), (what), (string), (type), (other), (desc)) -#endif /* ECOFF_DEBUGGING */ - -#endif /* SEPARATE_STAB_SECTIONS not defined. */ - -extern void elf_frob_symbol (symbolS *, int *); -#ifndef obj_frob_symbol -#define obj_frob_symbol(symp, punt) elf_frob_symbol (symp, &punt) -#endif - -extern void elf_pop_insert (void); -#ifndef obj_pop_insert -#define obj_pop_insert() elf_pop_insert() -#endif - -#ifndef OBJ_MAYBE_ELF -/* If OBJ_MAYBE_ELF then obj-multi.h will define obj_ecoff_set_ext. */ -#define obj_ecoff_set_ext elf_ecoff_set_ext -struct ecoff_extr; -extern void elf_ecoff_set_ext (symbolS *, struct ecoff_extr *); -#endif -extern asection *elf_com_section_ptr; -extern symbolS * elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, - addressT size); - -#endif /* _OBJ_ELF_H */ diff --git a/contrib/binutils-2.22/gas/config/tc-i386-intel.c b/contrib/binutils-2.22/gas/config/tc-i386-intel.c deleted file mode 100644 index 1e563b2d81..0000000000 --- a/contrib/binutils-2.22/gas/config/tc-i386-intel.c +++ /dev/null @@ -1,964 +0,0 @@ -/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64 - Copyright 2009, 2010 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -static struct - { - operatorT op_modifier; /* Operand modifier. */ - int is_mem; /* 1 if operand is memory reference. */ - int is_indirect; /* 1 if operand is indirect reference. */ - int has_offset; /* 1 if operand has offset. */ - unsigned int in_offset; /* >=1 if processing operand of offset. */ - unsigned int in_bracket; /* >=1 if processing operand in brackets. */ - unsigned int in_scale; /* >=1 if processing multipication operand - * in brackets. */ - i386_operand_type reloc_types; /* Value obtained from lex_got(). */ - const reg_entry *base; /* Base register (if any). */ - const reg_entry *index; /* Index register (if any). */ - offsetT scale_factor; /* Accumulated scale factor. */ - symbolS *seg; - } -intel_state; - -/* offset X_add_symbol */ -#define O_offset O_md32 -/* offset X_add_symbol */ -#define O_short O_md31 -/* near ptr X_add_symbol */ -#define O_near_ptr O_md30 -/* far ptr X_add_symbol */ -#define O_far_ptr O_md29 -/* byte ptr X_add_symbol */ -#define O_byte_ptr O_md28 -/* word ptr X_add_symbol */ -#define O_word_ptr O_md27 -/* dword ptr X_add_symbol */ -#define O_dword_ptr O_md26 -/* qword ptr X_add_symbol */ -#define O_qword_ptr O_md25 -/* oword ptr X_add_symbol */ -#define O_oword_ptr O_md24 -/* fword ptr X_add_symbol */ -#define O_fword_ptr O_md23 -/* tbyte ptr X_add_symbol */ -#define O_tbyte_ptr O_md22 -/* xmmword ptr X_add_symbol */ -#define O_xmmword_ptr O_md21 -/* ymmword ptr X_add_symbol */ -#define O_ymmword_ptr O_md20 - -static struct - { - const char *name; - operatorT op; - unsigned int operands; - } -const i386_operators[] = - { - { "and", O_bit_and, 2 }, - { "eq", O_eq, 2 }, - { "ge", O_ge, 2 }, - { "gt", O_gt, 2 }, - { "le", O_le, 2 }, - { "lt", O_lt, 2 }, - { "mod", O_modulus, 2 }, - { "ne", O_ne, 2 }, - { "not", O_bit_not, 1 }, - { "offset", O_offset, 1 }, - { "or", O_bit_inclusive_or, 2 }, - { "shl", O_left_shift, 2 }, - { "short", O_short, 1 }, - { "shr", O_right_shift, 2 }, - { "xor", O_bit_exclusive_or, 2 }, - { NULL, O_illegal, 0 } - }; - -static struct - { - const char *name; - operatorT op; - unsigned short sz[3]; - } -const i386_types[] = - { -#define I386_TYPE(t, n) { #t, O_##t##_ptr, { n, n, n } } - I386_TYPE(byte, 1), - I386_TYPE(word, 2), - I386_TYPE(dword, 4), - I386_TYPE(fword, 6), - I386_TYPE(qword, 8), - I386_TYPE(tbyte, 10), - I386_TYPE(oword, 16), - I386_TYPE(xmmword, 16), - I386_TYPE(ymmword, 32), -#undef I386_TYPE - { "near", O_near_ptr, { 0xff04, 0xff02, 0xff08 } }, - { "far", O_far_ptr, { 0xff06, 0xff05, 0xff06 } }, - { NULL, O_illegal, { 0, 0, 0 } } - }; - -operatorT i386_operator (const char *name, unsigned int operands, char *pc) -{ - unsigned int j; - - if (!intel_syntax) - return O_absent; - - if (!name) - { - if (operands != 2) - return O_illegal; - switch (*input_line_pointer) - { - case ':': - ++input_line_pointer; - return O_full_ptr; - case '[': - ++input_line_pointer; - return O_index; - case '@': - if (this_operand >= 0 && i.reloc[this_operand] == NO_RELOC) - { - int adjust = 0; - char *gotfree_input_line = lex_got (&i.reloc[this_operand], - &adjust, - &intel_state.reloc_types); - - if (!gotfree_input_line) - break; - free (gotfree_input_line); - *input_line_pointer++ = '+'; - memset (input_line_pointer, '0', adjust - 1); - input_line_pointer[adjust - 1] = ' '; - return O_add; - } - break; - } - return O_illegal; - } - - for (j = 0; i386_operators[j].name; ++j) - if (strcasecmp (i386_operators[j].name, name) == 0) - { - if (i386_operators[j].operands - && i386_operators[j].operands != operands) - return O_illegal; - return i386_operators[j].op; - } - - for (j = 0; i386_types[j].name; ++j) - if (strcasecmp (i386_types[j].name, name) == 0) - break; - if (i386_types[j].name && *pc == ' ') - { - char *pname = ++input_line_pointer; - char c = get_symbol_end (); - - if (strcasecmp (pname, "ptr") == 0) - { - pname[-1] = *pc; - *pc = c; - if (intel_syntax > 0 || operands != 1) - return O_illegal; - return i386_types[j].op; - } - - *input_line_pointer = c; - input_line_pointer = pname - 1; - } - - return O_absent; -} - -static int i386_intel_parse_name (const char *name, expressionS *e) -{ - unsigned int j; - - if (! strcmp (name, "$")) - { - current_location (e); - return 1; - } - - for (j = 0; i386_types[j].name; ++j) - if (strcasecmp(i386_types[j].name, name) == 0) - { - e->X_op = O_constant; - e->X_add_number = i386_types[j].sz[flag_code]; - e->X_add_symbol = NULL; - e->X_op_symbol = NULL; - return 1; - } - - return 0; -} - -static INLINE int i386_intel_check (const reg_entry *rreg, - const reg_entry *base, - const reg_entry *iindex) -{ - if ((this_operand >= 0 - && rreg != i.op[this_operand].regs) - || base != intel_state.base - || iindex != intel_state.index) - { - as_bad (_("invalid use of register")); - return 0; - } - return 1; -} - -static INLINE void i386_intel_fold (expressionS *e, symbolS *sym) -{ - expressionS *exp = symbol_get_value_expression (sym); - if (S_GET_SEGMENT (sym) == absolute_section) - { - offsetT val = e->X_add_number; - - *e = *exp; - e->X_add_number += val; - } - else - { - if (exp->X_op == O_symbol - && strcmp (S_GET_NAME (exp->X_add_symbol), - GLOBAL_OFFSET_TABLE_NAME) == 0) - sym = exp->X_add_symbol; - e->X_add_symbol = sym; - e->X_op_symbol = NULL; - e->X_op = O_symbol; - } -} - -static int -i386_intel_simplify_register (expressionS *e) -{ - int reg_num; - - if (this_operand < 0 || intel_state.in_offset) - { - as_bad (_("invalid use of register")); - return 0; - } - - if (e->X_op == O_register) - reg_num = e->X_add_number; - else - reg_num = e->X_md - 1; - - if (!intel_state.in_bracket) - { - if (i.op[this_operand].regs) - { - as_bad (_("invalid use of register")); - return 0; - } - if (i386_regtab[reg_num].reg_type.bitfield.sreg3 - && i386_regtab[reg_num].reg_num == RegFlat) - { - as_bad (_("invalid use of pseudo-register")); - return 0; - } - i.op[this_operand].regs = i386_regtab + reg_num; - } - else if (!intel_state.base && !intel_state.in_scale) - intel_state.base = i386_regtab + reg_num; - else if (!intel_state.index) - intel_state.index = i386_regtab + reg_num; - else - { - /* esp is invalid as index */ - intel_state.index = i386_regtab + REGNAM_EAX + 4; - } - return 2; -} - -static int i386_intel_simplify (expressionS *); - -static INLINE int i386_intel_simplify_symbol(symbolS *sym) -{ - int ret = i386_intel_simplify (symbol_get_value_expression (sym)); - - if (ret == 2) - { - S_SET_SEGMENT(sym, absolute_section); - ret = 1; - } - return ret; -} - -static int i386_intel_simplify (expressionS *e) -{ - const reg_entry *the_reg = (this_operand >= 0 - ? i.op[this_operand].regs : NULL); - const reg_entry *base = intel_state.base; - const reg_entry *state_index = intel_state.index; - int ret; - - if (!intel_syntax) - return 1; - - switch (e->X_op) - { - case O_index: - if (e->X_add_symbol) - { - if (!i386_intel_simplify_symbol (e->X_add_symbol) - || !i386_intel_check(the_reg, intel_state.base, - intel_state.index)) - return 0;; - } - if (!intel_state.in_offset) - ++intel_state.in_bracket; - ret = i386_intel_simplify_symbol (e->X_op_symbol); - if (!intel_state.in_offset) - --intel_state.in_bracket; - if (!ret) - return 0; - if (e->X_add_symbol) - e->X_op = O_add; - else - i386_intel_fold (e, e->X_op_symbol); - break; - - case O_offset: - intel_state.has_offset = 1; - ++intel_state.in_offset; - ret = i386_intel_simplify_symbol (e->X_add_symbol); - --intel_state.in_offset; - if (!ret || !i386_intel_check(the_reg, base, state_index)) - return 0; - i386_intel_fold (e, e->X_add_symbol); - return ret; - - case O_byte_ptr: - case O_word_ptr: - case O_dword_ptr: - case O_fword_ptr: - case O_qword_ptr: - case O_tbyte_ptr: - case O_oword_ptr: - case O_xmmword_ptr: - case O_ymmword_ptr: - case O_near_ptr: - case O_far_ptr: - if (intel_state.op_modifier == O_absent) - intel_state.op_modifier = e->X_op; - /* FALLTHROUGH */ - case O_short: - if (symbol_get_value_expression (e->X_add_symbol)->X_op - == O_register) - { - as_bad (_("invalid use of register")); - return 0; - } - if (!i386_intel_simplify_symbol (e->X_add_symbol)) - return 0; - i386_intel_fold (e, e->X_add_symbol); - break; - - case O_full_ptr: - if (symbol_get_value_expression (e->X_op_symbol)->X_op - == O_register) - { - as_bad (_("invalid use of register")); - return 0; - } - if (!i386_intel_simplify_symbol (e->X_op_symbol) - || !i386_intel_check(the_reg, intel_state.base, - intel_state.index)) - return 0; - if (!intel_state.in_offset) - intel_state.seg = e->X_add_symbol; - i386_intel_fold (e, e->X_op_symbol); - break; - - case O_multiply: - if (this_operand >= 0 && intel_state.in_bracket) - { - expressionS *scale = NULL; - - if (intel_state.index) - --scale; - - if (!intel_state.in_scale++) - intel_state.scale_factor = 1; - - ret = i386_intel_simplify_symbol (e->X_add_symbol); - if (ret && !scale && intel_state.index) - scale = symbol_get_value_expression (e->X_op_symbol); - - if (ret) - ret = i386_intel_simplify_symbol (e->X_op_symbol); - if (ret && !scale && intel_state.index) - scale = symbol_get_value_expression (e->X_add_symbol); - - if (ret && scale && (scale + 1)) - { - resolve_expression (scale); - if (scale->X_op != O_constant - || intel_state.index->reg_type.bitfield.reg16) - scale->X_add_number = 0; - intel_state.scale_factor *= scale->X_add_number; - } - - --intel_state.in_scale; - if (!ret) - return 0; - - if (!intel_state.in_scale) - switch (intel_state.scale_factor) - { - case 1: - i.log2_scale_factor = 0; - break; - case 2: - i.log2_scale_factor = 1; - break; - case 4: - i.log2_scale_factor = 2; - break; - case 8: - i.log2_scale_factor = 3; - break; - default: - /* esp is invalid as index */ - intel_state.index = i386_regtab + REGNAM_EAX + 4; - break; - } - - break; - } - goto fallthrough; - - case O_register: - ret = i386_intel_simplify_register (e); - if (ret == 2) - { - gas_assert (e->X_add_number < (unsigned short) -1); - e->X_md = (unsigned short) e->X_add_number + 1; - e->X_op = O_constant; - e->X_add_number = 0; - } - return ret; - - case O_constant: - if (e->X_md) - return i386_intel_simplify_register (e); - - /* FALLTHROUGH */ - default: -fallthrough: - if (e->X_add_symbol - && !i386_intel_simplify_symbol (e->X_add_symbol)) - return 0; - if (e->X_op == O_add || e->X_op == O_subtract) - { - base = intel_state.base; - state_index = intel_state.index; - } - if (!i386_intel_check (the_reg, base, state_index) - || (e->X_op_symbol - && !i386_intel_simplify_symbol (e->X_op_symbol)) - || !i386_intel_check (the_reg, - (e->X_op != O_add - ? base : intel_state.base), - (e->X_op != O_add - ? state_index : intel_state.index))) - return 0; - break; - } - - if (this_operand >= 0 - && e->X_op == O_symbol - && !intel_state.in_offset) - { - segT seg = S_GET_SEGMENT (e->X_add_symbol); - - if (seg != absolute_section - && seg != reg_section - && seg != expr_section) - intel_state.is_mem |= 2 - !intel_state.in_bracket; - } - - return 1; -} - -int i386_need_index_operator (void) -{ - return intel_syntax < 0; -} - -static int -i386_intel_operand (char *operand_string, int got_a_float) -{ - char *saved_input_line_pointer, *buf; - segT exp_seg; - expressionS exp, *expP; - char suffix = 0; - int ret; - - /* Initialize state structure. */ - intel_state.op_modifier = O_absent; - intel_state.is_mem = 0; - intel_state.is_indirect = 0; - intel_state.has_offset = 0; - intel_state.base = NULL; - intel_state.index = NULL; - intel_state.seg = NULL; - operand_type_set (&intel_state.reloc_types, ~0); - gas_assert (!intel_state.in_offset); - gas_assert (!intel_state.in_bracket); - gas_assert (!intel_state.in_scale); - - saved_input_line_pointer = input_line_pointer; - input_line_pointer = buf = xstrdup (operand_string); - - intel_syntax = -1; - memset (&exp, 0, sizeof(exp)); - exp_seg = expression (&exp); - ret = i386_intel_simplify (&exp); - intel_syntax = 1; - - SKIP_WHITESPACE (); - if (!is_end_of_line[(unsigned char) *input_line_pointer]) - { - as_bad (_("junk `%s' after expression"), input_line_pointer); - ret = 0; - } - else if (exp.X_op == O_illegal || exp.X_op == O_absent) - { - as_bad (_("invalid expression")); - ret = 0; - } - else if (!intel_state.has_offset - && input_line_pointer > buf - && *(input_line_pointer - 1) == ']') - { - intel_state.is_mem |= 1; - intel_state.is_indirect = 1; - } - - input_line_pointer = saved_input_line_pointer; - free (buf); - - gas_assert (!intel_state.in_offset); - gas_assert (!intel_state.in_bracket); - gas_assert (!intel_state.in_scale); - - if (!ret) - return 0; - - if (intel_state.op_modifier != O_absent - && current_templates->start->base_opcode != 0x8d /* lea */) - { - i.types[this_operand].bitfield.unspecified = 0; - - switch (intel_state.op_modifier) - { - case O_byte_ptr: - i.types[this_operand].bitfield.byte = 1; - suffix = BYTE_MNEM_SUFFIX; - break; - - case O_word_ptr: - i.types[this_operand].bitfield.word = 1; - if ((current_templates->start->name[0] == 'l' - && current_templates->start->name[2] == 's' - && current_templates->start->name[3] == 0) - || current_templates->start->base_opcode == 0x62 /* bound */) - suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ - else if (got_a_float == 2) /* "fi..." */ - suffix = SHORT_MNEM_SUFFIX; - else - suffix = WORD_MNEM_SUFFIX; - break; - - case O_dword_ptr: - i.types[this_operand].bitfield.dword = 1; - if ((current_templates->start->name[0] == 'l' - && current_templates->start->name[2] == 's' - && current_templates->start->name[3] == 0) - || current_templates->start->base_opcode == 0x62 /* bound */) - suffix = WORD_MNEM_SUFFIX; - else if (flag_code == CODE_16BIT - && (current_templates->start->opcode_modifier.jump - || current_templates->start->opcode_modifier.jumpdword)) - suffix = LONG_DOUBLE_MNEM_SUFFIX; - else if (got_a_float == 1) /* "f..." */ - suffix = SHORT_MNEM_SUFFIX; - else - suffix = LONG_MNEM_SUFFIX; - break; - - case O_fword_ptr: - i.types[this_operand].bitfield.fword = 1; - if (current_templates->start->name[0] == 'l' - && current_templates->start->name[2] == 's' - && current_templates->start->name[3] == 0) - suffix = LONG_MNEM_SUFFIX; - else if (!got_a_float) - { - if (flag_code == CODE_16BIT) - add_prefix (DATA_PREFIX_OPCODE); - suffix = LONG_DOUBLE_MNEM_SUFFIX; - } - else - suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ - break; - - case O_qword_ptr: - i.types[this_operand].bitfield.qword = 1; - if (current_templates->start->base_opcode == 0x62 /* bound */ - || got_a_float == 1) /* "f..." */ - suffix = LONG_MNEM_SUFFIX; - else - suffix = QWORD_MNEM_SUFFIX; - break; - - case O_tbyte_ptr: - i.types[this_operand].bitfield.tbyte = 1; - if (got_a_float == 1) - suffix = LONG_DOUBLE_MNEM_SUFFIX; - else - suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ - break; - - case O_oword_ptr: - case O_xmmword_ptr: - i.types[this_operand].bitfield.xmmword = 1; - suffix = XMMWORD_MNEM_SUFFIX; - break; - - case O_ymmword_ptr: - i.types[this_operand].bitfield.ymmword = 1; - suffix = YMMWORD_MNEM_SUFFIX; - break; - - case O_far_ptr: - suffix = LONG_DOUBLE_MNEM_SUFFIX; - /* FALLTHROUGH */ - case O_near_ptr: - if (!current_templates->start->opcode_modifier.jump - && !current_templates->start->opcode_modifier.jumpdword) - suffix = got_a_float /* so it will cause an error */ - ? BYTE_MNEM_SUFFIX - : LONG_DOUBLE_MNEM_SUFFIX; - break; - - default: - BAD_CASE (intel_state.op_modifier); - break; - } - - if (!i.suffix) - i.suffix = suffix; - else if (i.suffix != suffix) - { - as_bad (_("conflicting operand size modifiers")); - return 0; - } - } - - /* Operands for jump/call need special consideration. */ - if (current_templates->start->opcode_modifier.jump - || current_templates->start->opcode_modifier.jumpdword - || current_templates->start->opcode_modifier.jumpintersegment) - { - if (i.op[this_operand].regs - || intel_state.base - || intel_state.index - || intel_state.is_mem > 1) - i.types[this_operand].bitfield.jumpabsolute = 1; - else - switch (intel_state.op_modifier) - { - case O_near_ptr: - if (intel_state.seg) - i.types[this_operand].bitfield.jumpabsolute = 1; - else - intel_state.is_mem = 1; - break; - case O_far_ptr: - case O_absent: - if (!intel_state.seg) - { - intel_state.is_mem = 1; - if (intel_state.op_modifier == O_absent) - { - if (intel_state.is_indirect == 1) - i.types[this_operand].bitfield.jumpabsolute = 1; - break; - } - as_bad (_("cannot infer the segment part of the operand")); - return 0; - } - else if (S_GET_SEGMENT (intel_state.seg) == reg_section) - i.types[this_operand].bitfield.jumpabsolute = 1; - else - { - i386_operand_type types; - - if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS) - { - as_bad (_("at most %d immediate operands are allowed"), - MAX_IMMEDIATE_OPERANDS); - return 0; - } - expP = &im_expressions[i.imm_operands++]; - memset (expP, 0, sizeof(*expP)); - expP->X_op = O_symbol; - expP->X_add_symbol = intel_state.seg; - i.op[this_operand].imms = expP; - - resolve_expression (expP); - operand_type_set (&types, ~0); - if (!i386_finalize_immediate (S_GET_SEGMENT (intel_state.seg), - expP, types, operand_string)) - return 0; - if (i.operands < MAX_OPERANDS) - { - this_operand = i.operands++; - i.types[this_operand].bitfield.unspecified = 1; - } - if (suffix == LONG_DOUBLE_MNEM_SUFFIX) - i.suffix = 0; - intel_state.seg = NULL; - intel_state.is_mem = 0; - } - break; - default: - i.types[this_operand].bitfield.jumpabsolute = 1; - break; - } - if (i.types[this_operand].bitfield.jumpabsolute) - intel_state.is_mem |= 1; - } - else if (intel_state.seg) - intel_state.is_mem |= 1; - - if (i.op[this_operand].regs) - { - i386_operand_type temp; - - /* Register operand. */ - if (intel_state.base || intel_state.index || intel_state.seg) - { - as_bad (_("invalid operand")); - return 0; - } - - temp = i.op[this_operand].regs->reg_type; - temp.bitfield.baseindex = 0; - i.types[this_operand] = operand_type_or (i.types[this_operand], - temp); - i.types[this_operand].bitfield.unspecified = 0; - ++i.reg_operands; - } - else if (intel_state.base - || intel_state.index - || intel_state.seg - || intel_state.is_mem) - { - /* Memory operand. */ - if (i.mem_operands - >= 2 - !current_templates->start->opcode_modifier.isstring) - { - /* Handle - - call 0x9090,0x90909090 - lcall 0x9090,0x90909090 - jmp 0x9090,0x90909090 - ljmp 0x9090,0x90909090 - */ - - if ((current_templates->start->opcode_modifier.jumpintersegment - || current_templates->start->opcode_modifier.jumpdword - || current_templates->start->opcode_modifier.jump) - && this_operand == 1 - && intel_state.seg == NULL - && i.mem_operands == 1 - && i.disp_operands == 1 - && intel_state.op_modifier == O_absent) - { - /* Try to process the first operand as immediate, */ - this_operand = 0; - if (i386_finalize_immediate (exp_seg, i.op[0].imms, - intel_state.reloc_types, - NULL)) - { - this_operand = 1; - expP = &im_expressions[0]; - i.op[this_operand].imms = expP; - *expP = exp; - - /* Try to process the second operand as immediate, */ - if (i386_finalize_immediate (exp_seg, expP, - intel_state.reloc_types, - NULL)) - { - i.mem_operands = 0; - i.disp_operands = 0; - i.imm_operands = 2; - i.types[0].bitfield.mem = 0; - i.types[0].bitfield.disp16 = 0; - i.types[0].bitfield.disp32 = 0; - i.types[0].bitfield.disp32s = 0; - return 1; - } - } - } - - as_bad (_("too many memory references for `%s'"), - current_templates->start->name); - return 0; - } - - expP = &disp_expressions[i.disp_operands]; - memcpy (expP, &exp, sizeof(exp)); - resolve_expression (expP); - - if (expP->X_op != O_constant - || expP->X_add_number - || (!intel_state.base - && !intel_state.index)) - { - i.op[this_operand].disps = expP; - i.disp_operands++; - - if (flag_code == CODE_64BIT) - { - i.types[this_operand].bitfield.disp32 = 1; - if (!i.prefix[ADDR_PREFIX]) - { - i.types[this_operand].bitfield.disp64 = 1; - i.types[this_operand].bitfield.disp32s = 1; - } - } - else if (!i.prefix[ADDR_PREFIX] ^ (flag_code == CODE_16BIT)) - i.types[this_operand].bitfield.disp32 = 1; - else - i.types[this_operand].bitfield.disp16 = 1; - -#if defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) - /* - * exp_seg is used only for verification in - * i386_finalize_displacement, and we can end up seeing reg_section - * here - but we know we removed all registers from the expression - * (or error-ed on any remaining ones) in i386_intel_simplify. I - * consider the check in i386_finalize_displacement bogus anyway, in - * particular because it doesn't allow for expr_section, so I'd - * rather see that check (and the similar one in - * i386_finalize_immediate) use SEG_NORMAL(), but not being an a.out - * expert I can't really say whether that would have other bad side - * effects. - */ - if (OUTPUT_FLAVOR == bfd_target_aout_flavour - && exp_seg == reg_section) - exp_seg = expP->X_op != O_constant ? undefined_section - : absolute_section; -#endif - - if (!i386_finalize_displacement (exp_seg, expP, - intel_state.reloc_types, - operand_string)) - return 0; - } - - if (intel_state.base || intel_state.index) - i.types[this_operand].bitfield.baseindex = 1; - - if (intel_state.seg) - { - for (;;) - { - expP = symbol_get_value_expression (intel_state.seg); - if (expP->X_op != O_full_ptr) - break; - intel_state.seg = expP->X_add_symbol; - } - if (expP->X_op != O_register) - { - as_bad (_("segment register name expected")); - return 0; - } - if (!i386_regtab[expP->X_add_number].reg_type.bitfield.sreg2 - && !i386_regtab[expP->X_add_number].reg_type.bitfield.sreg3) - { - as_bad (_("invalid use of register")); - return 0; - } - switch (i386_regtab[expP->X_add_number].reg_num) - { - case 0: i.seg[i.mem_operands] = &es; break; - case 1: i.seg[i.mem_operands] = &cs; break; - case 2: i.seg[i.mem_operands] = &ss; break; - case 3: i.seg[i.mem_operands] = &ds; break; - case 4: i.seg[i.mem_operands] = &fs; break; - case 5: i.seg[i.mem_operands] = &gs; break; - case RegFlat: i.seg[i.mem_operands] = NULL; break; - } - } - - /* Swap base and index in 16-bit memory operands like - [si+bx]. Since i386_index_check is also used in AT&T - mode we have to do that here. */ - if (intel_state.base - && intel_state.index - && intel_state.base->reg_type.bitfield.reg16 - && intel_state.index->reg_type.bitfield.reg16 - && intel_state.base->reg_num >= 6 - && intel_state.index->reg_num < 6) - { - i.base_reg = intel_state.index; - i.index_reg = intel_state.base; - } - else - { - i.base_reg = intel_state.base; - i.index_reg = intel_state.index; - } - - if (!i386_index_check (operand_string)) - return 0; - - i.types[this_operand].bitfield.mem = 1; - ++i.mem_operands; - } - else - { - /* Immediate. */ - if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS) - { - as_bad (_("at most %d immediate operands are allowed"), - MAX_IMMEDIATE_OPERANDS); - return 0; - } - - expP = &im_expressions[i.imm_operands++]; - i.op[this_operand].imms = expP; - *expP = exp; - - return i386_finalize_immediate (exp_seg, expP, intel_state.reloc_types, - operand_string); - } - - return 1; -} diff --git a/contrib/binutils-2.22/gas/config/tc-i386.c b/contrib/binutils-2.22/gas/config/tc-i386.c deleted file mode 100644 index 59182bbeab..0000000000 --- a/contrib/binutils-2.22/gas/config/tc-i386.c +++ /dev/null @@ -1,9277 +0,0 @@ -/* tc-i386.c -- Assemble code for the Intel 80386 - Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Intel 80386 machine specific gas. - Written by Eliot Dresselhaus (eliot@mgm.mit.edu). - x86_64 support by Jan Hubicka (jh@suse.cz) - VIA PadLock support by Michal Ludvig (mludvig@suse.cz) - Bugs & suggestions are completely welcome. This is free software. - Please help us make it better. */ - -#include "as.h" -#include "safe-ctype.h" -#include "subsegs.h" -#include "dwarf2dbg.h" -#include "dw2gencfi.h" -#include "elf/x86-64.h" -#include "opcodes/i386-init.h" - -#ifndef REGISTER_WARNINGS -#define REGISTER_WARNINGS 1 -#endif - -#ifndef INFER_ADDR_PREFIX -#define INFER_ADDR_PREFIX 1 -#endif - -#ifndef DEFAULT_ARCH -#define DEFAULT_ARCH "i386" -#endif - -#ifndef INLINE -#if __GNUC__ >= 2 -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -/* Prefixes will be emitted in the order defined below. - WAIT_PREFIX must be the first prefix since FWAIT is really is an - instruction, and so must come before any prefixes. - The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX, - REP_PREFIX, LOCK_PREFIX. */ -#define WAIT_PREFIX 0 -#define SEG_PREFIX 1 -#define ADDR_PREFIX 2 -#define DATA_PREFIX 3 -#define REP_PREFIX 4 -#define LOCK_PREFIX 5 -#define REX_PREFIX 6 /* must come last. */ -#define MAX_PREFIXES 7 /* max prefixes per opcode */ - -/* we define the syntax here (modulo base,index,scale syntax) */ -#define REGISTER_PREFIX '%' -#define IMMEDIATE_PREFIX '$' -#define ABSOLUTE_PREFIX '*' - -/* these are the instruction mnemonic suffixes in AT&T syntax or - memory operand size in Intel syntax. */ -#define WORD_MNEM_SUFFIX 'w' -#define BYTE_MNEM_SUFFIX 'b' -#define SHORT_MNEM_SUFFIX 's' -#define LONG_MNEM_SUFFIX 'l' -#define QWORD_MNEM_SUFFIX 'q' -#define XMMWORD_MNEM_SUFFIX 'x' -#define YMMWORD_MNEM_SUFFIX 'y' -/* Intel Syntax. Use a non-ascii letter since since it never appears - in instructions. */ -#define LONG_DOUBLE_MNEM_SUFFIX '\1' - -#define END_OF_INSN '\0' - -/* - 'templates' is for grouping together 'template' structures for opcodes - of the same name. This is only used for storing the insns in the grand - ole hash table of insns. - The templates themselves start at START and range up to (but not including) - END. - */ -typedef struct -{ - const insn_template *start; - const insn_template *end; -} -templates; - -/* 386 operand encoding bytes: see 386 book for details of this. */ -typedef struct -{ - unsigned int regmem; /* codes register or memory operand */ - unsigned int reg; /* codes register operand (or extended opcode) */ - unsigned int mode; /* how to interpret regmem & reg */ -} -modrm_byte; - -/* x86-64 extension prefix. */ -typedef int rex_byte; - -/* 386 opcode byte to code indirect addressing. */ -typedef struct -{ - unsigned base; - unsigned index; - unsigned scale; -} -sib_byte; - -/* x86 arch names, types and features */ -typedef struct -{ - const char *name; /* arch name */ - unsigned int len; /* arch string length */ - enum processor_type type; /* arch type */ - i386_cpu_flags flags; /* cpu feature flags */ - unsigned int skip; /* show_arch should skip this. */ - unsigned int negated; /* turn off indicated flags. */ -} -arch_entry; - -static void update_code_flag (int, int); -static void set_code_flag (int); -static void set_16bit_gcc_code_flag (int); -static void set_intel_syntax (int); -static void set_intel_mnemonic (int); -static void set_allow_index_reg (int); -static void set_sse_check (int); -static void set_cpu_arch (int); -#ifdef TE_PE -static void pe_directive_secrel (int); -#endif -static void signed_cons (int); -static char *output_invalid (int c); -static int i386_finalize_immediate (segT, expressionS *, i386_operand_type, - const char *); -static int i386_finalize_displacement (segT, expressionS *, i386_operand_type, - const char *); -static int i386_att_operand (char *); -static int i386_intel_operand (char *, int); -static int i386_intel_simplify (expressionS *); -static int i386_intel_parse_name (const char *, expressionS *); -static const reg_entry *parse_register (char *, char **); -static char *parse_insn (char *, char *); -static char *parse_operands (char *, const char *); -static void swap_operands (void); -static void swap_2_operands (int, int); -static void optimize_imm (void); -static void optimize_disp (void); -static const insn_template *match_template (void); -static int check_string (void); -static int process_suffix (void); -static int check_byte_reg (void); -static int check_long_reg (void); -static int check_qword_reg (void); -static int check_word_reg (void); -static int finalize_imm (void); -static int process_operands (void); -static const seg_entry *build_modrm_byte (void); -static void output_insn (void); -static void output_imm (fragS *, offsetT); -static void output_disp (fragS *, offsetT); -#ifndef I386COFF -static void s_bss (int); -#endif -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) -static void handle_large_common (int small ATTRIBUTE_UNUSED); -#endif - -static const char *default_arch = DEFAULT_ARCH; - -/* VEX prefix. */ -typedef struct -{ - /* VEX prefix is either 2 byte or 3 byte. */ - unsigned char bytes[3]; - unsigned int length; - /* Destination or source register specifier. */ - const reg_entry *register_specifier; -} vex_prefix; - -/* 'md_assemble ()' gathers together information and puts it into a - i386_insn. */ - -union i386_op - { - expressionS *disps; - expressionS *imms; - const reg_entry *regs; - }; - -enum i386_error - { - operand_size_mismatch, - operand_type_mismatch, - register_type_mismatch, - number_of_operands_mismatch, - invalid_instruction_suffix, - bad_imm4, - old_gcc_only, - unsupported_with_intel_mnemonic, - unsupported_syntax, - unsupported, - invalid_vsib_address, - unsupported_vector_index_register - }; - -struct _i386_insn - { - /* TM holds the template for the insn were currently assembling. */ - insn_template tm; - - /* SUFFIX holds the instruction size suffix for byte, word, dword - or qword, if given. */ - char suffix; - - /* OPERANDS gives the number of given operands. */ - unsigned int operands; - - /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number - of given register, displacement, memory operands and immediate - operands. */ - unsigned int reg_operands, disp_operands, mem_operands, imm_operands; - - /* TYPES [i] is the type (see above #defines) which tells us how to - use OP[i] for the corresponding operand. */ - i386_operand_type types[MAX_OPERANDS]; - - /* Displacement expression, immediate expression, or register for each - operand. */ - union i386_op op[MAX_OPERANDS]; - - /* Flags for operands. */ - unsigned int flags[MAX_OPERANDS]; -#define Operand_PCrel 1 - - /* Relocation type for operand */ - enum bfd_reloc_code_real reloc[MAX_OPERANDS]; - - /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode - the base index byte below. */ - const reg_entry *base_reg; - const reg_entry *index_reg; - unsigned int log2_scale_factor; - - /* SEG gives the seg_entries of this insn. They are zero unless - explicit segment overrides are given. */ - const seg_entry *seg[2]; - - /* PREFIX holds all the given prefix opcodes (usually null). - PREFIXES is the number of prefix opcodes. */ - unsigned int prefixes; - unsigned char prefix[MAX_PREFIXES]; - - /* RM and SIB are the modrm byte and the sib byte where the - addressing modes of this insn are encoded. */ - modrm_byte rm; - rex_byte rex; - sib_byte sib; - vex_prefix vex; - - /* Swap operand in encoding. */ - unsigned int swap_operand; - - /* Force 32bit displacement in encoding. */ - unsigned int disp32_encoding; - - /* Error message. */ - enum i386_error error; - }; - -typedef struct _i386_insn i386_insn; - -/* List of chars besides those in app.c:symbol_chars that can start an - operand. Used to prevent the scrubber eating vital white-space. */ -const char extra_symbol_chars[] = "*%-([" -#ifdef LEX_AT - "@" -#endif -#ifdef LEX_QM - "?" -#endif - ; - -#if (defined (TE_I386AIX) \ - || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \ - && !defined (TE_GNU) \ - && !defined (TE_LINUX) \ - && !defined (TE_NETWARE) \ - && !defined (TE_FreeBSD) \ - && !defined (TE_DragonFly) \ - && !defined (TE_NetBSD))) -/* This array holds the chars that always start a comment. If the - pre-processor is disabled, these aren't very useful. The option - --divide will remove '/' from this list. */ -const char *i386_comment_chars = "#/"; -#define SVR4_COMMENT_CHARS 1 -#define PREFIX_SEPARATOR '\\' - -#else -const char *i386_comment_chars = "#"; -#define PREFIX_SEPARATOR '/' -#endif - -/* This array holds the chars that only start a comment at the beginning of - a line. If the line seems to have the form '# 123 filename' - .line and .file directives will appear in the pre-processed output. - Note that input_file.c hand checks for '#' at the beginning of the - first line of the input file. This is because the compiler outputs - #NO_APP at the beginning of its output. - Also note that comments started like this one will always work if - '/' isn't otherwise defined. */ -const char line_comment_chars[] = "#/"; - -const char line_separator_chars[] = ";"; - -/* Chars that can be used to separate mant from exp in floating point - nums. */ -const char EXP_CHARS[] = "eE"; - -/* Chars that mean this number is a floating point constant - As in 0f12.456 - or 0d1.2345e12. */ -const char FLT_CHARS[] = "fFdDxX"; - -/* Tables for lexical analysis. */ -static char mnemonic_chars[256]; -static char register_chars[256]; -static char operand_chars[256]; -static char identifier_chars[256]; -static char digit_chars[256]; - -/* Lexical macros. */ -#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x]) -#define is_operand_char(x) (operand_chars[(unsigned char) x]) -#define is_register_char(x) (register_chars[(unsigned char) x]) -#define is_space_char(x) ((x) == ' ') -#define is_identifier_char(x) (identifier_chars[(unsigned char) x]) -#define is_digit_char(x) (digit_chars[(unsigned char) x]) - -/* All non-digit non-letter characters that may occur in an operand. */ -static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]"; - -/* md_assemble() always leaves the strings it's passed unaltered. To - effect this we maintain a stack of saved characters that we've smashed - with '\0's (indicating end of strings for various sub-fields of the - assembler instruction). */ -static char save_stack[32]; -static char *save_stack_p; -#define END_STRING_AND_SAVE(s) \ - do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0) -#define RESTORE_END_STRING(s) \ - do { *(s) = *--save_stack_p; } while (0) - -/* The instruction we're assembling. */ -static i386_insn i; - -/* Possible templates for current insn. */ -static const templates *current_templates; - -/* Per instruction expressionS buffers: max displacements & immediates. */ -static expressionS disp_expressions[MAX_MEMORY_OPERANDS]; -static expressionS im_expressions[MAX_IMMEDIATE_OPERANDS]; - -/* Current operand we are working on. */ -static int this_operand = -1; - -/* We support four different modes. FLAG_CODE variable is used to distinguish - these. */ - -enum flag_code { - CODE_32BIT, - CODE_16BIT, - CODE_64BIT }; - -static enum flag_code flag_code; -static unsigned int object_64bit; -static unsigned int disallow_64bit_reloc; -static int use_rela_relocations = 0; - -#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ - || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) - -/* The ELF ABI to use. */ -enum x86_elf_abi -{ - I386_ABI, - X86_64_ABI, - X86_64_X32_ABI -}; - -static enum x86_elf_abi x86_elf_abi = I386_ABI; -#endif - -/* The names used to print error messages. */ -static const char *flag_code_names[] = - { - "32", - "16", - "64" - }; - -/* 1 for intel syntax, - 0 if att syntax. */ -static int intel_syntax = 0; - -/* 1 for intel mnemonic, - 0 if att mnemonic. */ -static int intel_mnemonic = !SYSV386_COMPAT; - -/* 1 if support old (<= 2.8.1) versions of gcc. */ -static int old_gcc = OLDGCC_COMPAT; - -/* 1 if pseudo registers are permitted. */ -static int allow_pseudo_reg = 0; - -/* 1 if register prefix % not required. */ -static int allow_naked_reg = 0; - -/* 1 if pseudo index register, eiz/riz, is allowed . */ -static int allow_index_reg = 0; - -static enum - { - sse_check_none = 0, - sse_check_warning, - sse_check_error - } -sse_check; - -/* Register prefix used for error message. */ -static const char *register_prefix = "%"; - -/* Used in 16 bit gcc mode to add an l suffix to call, ret, enter, - leave, push, and pop instructions so that gcc has the same stack - frame as in 32 bit mode. */ -static char stackop_size = '\0'; - -/* Non-zero to optimize code alignment. */ -int optimize_align_code = 1; - -/* Non-zero to quieten some warnings. */ -static int quiet_warnings = 0; - -/* CPU name. */ -static const char *cpu_arch_name = NULL; -static char *cpu_sub_arch_name = NULL; - -/* CPU feature flags. */ -static i386_cpu_flags cpu_arch_flags = CPU_UNKNOWN_FLAGS; - -/* If we have selected a cpu we are generating instructions for. */ -static int cpu_arch_tune_set = 0; - -/* Cpu we are generating instructions for. */ -enum processor_type cpu_arch_tune = PROCESSOR_UNKNOWN; - -/* CPU feature flags of cpu we are generating instructions for. */ -static i386_cpu_flags cpu_arch_tune_flags; - -/* CPU instruction set architecture used. */ -enum processor_type cpu_arch_isa = PROCESSOR_UNKNOWN; - -/* CPU feature flags of instruction set architecture used. */ -i386_cpu_flags cpu_arch_isa_flags; - -/* If set, conditional jumps are not automatically promoted to handle - larger than a byte offset. */ -static unsigned int no_cond_jump_promotion = 0; - -/* Encode SSE instructions with VEX prefix. */ -static unsigned int sse2avx; - -/* Encode scalar AVX instructions with specific vector length. */ -static enum - { - vex128 = 0, - vex256 - } avxscalar; - -/* Pre-defined "_GLOBAL_OFFSET_TABLE_". */ -static symbolS *GOT_symbol; - -/* The dwarf2 return column, adjusted for 32 or 64 bit. */ -unsigned int x86_dwarf2_return_column; - -/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */ -int x86_cie_data_alignment; - -/* Interface to relax_segment. - There are 3 major relax states for 386 jump insns because the - different types of jumps add different sizes to frags when we're - figuring out what sort of jump to choose to reach a given label. */ - -/* Types. */ -#define UNCOND_JUMP 0 -#define COND_JUMP 1 -#define COND_JUMP86 2 - -/* Sizes. */ -#define CODE16 1 -#define SMALL 0 -#define SMALL16 (SMALL | CODE16) -#define BIG 2 -#define BIG16 (BIG | CODE16) - -#ifndef INLINE -#ifdef __GNUC__ -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -#define ENCODE_RELAX_STATE(type, size) \ - ((relax_substateT) (((type) << 2) | (size))) -#define TYPE_FROM_RELAX_STATE(s) \ - ((s) >> 2) -#define DISP_SIZE_FROM_RELAX_STATE(s) \ - ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1))) - -/* This table is used by relax_frag to promote short jumps to long - ones where necessary. SMALL (short) jumps may be promoted to BIG - (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We - don't allow a short jump in a 32 bit code segment to be promoted to - a 16 bit offset jump because it's slower (requires data size - prefix), and doesn't work, unless the destination is in the bottom - 64k of the code segment (The top 16 bits of eip are zeroed). */ - -const relax_typeS md_relax_table[] = -{ - /* The fields are: - 1) most positive reach of this state, - 2) most negative reach of this state, - 3) how many bytes this mode will have in the variable part of the frag - 4) which index into the table to try if we can't fit into this one. */ - - /* UNCOND_JUMP states. */ - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)}, - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)}, - /* dword jmp adds 4 bytes to frag: - 0 extra opcode bytes, 4 displacement bytes. */ - {0, 0, 4, 0}, - /* word jmp adds 2 byte2 to frag: - 0 extra opcode bytes, 2 displacement bytes. */ - {0, 0, 2, 0}, - - /* COND_JUMP states. */ - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)}, - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)}, - /* dword conditionals adds 5 bytes to frag: - 1 extra opcode byte, 4 displacement bytes. */ - {0, 0, 5, 0}, - /* word conditionals add 3 bytes to frag: - 1 extra opcode byte, 2 displacement bytes. */ - {0, 0, 3, 0}, - - /* COND_JUMP86 states. */ - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)}, - {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)}, - /* dword conditionals adds 5 bytes to frag: - 1 extra opcode byte, 4 displacement bytes. */ - {0, 0, 5, 0}, - /* word conditionals add 4 bytes to frag: - 1 displacement byte and a 3 byte long branch insn. */ - {0, 0, 4, 0} -}; - -static const arch_entry cpu_arch[] = -{ - /* Do not replace the first two entries - i386_target_format() - relies on them being there in this order. */ - { STRING_COMMA_LEN ("generic32"), PROCESSOR_GENERIC32, - CPU_GENERIC32_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("generic64"), PROCESSOR_GENERIC64, - CPU_GENERIC64_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i8086"), PROCESSOR_UNKNOWN, - CPU_NONE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i186"), PROCESSOR_UNKNOWN, - CPU_I186_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i286"), PROCESSOR_UNKNOWN, - CPU_I286_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i386"), PROCESSOR_I386, - CPU_I386_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i486"), PROCESSOR_I486, - CPU_I486_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i586"), PROCESSOR_PENTIUM, - CPU_I586_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("i686"), PROCESSOR_PENTIUMPRO, - CPU_I686_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("pentium"), PROCESSOR_PENTIUM, - CPU_I586_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("pentiumpro"), PROCESSOR_PENTIUMPRO, - CPU_PENTIUMPRO_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("pentiumii"), PROCESSOR_PENTIUMPRO, - CPU_P2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("pentiumiii"),PROCESSOR_PENTIUMPRO, - CPU_P3_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("pentium4"), PROCESSOR_PENTIUM4, - CPU_P4_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("prescott"), PROCESSOR_NOCONA, - CPU_CORE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("nocona"), PROCESSOR_NOCONA, - CPU_NOCONA_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("yonah"), PROCESSOR_CORE, - CPU_CORE_FLAGS, 1, 0 }, - { STRING_COMMA_LEN ("core"), PROCESSOR_CORE, - CPU_CORE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("merom"), PROCESSOR_CORE2, - CPU_CORE2_FLAGS, 1, 0 }, - { STRING_COMMA_LEN ("core2"), PROCESSOR_CORE2, - CPU_CORE2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("corei7"), PROCESSOR_COREI7, - CPU_COREI7_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM, - CPU_L1OM_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM, - CPU_K1OM_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("k6"), PROCESSOR_K6, - CPU_K6_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6, - CPU_K6_2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("athlon"), PROCESSOR_ATHLON, - CPU_ATHLON_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("sledgehammer"), PROCESSOR_K8, - CPU_K8_FLAGS, 1, 0 }, - { STRING_COMMA_LEN ("opteron"), PROCESSOR_K8, - CPU_K8_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("k8"), PROCESSOR_K8, - CPU_K8_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("amdfam10"), PROCESSOR_AMDFAM10, - CPU_AMDFAM10_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("bdver1"), PROCESSOR_BD, - CPU_BDVER1_FLAGS, 0, 0 }, - { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD, - CPU_BDVER2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN, - CPU_8087_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN, - CPU_287_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".387"), PROCESSOR_UNKNOWN, - CPU_387_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".no87"), PROCESSOR_UNKNOWN, - CPU_ANY87_FLAGS, 0, 1 }, - { STRING_COMMA_LEN (".mmx"), PROCESSOR_UNKNOWN, - CPU_MMX_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".nommx"), PROCESSOR_UNKNOWN, - CPU_3DNOWA_FLAGS, 0, 1 }, - { STRING_COMMA_LEN (".sse"), PROCESSOR_UNKNOWN, - CPU_SSE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse2"), PROCESSOR_UNKNOWN, - CPU_SSE2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse3"), PROCESSOR_UNKNOWN, - CPU_SSE3_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".ssse3"), PROCESSOR_UNKNOWN, - CPU_SSSE3_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse4.1"), PROCESSOR_UNKNOWN, - CPU_SSE4_1_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse4.2"), PROCESSOR_UNKNOWN, - CPU_SSE4_2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse4"), PROCESSOR_UNKNOWN, - CPU_SSE4_2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".nosse"), PROCESSOR_UNKNOWN, - CPU_ANY_SSE_FLAGS, 0, 1 }, - { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN, - CPU_AVX_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".avx2"), PROCESSOR_UNKNOWN, - CPU_AVX2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN, - CPU_ANY_AVX_FLAGS, 0, 1 }, - { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN, - CPU_VMX_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN, - CPU_SMX_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN, - CPU_XSAVE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".xsaveopt"), PROCESSOR_UNKNOWN, - CPU_XSAVEOPT_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".aes"), PROCESSOR_UNKNOWN, - CPU_AES_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".pclmul"), PROCESSOR_UNKNOWN, - CPU_PCLMUL_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".clmul"), PROCESSOR_UNKNOWN, - CPU_PCLMUL_FLAGS, 1, 0 }, - { STRING_COMMA_LEN (".fsgsbase"), PROCESSOR_UNKNOWN, - CPU_FSGSBASE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".rdrnd"), PROCESSOR_UNKNOWN, - CPU_RDRND_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN, - CPU_F16C_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".bmi2"), PROCESSOR_UNKNOWN, - CPU_BMI2_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN, - CPU_FMA_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN, - CPU_FMA4_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".xop"), PROCESSOR_UNKNOWN, - CPU_XOP_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".lwp"), PROCESSOR_UNKNOWN, - CPU_LWP_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN, - CPU_MOVBE_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN, - CPU_EPT_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN, - CPU_LZCNT_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".invpcid"), PROCESSOR_UNKNOWN, - CPU_INVPCID_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN, - CPU_CLFLUSH_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN, - CPU_NOP_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".syscall"), PROCESSOR_UNKNOWN, - CPU_SYSCALL_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".rdtscp"), PROCESSOR_UNKNOWN, - CPU_RDTSCP_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".3dnow"), PROCESSOR_UNKNOWN, - CPU_3DNOW_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".3dnowa"), PROCESSOR_UNKNOWN, - CPU_3DNOWA_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".padlock"), PROCESSOR_UNKNOWN, - CPU_PADLOCK_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".pacifica"), PROCESSOR_UNKNOWN, - CPU_SVME_FLAGS, 1, 0 }, - { STRING_COMMA_LEN (".svme"), PROCESSOR_UNKNOWN, - CPU_SVME_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".sse4a"), PROCESSOR_UNKNOWN, - CPU_SSE4A_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".abm"), PROCESSOR_UNKNOWN, - CPU_ABM_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".bmi"), PROCESSOR_UNKNOWN, - CPU_BMI_FLAGS, 0, 0 }, - { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN, - CPU_TBM_FLAGS, 0, 0 }, -}; - -#ifdef I386COFF -/* Like s_lcomm_internal in gas/read.c but the alignment string - is allowed to be optional. */ - -static symbolS * -pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size) -{ - addressT align = 0; - - SKIP_WHITESPACE (); - - if (needs_align - && *input_line_pointer == ',') - { - align = parse_align (needs_align - 1); - - if (align == (addressT) -1) - return NULL; - } - else - { - if (size >= 8) - align = 3; - else if (size >= 4) - align = 2; - else if (size >= 2) - align = 1; - else - align = 0; - } - - bss_alloc (symbolP, size, align); - return symbolP; -} - -static void -pe_lcomm (int needs_align) -{ - s_comm_internal (needs_align * 2, pe_lcomm_internal); -} -#endif - -const pseudo_typeS md_pseudo_table[] = -{ -#if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO) - {"align", s_align_bytes, 0}, -#else - {"align", s_align_ptwo, 0}, -#endif - {"arch", set_cpu_arch, 0}, -#ifndef I386COFF - {"bss", s_bss, 0}, -#else - {"lcomm", pe_lcomm, 1}, -#endif - {"ffloat", float_cons, 'f'}, - {"dfloat", float_cons, 'd'}, - {"tfloat", float_cons, 'x'}, - {"value", cons, 2}, - {"slong", signed_cons, 4}, - {"noopt", s_ignore, 0}, - {"optim", s_ignore, 0}, - {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT}, - {"code16", set_code_flag, CODE_16BIT}, - {"code32", set_code_flag, CODE_32BIT}, - {"code64", set_code_flag, CODE_64BIT}, - {"intel_syntax", set_intel_syntax, 1}, - {"att_syntax", set_intel_syntax, 0}, - {"intel_mnemonic", set_intel_mnemonic, 1}, - {"att_mnemonic", set_intel_mnemonic, 0}, - {"allow_index_reg", set_allow_index_reg, 1}, - {"disallow_index_reg", set_allow_index_reg, 0}, - {"sse_check", set_sse_check, 0}, -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - {"largecomm", handle_large_common, 0}, -#else - {"file", (void (*) (int)) dwarf2_directive_file, 0}, - {"loc", dwarf2_directive_loc, 0}, - {"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0}, -#endif -#ifdef TE_PE - {"secrel32", pe_directive_secrel, 0}, -#endif - {0, 0, 0} -}; - -/* For interface with expression (). */ -extern char *input_line_pointer; - -/* Hash table for instruction mnemonic lookup. */ -static struct hash_control *op_hash; - -/* Hash table for register lookup. */ -static struct hash_control *reg_hash; - -void -i386_align_code (fragS *fragP, int count) -{ - /* Various efficient no-op patterns for aligning code labels. - Note: Don't try to assemble the instructions in the comments. - 0L and 0w are not legal. */ - static const char f32_1[] = - {0x90}; /* nop */ - static const char f32_2[] = - {0x66,0x90}; /* xchg %ax,%ax */ - static const char f32_3[] = - {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */ - static const char f32_4[] = - {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const char f32_5[] = - {0x90, /* nop */ - 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ - static const char f32_6[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */ - static const char f32_7[] = - {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const char f32_8[] = - {0x90, /* nop */ - 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ - static const char f32_9[] = - {0x89,0xf6, /* movl %esi,%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_10[] = - {0x8d,0x76,0x00, /* leal 0(%esi),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_11[] = - {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_12[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ - 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */ - static const char f32_13[] = - {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f32_14[] = - {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */ - 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ - static const char f16_3[] = - {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */ - static const char f16_4[] = - {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ - static const char f16_5[] = - {0x90, /* nop */ - 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ - static const char f16_6[] = - {0x89,0xf6, /* mov %si,%si */ - 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char f16_7[] = - {0x8d,0x74,0x00, /* lea 0(%si),%si */ - 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char f16_8[] = - {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */ - 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ - static const char jump_31[] = - {0xeb,0x1d,0x90,0x90,0x90,0x90,0x90, /* jmp .+31; lotsa nops */ - 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, - 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, - 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; - static const char *const f32_patt[] = { - f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8, - f32_9, f32_10, f32_11, f32_12, f32_13, f32_14 - }; - static const char *const f16_patt[] = { - f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8 - }; - /* nopl (%[re]ax) */ - static const char alt_3[] = - {0x0f,0x1f,0x00}; - /* nopl 0(%[re]ax) */ - static const char alt_4[] = - {0x0f,0x1f,0x40,0x00}; - /* nopl 0(%[re]ax,%[re]ax,1) */ - static const char alt_5[] = - {0x0f,0x1f,0x44,0x00,0x00}; - /* nopw 0(%[re]ax,%[re]ax,1) */ - static const char alt_6[] = - {0x66,0x0f,0x1f,0x44,0x00,0x00}; - /* nopl 0L(%[re]ax) */ - static const char alt_7[] = - {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; - /* nopl 0L(%[re]ax,%[re]ax,1) */ - static const char alt_8[] = - {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* nopw 0L(%[re]ax,%[re]ax,1) */ - static const char alt_9[] = - {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_10[] = - {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* data16 - nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_long_11[] = - {0x66, - 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* data16 - data16 - nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_long_12[] = - {0x66, - 0x66, - 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* data16 - data16 - data16 - nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_long_13[] = - {0x66, - 0x66, - 0x66, - 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* data16 - data16 - data16 - data16 - nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_long_14[] = - {0x66, - 0x66, - 0x66, - 0x66, - 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* data16 - data16 - data16 - data16 - data16 - nopw %cs:0L(%[re]ax,%[re]ax,1) */ - static const char alt_long_15[] = - {0x66, - 0x66, - 0x66, - 0x66, - 0x66, - 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - /* nopl 0(%[re]ax,%[re]ax,1) - nopw 0(%[re]ax,%[re]ax,1) */ - static const char alt_short_11[] = - {0x0f,0x1f,0x44,0x00,0x00, - 0x66,0x0f,0x1f,0x44,0x00,0x00}; - /* nopw 0(%[re]ax,%[re]ax,1) - nopw 0(%[re]ax,%[re]ax,1) */ - static const char alt_short_12[] = - {0x66,0x0f,0x1f,0x44,0x00,0x00, - 0x66,0x0f,0x1f,0x44,0x00,0x00}; - /* nopw 0(%[re]ax,%[re]ax,1) - nopl 0L(%[re]ax) */ - static const char alt_short_13[] = - {0x66,0x0f,0x1f,0x44,0x00,0x00, - 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; - /* nopl 0L(%[re]ax) - nopl 0L(%[re]ax) */ - static const char alt_short_14[] = - {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00, - 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; - /* nopl 0L(%[re]ax) - nopl 0L(%[re]ax,%[re]ax,1) */ - static const char alt_short_15[] = - {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00, - 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; - static const char *const alt_short_patt[] = { - f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, - alt_9, alt_10, alt_short_11, alt_short_12, alt_short_13, - alt_short_14, alt_short_15 - }; - static const char *const alt_long_patt[] = { - f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, - alt_9, alt_10, alt_long_11, alt_long_12, alt_long_13, - alt_long_14, alt_long_15 - }; - - /* Only align for at least a positive non-zero boundary. */ - if (count <= 0 || count > MAX_MEM_FOR_RS_ALIGN_CODE) - return; - - /* We need to decide which NOP sequence to use for 32bit and - 64bit. When -mtune= is used: - - 1. For PROCESSOR_I386, PROCESSOR_I486, PROCESSOR_PENTIUM and - PROCESSOR_GENERIC32, f32_patt will be used. - 2. For PROCESSOR_PENTIUMPRO, PROCESSOR_PENTIUM4, PROCESSOR_NOCONA, - PROCESSOR_CORE, PROCESSOR_CORE2, PROCESSOR_COREI7, and - PROCESSOR_GENERIC64, alt_long_patt will be used. - 3. For PROCESSOR_ATHLON, PROCESSOR_K6, PROCESSOR_K8 and - PROCESSOR_AMDFAM10, and PROCESSOR_BD, alt_short_patt - will be used. - - When -mtune= isn't used, alt_long_patt will be used if - cpu_arch_isa_flags has CpuNop. Otherwise, f32_patt will - be used. - - When -march= or .arch is used, we can't use anything beyond - cpu_arch_isa_flags. */ - - if (flag_code == CODE_16BIT) - { - if (count > 8) - { - memcpy (fragP->fr_literal + fragP->fr_fix, - jump_31, count); - /* Adjust jump offset. */ - fragP->fr_literal[fragP->fr_fix + 1] = count - 2; - } - else - memcpy (fragP->fr_literal + fragP->fr_fix, - f16_patt[count - 1], count); - } - else - { - const char *const *patt = NULL; - - if (fragP->tc_frag_data.isa == PROCESSOR_UNKNOWN) - { - /* PROCESSOR_UNKNOWN means that all ISAs may be used. */ - switch (cpu_arch_tune) - { - case PROCESSOR_UNKNOWN: - /* We use cpu_arch_isa_flags to check if we SHOULD - optimize with nops. */ - if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) - patt = alt_long_patt; - else - patt = f32_patt; - break; - case PROCESSOR_PENTIUM4: - case PROCESSOR_NOCONA: - case PROCESSOR_CORE: - case PROCESSOR_CORE2: - case PROCESSOR_COREI7: - case PROCESSOR_L1OM: - case PROCESSOR_K1OM: - case PROCESSOR_GENERIC64: - patt = alt_long_patt; - break; - case PROCESSOR_K6: - case PROCESSOR_ATHLON: - case PROCESSOR_K8: - case PROCESSOR_AMDFAM10: - case PROCESSOR_BD: - patt = alt_short_patt; - break; - case PROCESSOR_I386: - case PROCESSOR_I486: - case PROCESSOR_PENTIUM: - case PROCESSOR_PENTIUMPRO: - case PROCESSOR_GENERIC32: - patt = f32_patt; - break; - } - } - else - { - switch (fragP->tc_frag_data.tune) - { - case PROCESSOR_UNKNOWN: - /* When cpu_arch_isa is set, cpu_arch_tune shouldn't be - PROCESSOR_UNKNOWN. */ - abort (); - break; - - case PROCESSOR_I386: - case PROCESSOR_I486: - case PROCESSOR_PENTIUM: - case PROCESSOR_K6: - case PROCESSOR_ATHLON: - case PROCESSOR_K8: - case PROCESSOR_AMDFAM10: - case PROCESSOR_BD: - case PROCESSOR_GENERIC32: - /* We use cpu_arch_isa_flags to check if we CAN optimize - with nops. */ - if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) - patt = alt_short_patt; - else - patt = f32_patt; - break; - case PROCESSOR_PENTIUMPRO: - case PROCESSOR_PENTIUM4: - case PROCESSOR_NOCONA: - case PROCESSOR_CORE: - case PROCESSOR_CORE2: - case PROCESSOR_COREI7: - case PROCESSOR_L1OM: - case PROCESSOR_K1OM: - if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) - patt = alt_long_patt; - else - patt = f32_patt; - break; - case PROCESSOR_GENERIC64: - patt = alt_long_patt; - break; - } - } - - if (patt == f32_patt) - { - /* If the padding is less than 15 bytes, we use the normal - ones. Otherwise, we use a jump instruction and adjust - its offset. */ - int limit; - - /* For 64bit, the limit is 3 bytes. */ - if (flag_code == CODE_64BIT - && fragP->tc_frag_data.isa_flags.bitfield.cpulm) - limit = 3; - else - limit = 15; - if (count < limit) - memcpy (fragP->fr_literal + fragP->fr_fix, - patt[count - 1], count); - else - { - memcpy (fragP->fr_literal + fragP->fr_fix, - jump_31, count); - /* Adjust jump offset. */ - fragP->fr_literal[fragP->fr_fix + 1] = count - 2; - } - } - else - { - /* Maximum length of an instruction is 15 byte. If the - padding is greater than 15 bytes and we don't use jump, - we have to break it into smaller pieces. */ - int padding = count; - while (padding > 15) - { - padding -= 15; - memcpy (fragP->fr_literal + fragP->fr_fix + padding, - patt [14], 15); - } - - if (padding) - memcpy (fragP->fr_literal + fragP->fr_fix, - patt [padding - 1], padding); - } - } - fragP->fr_var = count; -} - -static INLINE int -operand_type_all_zero (const union i386_operand_type *x) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - if (x->array[2]) - return 0; - case 2: - if (x->array[1]) - return 0; - case 1: - return !x->array[0]; - default: - abort (); - } -} - -static INLINE void -operand_type_set (union i386_operand_type *x, unsigned int v) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - x->array[2] = v; - case 2: - x->array[1] = v; - case 1: - x->array[0] = v; - break; - default: - abort (); - } -} - -static INLINE int -operand_type_equal (const union i386_operand_type *x, - const union i386_operand_type *y) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - if (x->array[2] != y->array[2]) - return 0; - case 2: - if (x->array[1] != y->array[1]) - return 0; - case 1: - return x->array[0] == y->array[0]; - break; - default: - abort (); - } -} - -static INLINE int -cpu_flags_all_zero (const union i386_cpu_flags *x) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - if (x->array[2]) - return 0; - case 2: - if (x->array[1]) - return 0; - case 1: - return !x->array[0]; - default: - abort (); - } -} - -static INLINE void -cpu_flags_set (union i386_cpu_flags *x, unsigned int v) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - x->array[2] = v; - case 2: - x->array[1] = v; - case 1: - x->array[0] = v; - break; - default: - abort (); - } -} - -static INLINE int -cpu_flags_equal (const union i386_cpu_flags *x, - const union i386_cpu_flags *y) -{ - switch (ARRAY_SIZE(x->array)) - { - case 3: - if (x->array[2] != y->array[2]) - return 0; - case 2: - if (x->array[1] != y->array[1]) - return 0; - case 1: - return x->array[0] == y->array[0]; - break; - default: - abort (); - } -} - -static INLINE int -cpu_flags_check_cpu64 (i386_cpu_flags f) -{ - return !((flag_code == CODE_64BIT && f.bitfield.cpuno64) - || (flag_code != CODE_64BIT && f.bitfield.cpu64)); -} - -static INLINE i386_cpu_flags -cpu_flags_and (i386_cpu_flags x, i386_cpu_flags y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] &= y.array [2]; - case 2: - x.array [1] &= y.array [1]; - case 1: - x.array [0] &= y.array [0]; - break; - default: - abort (); - } - return x; -} - -static INLINE i386_cpu_flags -cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] |= y.array [2]; - case 2: - x.array [1] |= y.array [1]; - case 1: - x.array [0] |= y.array [0]; - break; - default: - abort (); - } - return x; -} - -static INLINE i386_cpu_flags -cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] &= ~y.array [2]; - case 2: - x.array [1] &= ~y.array [1]; - case 1: - x.array [0] &= ~y.array [0]; - break; - default: - abort (); - } - return x; -} - -#define CPU_FLAGS_ARCH_MATCH 0x1 -#define CPU_FLAGS_64BIT_MATCH 0x2 -#define CPU_FLAGS_AES_MATCH 0x4 -#define CPU_FLAGS_PCLMUL_MATCH 0x8 -#define CPU_FLAGS_AVX_MATCH 0x10 - -#define CPU_FLAGS_32BIT_MATCH \ - (CPU_FLAGS_ARCH_MATCH | CPU_FLAGS_AES_MATCH \ - | CPU_FLAGS_PCLMUL_MATCH | CPU_FLAGS_AVX_MATCH) -#define CPU_FLAGS_PERFECT_MATCH \ - (CPU_FLAGS_32BIT_MATCH | CPU_FLAGS_64BIT_MATCH) - -/* Return CPU flags match bits. */ - -static int -cpu_flags_match (const insn_template *t) -{ - i386_cpu_flags x = t->cpu_flags; - int match = cpu_flags_check_cpu64 (x) ? CPU_FLAGS_64BIT_MATCH : 0; - - x.bitfield.cpu64 = 0; - x.bitfield.cpuno64 = 0; - - if (cpu_flags_all_zero (&x)) - { - /* This instruction is available on all archs. */ - match |= CPU_FLAGS_32BIT_MATCH; - } - else - { - /* This instruction is available only on some archs. */ - i386_cpu_flags cpu = cpu_arch_flags; - - cpu.bitfield.cpu64 = 0; - cpu.bitfield.cpuno64 = 0; - cpu = cpu_flags_and (x, cpu); - if (!cpu_flags_all_zero (&cpu)) - { - if (x.bitfield.cpuavx) - { - /* We only need to check AES/PCLMUL/SSE2AVX with AVX. */ - if (cpu.bitfield.cpuavx) - { - /* Check SSE2AVX. */ - if (!t->opcode_modifier.sse2avx|| sse2avx) - { - match |= (CPU_FLAGS_ARCH_MATCH - | CPU_FLAGS_AVX_MATCH); - /* Check AES. */ - if (!x.bitfield.cpuaes || cpu.bitfield.cpuaes) - match |= CPU_FLAGS_AES_MATCH; - /* Check PCLMUL. */ - if (!x.bitfield.cpupclmul - || cpu.bitfield.cpupclmul) - match |= CPU_FLAGS_PCLMUL_MATCH; - } - } - else - match |= CPU_FLAGS_ARCH_MATCH; - } - else - match |= CPU_FLAGS_32BIT_MATCH; - } - } - return match; -} - -static INLINE i386_operand_type -operand_type_and (i386_operand_type x, i386_operand_type y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] &= y.array [2]; - case 2: - x.array [1] &= y.array [1]; - case 1: - x.array [0] &= y.array [0]; - break; - default: - abort (); - } - return x; -} - -static INLINE i386_operand_type -operand_type_or (i386_operand_type x, i386_operand_type y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] |= y.array [2]; - case 2: - x.array [1] |= y.array [1]; - case 1: - x.array [0] |= y.array [0]; - break; - default: - abort (); - } - return x; -} - -static INLINE i386_operand_type -operand_type_xor (i386_operand_type x, i386_operand_type y) -{ - switch (ARRAY_SIZE (x.array)) - { - case 3: - x.array [2] ^= y.array [2]; - case 2: - x.array [1] ^= y.array [1]; - case 1: - x.array [0] ^= y.array [0]; - break; - default: - abort (); - } - return x; -} - -static const i386_operand_type acc32 = OPERAND_TYPE_ACC32; -static const i386_operand_type acc64 = OPERAND_TYPE_ACC64; -static const i386_operand_type control = OPERAND_TYPE_CONTROL; -static const i386_operand_type inoutportreg - = OPERAND_TYPE_INOUTPORTREG; -static const i386_operand_type reg16_inoutportreg - = OPERAND_TYPE_REG16_INOUTPORTREG; -static const i386_operand_type disp16 = OPERAND_TYPE_DISP16; -static const i386_operand_type disp32 = OPERAND_TYPE_DISP32; -static const i386_operand_type disp32s = OPERAND_TYPE_DISP32S; -static const i386_operand_type disp16_32 = OPERAND_TYPE_DISP16_32; -static const i386_operand_type anydisp - = OPERAND_TYPE_ANYDISP; -static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM; -static const i386_operand_type regymm = OPERAND_TYPE_REGYMM; -static const i386_operand_type imm8 = OPERAND_TYPE_IMM8; -static const i386_operand_type imm8s = OPERAND_TYPE_IMM8S; -static const i386_operand_type imm16 = OPERAND_TYPE_IMM16; -static const i386_operand_type imm32 = OPERAND_TYPE_IMM32; -static const i386_operand_type imm32s = OPERAND_TYPE_IMM32S; -static const i386_operand_type imm64 = OPERAND_TYPE_IMM64; -static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32; -static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S; -static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S; -static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4; - -enum operand_type -{ - reg, - imm, - disp, - anymem -}; - -static INLINE int -operand_type_check (i386_operand_type t, enum operand_type c) -{ - switch (c) - { - case reg: - return (t.bitfield.reg8 - || t.bitfield.reg16 - || t.bitfield.reg32 - || t.bitfield.reg64); - - case imm: - return (t.bitfield.imm8 - || t.bitfield.imm8s - || t.bitfield.imm16 - || t.bitfield.imm32 - || t.bitfield.imm32s - || t.bitfield.imm64); - - case disp: - return (t.bitfield.disp8 - || t.bitfield.disp16 - || t.bitfield.disp32 - || t.bitfield.disp32s - || t.bitfield.disp64); - - case anymem: - return (t.bitfield.disp8 - || t.bitfield.disp16 - || t.bitfield.disp32 - || t.bitfield.disp32s - || t.bitfield.disp64 - || t.bitfield.baseindex); - - default: - abort (); - } - - return 0; -} - -/* Return 1 if there is no conflict in 8bit/16bit/32bit/64bit on - operand J for instruction template T. */ - -static INLINE int -match_reg_size (const insn_template *t, unsigned int j) -{ - return !((i.types[j].bitfield.byte - && !t->operand_types[j].bitfield.byte) - || (i.types[j].bitfield.word - && !t->operand_types[j].bitfield.word) - || (i.types[j].bitfield.dword - && !t->operand_types[j].bitfield.dword) - || (i.types[j].bitfield.qword - && !t->operand_types[j].bitfield.qword)); -} - -/* Return 1 if there is no conflict in any size on operand J for - instruction template T. */ - -static INLINE int -match_mem_size (const insn_template *t, unsigned int j) -{ - return (match_reg_size (t, j) - && !((i.types[j].bitfield.unspecified - && !t->operand_types[j].bitfield.unspecified) - || (i.types[j].bitfield.fword - && !t->operand_types[j].bitfield.fword) - || (i.types[j].bitfield.tbyte - && !t->operand_types[j].bitfield.tbyte) - || (i.types[j].bitfield.xmmword - && !t->operand_types[j].bitfield.xmmword) - || (i.types[j].bitfield.ymmword - && !t->operand_types[j].bitfield.ymmword))); -} - -/* Return 1 if there is no size conflict on any operands for - instruction template T. */ - -static INLINE int -operand_size_match (const insn_template *t) -{ - unsigned int j; - int match = 1; - - /* Don't check jump instructions. */ - if (t->opcode_modifier.jump - || t->opcode_modifier.jumpbyte - || t->opcode_modifier.jumpdword - || t->opcode_modifier.jumpintersegment) - return match; - - /* Check memory and accumulator operand size. */ - for (j = 0; j < i.operands; j++) - { - if (t->operand_types[j].bitfield.anysize) - continue; - - if (t->operand_types[j].bitfield.acc && !match_reg_size (t, j)) - { - match = 0; - break; - } - - if (i.types[j].bitfield.mem && !match_mem_size (t, j)) - { - match = 0; - break; - } - } - - if (match) - return match; - else if (!t->opcode_modifier.d && !t->opcode_modifier.floatd) - { -mismatch: - i.error = operand_size_mismatch; - return 0; - } - - /* Check reverse. */ - gas_assert (i.operands == 2); - - match = 1; - for (j = 0; j < 2; j++) - { - if (t->operand_types[j].bitfield.acc - && !match_reg_size (t, j ? 0 : 1)) - goto mismatch; - - if (i.types[j].bitfield.mem - && !match_mem_size (t, j ? 0 : 1)) - goto mismatch; - } - - return match; -} - -static INLINE int -operand_type_match (i386_operand_type overlap, - i386_operand_type given) -{ - i386_operand_type temp = overlap; - - temp.bitfield.jumpabsolute = 0; - temp.bitfield.unspecified = 0; - temp.bitfield.byte = 0; - temp.bitfield.word = 0; - temp.bitfield.dword = 0; - temp.bitfield.fword = 0; - temp.bitfield.qword = 0; - temp.bitfield.tbyte = 0; - temp.bitfield.xmmword = 0; - temp.bitfield.ymmword = 0; - if (operand_type_all_zero (&temp)) - goto mismatch; - - if (given.bitfield.baseindex == overlap.bitfield.baseindex - && given.bitfield.jumpabsolute == overlap.bitfield.jumpabsolute) - return 1; - -mismatch: - i.error = operand_type_mismatch; - return 0; -} - -/* If given types g0 and g1 are registers they must be of the same type - unless the expected operand type register overlap is null. - Note that Acc in a template matches every size of reg. */ - -static INLINE int -operand_type_register_match (i386_operand_type m0, - i386_operand_type g0, - i386_operand_type t0, - i386_operand_type m1, - i386_operand_type g1, - i386_operand_type t1) -{ - if (!operand_type_check (g0, reg)) - return 1; - - if (!operand_type_check (g1, reg)) - return 1; - - if (g0.bitfield.reg8 == g1.bitfield.reg8 - && g0.bitfield.reg16 == g1.bitfield.reg16 - && g0.bitfield.reg32 == g1.bitfield.reg32 - && g0.bitfield.reg64 == g1.bitfield.reg64) - return 1; - - if (m0.bitfield.acc) - { - t0.bitfield.reg8 = 1; - t0.bitfield.reg16 = 1; - t0.bitfield.reg32 = 1; - t0.bitfield.reg64 = 1; - } - - if (m1.bitfield.acc) - { - t1.bitfield.reg8 = 1; - t1.bitfield.reg16 = 1; - t1.bitfield.reg32 = 1; - t1.bitfield.reg64 = 1; - } - - if (!(t0.bitfield.reg8 & t1.bitfield.reg8) - && !(t0.bitfield.reg16 & t1.bitfield.reg16) - && !(t0.bitfield.reg32 & t1.bitfield.reg32) - && !(t0.bitfield.reg64 & t1.bitfield.reg64)) - return 1; - - i.error = register_type_mismatch; - - return 0; -} - -static INLINE unsigned int -mode_from_disp_size (i386_operand_type t) -{ - if (t.bitfield.disp8) - return 1; - else if (t.bitfield.disp16 - || t.bitfield.disp32 - || t.bitfield.disp32s) - return 2; - else - return 0; -} - -static INLINE int -fits_in_signed_byte (offsetT num) -{ - return (num >= -128) && (num <= 127); -} - -static INLINE int -fits_in_unsigned_byte (offsetT num) -{ - return (num & 0xff) == num; -} - -static INLINE int -fits_in_unsigned_word (offsetT num) -{ - return (num & 0xffff) == num; -} - -static INLINE int -fits_in_signed_word (offsetT num) -{ - return (-32768 <= num) && (num <= 32767); -} - -static INLINE int -fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED) -{ -#ifndef BFD64 - return 1; -#else - return (!(((offsetT) -1 << 31) & num) - || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31)); -#endif -} /* fits_in_signed_long() */ - -static INLINE int -fits_in_unsigned_long (offsetT num ATTRIBUTE_UNUSED) -{ -#ifndef BFD64 - return 1; -#else - return (num & (((offsetT) 2 << 31) - 1)) == num; -#endif -} /* fits_in_unsigned_long() */ - -static INLINE int -fits_in_imm4 (offsetT num) -{ - return (num & 0xf) == num; -} - -static i386_operand_type -smallest_imm_type (offsetT num) -{ - i386_operand_type t; - - operand_type_set (&t, 0); - t.bitfield.imm64 = 1; - - if (cpu_arch_tune != PROCESSOR_I486 && num == 1) - { - /* This code is disabled on the 486 because all the Imm1 forms - in the opcode table are slower on the i486. They're the - versions with the implicitly specified single-position - displacement, which has another syntax if you really want to - use that form. */ - t.bitfield.imm1 = 1; - t.bitfield.imm8 = 1; - t.bitfield.imm8s = 1; - t.bitfield.imm16 = 1; - t.bitfield.imm32 = 1; - t.bitfield.imm32s = 1; - } - else if (fits_in_signed_byte (num)) - { - t.bitfield.imm8 = 1; - t.bitfield.imm8s = 1; - t.bitfield.imm16 = 1; - t.bitfield.imm32 = 1; - t.bitfield.imm32s = 1; - } - else if (fits_in_unsigned_byte (num)) - { - t.bitfield.imm8 = 1; - t.bitfield.imm16 = 1; - t.bitfield.imm32 = 1; - t.bitfield.imm32s = 1; - } - else if (fits_in_signed_word (num) || fits_in_unsigned_word (num)) - { - t.bitfield.imm16 = 1; - t.bitfield.imm32 = 1; - t.bitfield.imm32s = 1; - } - else if (fits_in_signed_long (num)) - { - t.bitfield.imm32 = 1; - t.bitfield.imm32s = 1; - } - else if (fits_in_unsigned_long (num)) - t.bitfield.imm32 = 1; - - return t; -} - -static offsetT -offset_in_range (offsetT val, int size) -{ - addressT mask; - - switch (size) - { - case 1: mask = ((addressT) 1 << 8) - 1; break; - case 2: mask = ((addressT) 1 << 16) - 1; break; - case 4: mask = ((addressT) 2 << 31) - 1; break; -#ifdef BFD64 - case 8: mask = ((addressT) 2 << 63) - 1; break; -#endif - default: abort (); - } - -#ifdef BFD64 - /* If BFD64, sign extend val for 32bit address mode. */ - if (flag_code != CODE_64BIT - || i.prefix[ADDR_PREFIX]) - if ((val & ~(((addressT) 2 << 31) - 1)) == 0) - val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31); -#endif - - if ((val & ~mask) != 0 && (val & ~mask) != ~mask) - { - char buf1[40], buf2[40]; - - sprint_value (buf1, val); - sprint_value (buf2, val & mask); - as_warn (_("%s shortened to %s"), buf1, buf2); - } - return val & mask; -} - -enum PREFIX_GROUP -{ - PREFIX_EXIST = 0, - PREFIX_LOCK, - PREFIX_REP, - PREFIX_OTHER -}; - -/* Returns - a. PREFIX_EXIST if attempting to add a prefix where one from the - same class already exists. - b. PREFIX_LOCK if lock prefix is added. - c. PREFIX_REP if rep/repne prefix is added. - d. PREFIX_OTHER if other prefix is added. - */ - -static enum PREFIX_GROUP -add_prefix (unsigned int prefix) -{ - enum PREFIX_GROUP ret = PREFIX_OTHER; - unsigned int q; - - if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16 - && flag_code == CODE_64BIT) - { - if ((i.prefix[REX_PREFIX] & prefix & REX_W) - || ((i.prefix[REX_PREFIX] & (REX_R | REX_X | REX_B)) - && (prefix & (REX_R | REX_X | REX_B)))) - ret = PREFIX_EXIST; - q = REX_PREFIX; - } - else - { - switch (prefix) - { - default: - abort (); - - case CS_PREFIX_OPCODE: - case DS_PREFIX_OPCODE: - case ES_PREFIX_OPCODE: - case FS_PREFIX_OPCODE: - case GS_PREFIX_OPCODE: - case SS_PREFIX_OPCODE: - q = SEG_PREFIX; - break; - - case REPNE_PREFIX_OPCODE: - case REPE_PREFIX_OPCODE: - q = REP_PREFIX; - ret = PREFIX_REP; - break; - - case LOCK_PREFIX_OPCODE: - q = LOCK_PREFIX; - ret = PREFIX_LOCK; - break; - - case FWAIT_OPCODE: - q = WAIT_PREFIX; - break; - - case ADDR_PREFIX_OPCODE: - q = ADDR_PREFIX; - break; - - case DATA_PREFIX_OPCODE: - q = DATA_PREFIX; - break; - } - if (i.prefix[q] != 0) - ret = PREFIX_EXIST; - } - - if (ret) - { - if (!i.prefix[q]) - ++i.prefixes; - i.prefix[q] |= prefix; - } - else - as_bad (_("same type of prefix used twice")); - - return ret; -} - -static void -update_code_flag (int value, int check) -{ - PRINTF_LIKE ((*as_error)); - - flag_code = (enum flag_code) value; - if (flag_code == CODE_64BIT) - { - cpu_arch_flags.bitfield.cpu64 = 1; - cpu_arch_flags.bitfield.cpuno64 = 0; - } - else - { - cpu_arch_flags.bitfield.cpu64 = 0; - cpu_arch_flags.bitfield.cpuno64 = 1; - } - if (value == CODE_64BIT && !cpu_arch_flags.bitfield.cpulm ) - { - if (check) - as_error = as_fatal; - else - as_error = as_bad; - (*as_error) (_("64bit mode not supported on `%s'."), - cpu_arch_name ? cpu_arch_name : default_arch); - } - if (value == CODE_32BIT && !cpu_arch_flags.bitfield.cpui386) - { - if (check) - as_error = as_fatal; - else - as_error = as_bad; - (*as_error) (_("32bit mode not supported on `%s'."), - cpu_arch_name ? cpu_arch_name : default_arch); - } - stackop_size = '\0'; -} - -static void -set_code_flag (int value) -{ - update_code_flag (value, 0); -} - -static void -set_16bit_gcc_code_flag (int new_code_flag) -{ - flag_code = (enum flag_code) new_code_flag; - if (flag_code != CODE_16BIT) - abort (); - cpu_arch_flags.bitfield.cpu64 = 0; - cpu_arch_flags.bitfield.cpuno64 = 1; - stackop_size = LONG_MNEM_SUFFIX; -} - -static void -set_intel_syntax (int syntax_flag) -{ - /* Find out if register prefixing is specified. */ - int ask_naked_reg = 0; - - SKIP_WHITESPACE (); - if (!is_end_of_line[(unsigned char) *input_line_pointer]) - { - char *string = input_line_pointer; - int e = get_symbol_end (); - - if (strcmp (string, "prefix") == 0) - ask_naked_reg = 1; - else if (strcmp (string, "noprefix") == 0) - ask_naked_reg = -1; - else - as_bad (_("bad argument to syntax directive.")); - *input_line_pointer = e; - } - demand_empty_rest_of_line (); - - intel_syntax = syntax_flag; - - if (ask_naked_reg == 0) - allow_naked_reg = (intel_syntax - && (bfd_get_symbol_leading_char (stdoutput) != '\0')); - else - allow_naked_reg = (ask_naked_reg < 0); - - expr_set_rank (O_full_ptr, syntax_flag ? 10 : 0); - - identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0; - identifier_chars['$'] = intel_syntax ? '$' : 0; - register_prefix = allow_naked_reg ? "" : "%"; -} - -static void -set_intel_mnemonic (int mnemonic_flag) -{ - intel_mnemonic = mnemonic_flag; -} - -static void -set_allow_index_reg (int flag) -{ - allow_index_reg = flag; -} - -static void -set_sse_check (int dummy ATTRIBUTE_UNUSED) -{ - SKIP_WHITESPACE (); - - if (!is_end_of_line[(unsigned char) *input_line_pointer]) - { - char *string = input_line_pointer; - int e = get_symbol_end (); - - if (strcmp (string, "none") == 0) - sse_check = sse_check_none; - else if (strcmp (string, "warning") == 0) - sse_check = sse_check_warning; - else if (strcmp (string, "error") == 0) - sse_check = sse_check_error; - else - as_bad (_("bad argument to sse_check directive.")); - *input_line_pointer = e; - } - else - as_bad (_("missing argument for sse_check directive")); - - demand_empty_rest_of_line (); -} - -static void -check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED, - i386_cpu_flags new_flag ATTRIBUTE_UNUSED) -{ -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - static const char *arch; - - /* Intel LIOM is only supported on ELF. */ - if (!IS_ELF) - return; - - if (!arch) - { - /* Use cpu_arch_name if it is set in md_parse_option. Otherwise - use default_arch. */ - arch = cpu_arch_name; - if (!arch) - arch = default_arch; - } - - /* If we are targeting Intel L1OM, we must enable it. */ - if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_L1OM - || new_flag.bitfield.cpul1om) - return; - - /* If we are targeting Intel K1OM, we must enable it. */ - if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_K1OM - || new_flag.bitfield.cpuk1om) - return; - - as_bad (_("`%s' is not supported on `%s'"), name, arch); -#endif -} - -static void -set_cpu_arch (int dummy ATTRIBUTE_UNUSED) -{ - SKIP_WHITESPACE (); - - if (!is_end_of_line[(unsigned char) *input_line_pointer]) - { - char *string = input_line_pointer; - int e = get_symbol_end (); - unsigned int j; - i386_cpu_flags flags; - - for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) - { - if (strcmp (string, cpu_arch[j].name) == 0) - { - check_cpu_arch_compatible (string, cpu_arch[j].flags); - - if (*string != '.') - { - cpu_arch_name = cpu_arch[j].name; - cpu_sub_arch_name = NULL; - cpu_arch_flags = cpu_arch[j].flags; - if (flag_code == CODE_64BIT) - { - cpu_arch_flags.bitfield.cpu64 = 1; - cpu_arch_flags.bitfield.cpuno64 = 0; - } - else - { - cpu_arch_flags.bitfield.cpu64 = 0; - cpu_arch_flags.bitfield.cpuno64 = 1; - } - cpu_arch_isa = cpu_arch[j].type; - cpu_arch_isa_flags = cpu_arch[j].flags; - if (!cpu_arch_tune_set) - { - cpu_arch_tune = cpu_arch_isa; - cpu_arch_tune_flags = cpu_arch_isa_flags; - } - break; - } - - if (!cpu_arch[j].negated) - flags = cpu_flags_or (cpu_arch_flags, - cpu_arch[j].flags); - else - flags = cpu_flags_and_not (cpu_arch_flags, - cpu_arch[j].flags); - if (!cpu_flags_equal (&flags, &cpu_arch_flags)) - { - if (cpu_sub_arch_name) - { - char *name = cpu_sub_arch_name; - cpu_sub_arch_name = concat (name, - cpu_arch[j].name, - (const char *) NULL); - free (name); - } - else - cpu_sub_arch_name = xstrdup (cpu_arch[j].name); - cpu_arch_flags = flags; - cpu_arch_isa_flags = flags; - } - *input_line_pointer = e; - demand_empty_rest_of_line (); - return; - } - } - if (j >= ARRAY_SIZE (cpu_arch)) - as_bad (_("no such architecture: `%s'"), string); - - *input_line_pointer = e; - } - else - as_bad (_("missing cpu architecture")); - - no_cond_jump_promotion = 0; - if (*input_line_pointer == ',' - && !is_end_of_line[(unsigned char) input_line_pointer[1]]) - { - char *string = ++input_line_pointer; - int e = get_symbol_end (); - - if (strcmp (string, "nojumps") == 0) - no_cond_jump_promotion = 1; - else if (strcmp (string, "jumps") == 0) - ; - else - as_bad (_("no such architecture modifier: `%s'"), string); - - *input_line_pointer = e; - } - - demand_empty_rest_of_line (); -} - -enum bfd_architecture -i386_arch (void) -{ - if (cpu_arch_isa == PROCESSOR_L1OM) - { - if (OUTPUT_FLAVOR != bfd_target_elf_flavour - || flag_code != CODE_64BIT) - as_fatal (_("Intel L1OM is 64bit ELF only")); - return bfd_arch_l1om; - } - else if (cpu_arch_isa == PROCESSOR_K1OM) - { - if (OUTPUT_FLAVOR != bfd_target_elf_flavour - || flag_code != CODE_64BIT) - as_fatal (_("Intel K1OM is 64bit ELF only")); - return bfd_arch_k1om; - } - else - return bfd_arch_i386; -} - -unsigned long -i386_mach (void) -{ - if (!strncmp (default_arch, "x86_64", 6)) - { - if (cpu_arch_isa == PROCESSOR_L1OM) - { - if (OUTPUT_FLAVOR != bfd_target_elf_flavour - || default_arch[6] != '\0') - as_fatal (_("Intel L1OM is 64bit ELF only")); - return bfd_mach_l1om; - } - else if (cpu_arch_isa == PROCESSOR_K1OM) - { - if (OUTPUT_FLAVOR != bfd_target_elf_flavour - || default_arch[6] != '\0') - as_fatal (_("Intel K1OM is 64bit ELF only")); - return bfd_mach_k1om; - } - else if (default_arch[6] == '\0') - return bfd_mach_x86_64; - else - return bfd_mach_x64_32; - } - else if (!strcmp (default_arch, "i386")) - return bfd_mach_i386_i386; - else - as_fatal (_("unknown architecture")); -} - -void -md_begin (void) -{ - const char *hash_err; - - /* Initialize op_hash hash table. */ - op_hash = hash_new (); - - { - const insn_template *optab; - templates *core_optab; - - /* Setup for loop. */ - optab = i386_optab; - core_optab = (templates *) xmalloc (sizeof (templates)); - core_optab->start = optab; - - while (1) - { - ++optab; - if (optab->name == NULL - || strcmp (optab->name, (optab - 1)->name) != 0) - { - /* different name --> ship out current template list; - add to hash table; & begin anew. */ - core_optab->end = optab; - hash_err = hash_insert (op_hash, - (optab - 1)->name, - (void *) core_optab); - if (hash_err) - { - as_fatal (_("internal Error: Can't hash %s: %s"), - (optab - 1)->name, - hash_err); - } - if (optab->name == NULL) - break; - core_optab = (templates *) xmalloc (sizeof (templates)); - core_optab->start = optab; - } - } - } - - /* Initialize reg_hash hash table. */ - reg_hash = hash_new (); - { - const reg_entry *regtab; - unsigned int regtab_size = i386_regtab_size; - - for (regtab = i386_regtab; regtab_size--; regtab++) - { - hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab); - if (hash_err) - as_fatal (_("internal Error: Can't hash %s: %s"), - regtab->reg_name, - hash_err); - } - } - - /* Fill in lexical tables: mnemonic_chars, operand_chars. */ - { - int c; - char *p; - - for (c = 0; c < 256; c++) - { - if (ISDIGIT (c)) - { - digit_chars[c] = c; - mnemonic_chars[c] = c; - register_chars[c] = c; - operand_chars[c] = c; - } - else if (ISLOWER (c)) - { - mnemonic_chars[c] = c; - register_chars[c] = c; - operand_chars[c] = c; - } - else if (ISUPPER (c)) - { - mnemonic_chars[c] = TOLOWER (c); - register_chars[c] = mnemonic_chars[c]; - operand_chars[c] = c; - } - - if (ISALPHA (c) || ISDIGIT (c)) - identifier_chars[c] = c; - else if (c >= 128) - { - identifier_chars[c] = c; - operand_chars[c] = c; - } - } - -#ifdef LEX_AT - identifier_chars['@'] = '@'; -#endif -#ifdef LEX_QM - identifier_chars['?'] = '?'; - operand_chars['?'] = '?'; -#endif - digit_chars['-'] = '-'; - mnemonic_chars['_'] = '_'; - mnemonic_chars['-'] = '-'; - mnemonic_chars['.'] = '.'; - identifier_chars['_'] = '_'; - identifier_chars['.'] = '.'; - - for (p = operand_special_chars; *p != '\0'; p++) - operand_chars[(unsigned char) *p] = *p; - } - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - if (IS_ELF) - { - record_alignment (text_section, 2); - record_alignment (data_section, 2); - record_alignment (bss_section, 2); - } -#endif - - if (flag_code == CODE_64BIT) - { -#if defined (OBJ_COFF) && defined (TE_PE) - x86_dwarf2_return_column = (OUTPUT_FLAVOR == bfd_target_coff_flavour - ? 32 : 16); -#else - x86_dwarf2_return_column = 16; -#endif - x86_cie_data_alignment = -8; - } - else - { - x86_dwarf2_return_column = 8; - x86_cie_data_alignment = -4; - } -} - -void -i386_print_statistics (FILE *file) -{ - hash_print_statistics (file, "i386 opcode", op_hash); - hash_print_statistics (file, "i386 register", reg_hash); -} - -#ifdef DEBUG386 - -/* Debugging routines for md_assemble. */ -static void pte (insn_template *); -static void pt (i386_operand_type); -static void pe (expressionS *); -static void ps (symbolS *); - -static void -pi (char *line, i386_insn *x) -{ - unsigned int j; - - fprintf (stdout, "%s: template ", line); - pte (&x->tm); - fprintf (stdout, " address: base %s index %s scale %x\n", - x->base_reg ? x->base_reg->reg_name : "none", - x->index_reg ? x->index_reg->reg_name : "none", - x->log2_scale_factor); - fprintf (stdout, " modrm: mode %x reg %x reg/mem %x\n", - x->rm.mode, x->rm.reg, x->rm.regmem); - fprintf (stdout, " sib: base %x index %x scale %x\n", - x->sib.base, x->sib.index, x->sib.scale); - fprintf (stdout, " rex: 64bit %x extX %x extY %x extZ %x\n", - (x->rex & REX_W) != 0, - (x->rex & REX_R) != 0, - (x->rex & REX_X) != 0, - (x->rex & REX_B) != 0); - for (j = 0; j < x->operands; j++) - { - fprintf (stdout, " #%d: ", j + 1); - pt (x->types[j]); - fprintf (stdout, "\n"); - if (x->types[j].bitfield.reg8 - || x->types[j].bitfield.reg16 - || x->types[j].bitfield.reg32 - || x->types[j].bitfield.reg64 - || x->types[j].bitfield.regmmx - || x->types[j].bitfield.regxmm - || x->types[j].bitfield.regymm - || x->types[j].bitfield.sreg2 - || x->types[j].bitfield.sreg3 - || x->types[j].bitfield.control - || x->types[j].bitfield.debug - || x->types[j].bitfield.test) - fprintf (stdout, "%s\n", x->op[j].regs->reg_name); - if (operand_type_check (x->types[j], imm)) - pe (x->op[j].imms); - if (operand_type_check (x->types[j], disp)) - pe (x->op[j].disps); - } -} - -static void -pte (insn_template *t) -{ - unsigned int j; - fprintf (stdout, " %d operands ", t->operands); - fprintf (stdout, "opcode %x ", t->base_opcode); - if (t->extension_opcode != None) - fprintf (stdout, "ext %x ", t->extension_opcode); - if (t->opcode_modifier.d) - fprintf (stdout, "D"); - if (t->opcode_modifier.w) - fprintf (stdout, "W"); - fprintf (stdout, "\n"); - for (j = 0; j < t->operands; j++) - { - fprintf (stdout, " #%d type ", j + 1); - pt (t->operand_types[j]); - fprintf (stdout, "\n"); - } -} - -static void -pe (expressionS *e) -{ - fprintf (stdout, " operation %d\n", e->X_op); - fprintf (stdout, " add_number %ld (%lx)\n", - (long) e->X_add_number, (long) e->X_add_number); - if (e->X_add_symbol) - { - fprintf (stdout, " add_symbol "); - ps (e->X_add_symbol); - fprintf (stdout, "\n"); - } - if (e->X_op_symbol) - { - fprintf (stdout, " op_symbol "); - ps (e->X_op_symbol); - fprintf (stdout, "\n"); - } -} - -static void -ps (symbolS *s) -{ - fprintf (stdout, "%s type %s%s", - S_GET_NAME (s), - S_IS_EXTERNAL (s) ? "EXTERNAL " : "", - segment_name (S_GET_SEGMENT (s))); -} - -static struct type_name - { - i386_operand_type mask; - const char *name; - } -const type_names[] = -{ - { OPERAND_TYPE_REG8, "r8" }, - { OPERAND_TYPE_REG16, "r16" }, - { OPERAND_TYPE_REG32, "r32" }, - { OPERAND_TYPE_REG64, "r64" }, - { OPERAND_TYPE_IMM8, "i8" }, - { OPERAND_TYPE_IMM8, "i8s" }, - { OPERAND_TYPE_IMM16, "i16" }, - { OPERAND_TYPE_IMM32, "i32" }, - { OPERAND_TYPE_IMM32S, "i32s" }, - { OPERAND_TYPE_IMM64, "i64" }, - { OPERAND_TYPE_IMM1, "i1" }, - { OPERAND_TYPE_BASEINDEX, "BaseIndex" }, - { OPERAND_TYPE_DISP8, "d8" }, - { OPERAND_TYPE_DISP16, "d16" }, - { OPERAND_TYPE_DISP32, "d32" }, - { OPERAND_TYPE_DISP32S, "d32s" }, - { OPERAND_TYPE_DISP64, "d64" }, - { OPERAND_TYPE_INOUTPORTREG, "InOutPortReg" }, - { OPERAND_TYPE_SHIFTCOUNT, "ShiftCount" }, - { OPERAND_TYPE_CONTROL, "control reg" }, - { OPERAND_TYPE_TEST, "test reg" }, - { OPERAND_TYPE_DEBUG, "debug reg" }, - { OPERAND_TYPE_FLOATREG, "FReg" }, - { OPERAND_TYPE_FLOATACC, "FAcc" }, - { OPERAND_TYPE_SREG2, "SReg2" }, - { OPERAND_TYPE_SREG3, "SReg3" }, - { OPERAND_TYPE_ACC, "Acc" }, - { OPERAND_TYPE_JUMPABSOLUTE, "Jump Absolute" }, - { OPERAND_TYPE_REGMMX, "rMMX" }, - { OPERAND_TYPE_REGXMM, "rXMM" }, - { OPERAND_TYPE_REGYMM, "rYMM" }, - { OPERAND_TYPE_ESSEG, "es" }, -}; - -static void -pt (i386_operand_type t) -{ - unsigned int j; - i386_operand_type a; - - for (j = 0; j < ARRAY_SIZE (type_names); j++) - { - a = operand_type_and (t, type_names[j].mask); - if (!operand_type_all_zero (&a)) - fprintf (stdout, "%s, ", type_names[j].name); - } - fflush (stdout); -} - -#endif /* DEBUG386 */ - -static bfd_reloc_code_real_type -reloc (unsigned int size, - int pcrel, - int sign, - bfd_reloc_code_real_type other) -{ - if (other != NO_RELOC) - { - reloc_howto_type *rel; - - if (size == 8) - switch (other) - { - case BFD_RELOC_X86_64_GOT32: - return BFD_RELOC_X86_64_GOT64; - break; - case BFD_RELOC_X86_64_PLTOFF64: - return BFD_RELOC_X86_64_PLTOFF64; - break; - case BFD_RELOC_X86_64_GOTPC32: - other = BFD_RELOC_X86_64_GOTPC64; - break; - case BFD_RELOC_X86_64_GOTPCREL: - other = BFD_RELOC_X86_64_GOTPCREL64; - break; - case BFD_RELOC_X86_64_TPOFF32: - other = BFD_RELOC_X86_64_TPOFF64; - break; - case BFD_RELOC_X86_64_DTPOFF32: - other = BFD_RELOC_X86_64_DTPOFF64; - break; - default: - break; - } - - /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless. */ - if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc)) - sign = -1; - - rel = bfd_reloc_type_lookup (stdoutput, other); - if (!rel) - as_bad (_("unknown relocation (%u)"), other); - else if (size != bfd_get_reloc_size (rel)) - as_bad (_("%u-byte relocation cannot be applied to %u-byte field"), - bfd_get_reloc_size (rel), - size); - else if (pcrel && !rel->pc_relative) - as_bad (_("non-pc-relative relocation for pc-relative field")); - else if ((rel->complain_on_overflow == complain_overflow_signed - && !sign) - || (rel->complain_on_overflow == complain_overflow_unsigned - && sign > 0)) - as_bad (_("relocated field and relocation type differ in signedness")); - else - return other; - return NO_RELOC; - } - - if (pcrel) - { - if (!sign) - as_bad (_("there are no unsigned pc-relative relocations")); - switch (size) - { - case 1: return BFD_RELOC_8_PCREL; - case 2: return BFD_RELOC_16_PCREL; - case 4: return BFD_RELOC_32_PCREL; - case 8: return BFD_RELOC_64_PCREL; - } - as_bad (_("cannot do %u byte pc-relative relocation"), size); - } - else - { - if (sign > 0) - switch (size) - { - case 4: return BFD_RELOC_X86_64_32S; - } - else - switch (size) - { - case 1: return BFD_RELOC_8; - case 2: return BFD_RELOC_16; - case 4: return BFD_RELOC_32; - case 8: return BFD_RELOC_64; - } - as_bad (_("cannot do %s %u byte relocation"), - sign > 0 ? "signed" : "unsigned", size); - } - - return NO_RELOC; -} - -/* Here we decide which fixups can be adjusted to make them relative to - the beginning of the section instead of the symbol. Basically we need - to make sure that the dynamic relocations are done correctly, so in - some cases we force the original symbol to be used. */ - -int -tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED) -{ -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - if (!IS_ELF) - return 1; - - /* Don't adjust pc-relative references to merge sections in 64-bit - mode. */ - if (use_rela_relocations - && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0 - && fixP->fx_pcrel) - return 0; - - /* The x86_64 GOTPCREL are represented as 32bit PCrel relocations - and changed later by validate_fix. */ - if (GOT_symbol && fixP->fx_subsy == GOT_symbol - && fixP->fx_r_type == BFD_RELOC_32_PCREL) - return 0; - - /* adjust_reloc_syms doesn't know about the GOT. */ - if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF - || fixP->fx_r_type == BFD_RELOC_386_PLT32 - || fixP->fx_r_type == BFD_RELOC_386_GOT32 - || fixP->fx_r_type == BFD_RELOC_386_TLS_GD - || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM - || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32 - || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32 - || fixP->fx_r_type == BFD_RELOC_386_TLS_IE - || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE - || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32 - || fixP->fx_r_type == BFD_RELOC_386_TLS_LE - || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTDESC - || fixP->fx_r_type == BFD_RELOC_386_TLS_DESC_CALL - || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32 - || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32 - || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL - || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD - || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD - || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32 - || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64 - || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF - || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32 - || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64 - || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64 - || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC - || fixP->fx_r_type == BFD_RELOC_X86_64_TLSDESC_CALL - || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT - || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - return 0; -#endif - return 1; -} - -static int -intel_float_operand (const char *mnemonic) -{ - /* Note that the value returned is meaningful only for opcodes with (memory) - operands, hence the code here is free to improperly handle opcodes that - have no operands (for better performance and smaller code). */ - - if (mnemonic[0] != 'f') - return 0; /* non-math */ - - switch (mnemonic[1]) - { - /* fclex, fdecstp, fdisi, femms, feni, fincstp, finit, fsetpm, and - the fs segment override prefix not currently handled because no - call path can make opcodes without operands get here */ - case 'i': - return 2 /* integer op */; - case 'l': - if (mnemonic[2] == 'd' && (mnemonic[3] == 'c' || mnemonic[3] == 'e')) - return 3; /* fldcw/fldenv */ - break; - case 'n': - if (mnemonic[2] != 'o' /* fnop */) - return 3; /* non-waiting control op */ - break; - case 'r': - if (mnemonic[2] == 's') - return 3; /* frstor/frstpm */ - break; - case 's': - if (mnemonic[2] == 'a') - return 3; /* fsave */ - if (mnemonic[2] == 't') - { - switch (mnemonic[3]) - { - case 'c': /* fstcw */ - case 'd': /* fstdw */ - case 'e': /* fstenv */ - case 's': /* fsts[gw] */ - return 3; - } - } - break; - case 'x': - if (mnemonic[2] == 'r' || mnemonic[2] == 's') - return 0; /* fxsave/fxrstor are not really math ops */ - break; - } - - return 1; -} - -/* Build the VEX prefix. */ - -static void -build_vex_prefix (const insn_template *t) -{ - unsigned int register_specifier; - unsigned int implied_prefix; - unsigned int vector_length; - - /* Check register specifier. */ - if (i.vex.register_specifier) - { - register_specifier = i.vex.register_specifier->reg_num; - if ((i.vex.register_specifier->reg_flags & RegRex)) - register_specifier += 8; - register_specifier = ~register_specifier & 0xf; - } - else - register_specifier = 0xf; - - /* Use 2-byte VEX prefix by swappping destination and source - operand. */ - if (!i.swap_operand - && i.operands == i.reg_operands - && i.tm.opcode_modifier.vexopcode == VEX0F - && i.tm.opcode_modifier.s - && i.rex == REX_B) - { - unsigned int xchg = i.operands - 1; - union i386_op temp_op; - i386_operand_type temp_type; - - temp_type = i.types[xchg]; - i.types[xchg] = i.types[0]; - i.types[0] = temp_type; - temp_op = i.op[xchg]; - i.op[xchg] = i.op[0]; - i.op[0] = temp_op; - - gas_assert (i.rm.mode == 3); - - i.rex = REX_R; - xchg = i.rm.regmem; - i.rm.regmem = i.rm.reg; - i.rm.reg = xchg; - - /* Use the next insn. */ - i.tm = t[1]; - } - - if (i.tm.opcode_modifier.vex == VEXScalar) - vector_length = avxscalar; - else - vector_length = i.tm.opcode_modifier.vex == VEX256 ? 1 : 0; - - switch ((i.tm.base_opcode >> 8) & 0xff) - { - case 0: - implied_prefix = 0; - break; - case DATA_PREFIX_OPCODE: - implied_prefix = 1; - break; - case REPE_PREFIX_OPCODE: - implied_prefix = 2; - break; - case REPNE_PREFIX_OPCODE: - implied_prefix = 3; - break; - default: - abort (); - } - - /* Use 2-byte VEX prefix if possible. */ - if (i.tm.opcode_modifier.vexopcode == VEX0F - && i.tm.opcode_modifier.vexw != VEXW1 - && (i.rex & (REX_W | REX_X | REX_B)) == 0) - { - /* 2-byte VEX prefix. */ - unsigned int r; - - i.vex.length = 2; - i.vex.bytes[0] = 0xc5; - - /* Check the REX.R bit. */ - r = (i.rex & REX_R) ? 0 : 1; - i.vex.bytes[1] = (r << 7 - | register_specifier << 3 - | vector_length << 2 - | implied_prefix); - } - else - { - /* 3-byte VEX prefix. */ - unsigned int m, w; - - i.vex.length = 3; - - switch (i.tm.opcode_modifier.vexopcode) - { - case VEX0F: - m = 0x1; - i.vex.bytes[0] = 0xc4; - break; - case VEX0F38: - m = 0x2; - i.vex.bytes[0] = 0xc4; - break; - case VEX0F3A: - m = 0x3; - i.vex.bytes[0] = 0xc4; - break; - case XOP08: - m = 0x8; - i.vex.bytes[0] = 0x8f; - break; - case XOP09: - m = 0x9; - i.vex.bytes[0] = 0x8f; - break; - case XOP0A: - m = 0xa; - i.vex.bytes[0] = 0x8f; - break; - default: - abort (); - } - - /* The high 3 bits of the second VEX byte are 1's compliment - of RXB bits from REX. */ - i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m; - - /* Check the REX.W bit. */ - w = (i.rex & REX_W) ? 1 : 0; - if (i.tm.opcode_modifier.vexw) - { - if (w) - abort (); - - if (i.tm.opcode_modifier.vexw == VEXW1) - w = 1; - } - - i.vex.bytes[2] = (w << 7 - | register_specifier << 3 - | vector_length << 2 - | implied_prefix); - } -} - -static void -process_immext (void) -{ - expressionS *exp; - - if (i.tm.cpu_flags.bitfield.cpusse3 && i.operands > 0) - { - /* SSE3 Instructions have the fixed operands with an opcode - suffix which is coded in the same place as an 8-bit immediate - field would be. Here we check those operands and remove them - afterwards. */ - unsigned int x; - - for (x = 0; x < i.operands; x++) - if (i.op[x].regs->reg_num != x) - as_bad (_("can't use register '%s%s' as operand %d in '%s'."), - register_prefix, i.op[x].regs->reg_name, x + 1, - i.tm.name); - - i.operands = 0; - } - - /* These AMD 3DNow! and SSE2 instructions have an opcode suffix - which is coded in the same place as an 8-bit immediate field - would be. Here we fake an 8-bit immediate operand from the - opcode suffix stored in tm.extension_opcode. - - AVX instructions also use this encoding, for some of - 3 argument instructions. */ - - gas_assert (i.imm_operands == 0 - && (i.operands <= 2 - || (i.tm.opcode_modifier.vex - && i.operands <= 4))); - - exp = &im_expressions[i.imm_operands++]; - i.op[i.operands].imms = exp; - i.types[i.operands] = imm8; - i.operands++; - exp->X_op = O_constant; - exp->X_add_number = i.tm.extension_opcode; - i.tm.extension_opcode = None; -} - -/* This is the guts of the machine-dependent assembler. LINE points to a - machine dependent instruction. This function is supposed to emit - the frags/bytes it assembles to. */ - -void -md_assemble (char *line) -{ - unsigned int j; - char mnemonic[MAX_MNEM_SIZE]; - const insn_template *t; - - /* Initialize globals. */ - memset (&i, '\0', sizeof (i)); - for (j = 0; j < MAX_OPERANDS; j++) - i.reloc[j] = NO_RELOC; - memset (disp_expressions, '\0', sizeof (disp_expressions)); - memset (im_expressions, '\0', sizeof (im_expressions)); - save_stack_p = save_stack; - - /* First parse an instruction mnemonic & call i386_operand for the operands. - We assume that the scrubber has arranged it so that line[0] is the valid - start of a (possibly prefixed) mnemonic. */ - - line = parse_insn (line, mnemonic); - if (line == NULL) - return; - - line = parse_operands (line, mnemonic); - this_operand = -1; - if (line == NULL) - return; - - /* Now we've parsed the mnemonic into a set of templates, and have the - operands at hand. */ - - /* All intel opcodes have reversed operands except for "bound" and - "enter". We also don't reverse intersegment "jmp" and "call" - instructions with 2 immediate operands so that the immediate segment - precedes the offset, as it does when in AT&T mode. */ - if (intel_syntax - && i.operands > 1 - && (strcmp (mnemonic, "bound") != 0) - && (strcmp (mnemonic, "invlpga") != 0) - && !(operand_type_check (i.types[0], imm) - && operand_type_check (i.types[1], imm))) - swap_operands (); - - /* The order of the immediates should be reversed - for 2 immediates extrq and insertq instructions */ - if (i.imm_operands == 2 - && (strcmp (mnemonic, "extrq") == 0 - || strcmp (mnemonic, "insertq") == 0)) - swap_2_operands (0, 1); - - if (i.imm_operands) - optimize_imm (); - - /* Don't optimize displacement for movabs since it only takes 64bit - displacement. */ - if (i.disp_operands - && !i.disp32_encoding - && (flag_code != CODE_64BIT - || strcmp (mnemonic, "movabs") != 0)) - optimize_disp (); - - /* Next, we find a template that matches the given insn, - making sure the overlap of the given operands types is consistent - with the template operand types. */ - - if (!(t = match_template ())) - return; - - if (sse_check != sse_check_none - && !i.tm.opcode_modifier.noavx - && (i.tm.cpu_flags.bitfield.cpusse - || i.tm.cpu_flags.bitfield.cpusse2 - || i.tm.cpu_flags.bitfield.cpusse3 - || i.tm.cpu_flags.bitfield.cpussse3 - || i.tm.cpu_flags.bitfield.cpusse4_1 - || i.tm.cpu_flags.bitfield.cpusse4_2)) - { - (sse_check == sse_check_warning - ? as_warn - : as_bad) (_("SSE instruction `%s' is used"), i.tm.name); - } - - /* Zap movzx and movsx suffix. The suffix has been set from - "word ptr" or "byte ptr" on the source operand in Intel syntax - or extracted from mnemonic in AT&T syntax. But we'll use - the destination register to choose the suffix for encoding. */ - if ((i.tm.base_opcode & ~9) == 0x0fb6) - { - /* In Intel syntax, there must be a suffix. In AT&T syntax, if - there is no suffix, the default will be byte extension. */ - if (i.reg_operands != 2 - && !i.suffix - && intel_syntax) - as_bad (_("ambiguous operand size for `%s'"), i.tm.name); - - i.suffix = 0; - } - - if (i.tm.opcode_modifier.fwait) - if (!add_prefix (FWAIT_OPCODE)) - return; - - /* Check for lock without a lockable instruction. Destination operand - must be memory unless it is xchg (0x86). */ - if (i.prefix[LOCK_PREFIX] - && (!i.tm.opcode_modifier.islockable - || i.mem_operands == 0 - || (i.tm.base_opcode != 0x86 - && !operand_type_check (i.types[i.operands - 1], anymem)))) - { - as_bad (_("expecting lockable instruction after `lock'")); - return; - } - - /* Check string instruction segment overrides. */ - if (i.tm.opcode_modifier.isstring && i.mem_operands != 0) - { - if (!check_string ()) - return; - i.disp_operands = 0; - } - - if (!process_suffix ()) - return; - - /* Update operand types. */ - for (j = 0; j < i.operands; j++) - i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]); - - /* Make still unresolved immediate matches conform to size of immediate - given in i.suffix. */ - if (!finalize_imm ()) - return; - - if (i.types[0].bitfield.imm1) - i.imm_operands = 0; /* kludge for shift insns. */ - - /* We only need to check those implicit registers for instructions - with 3 operands or less. */ - if (i.operands <= 3) - for (j = 0; j < i.operands; j++) - if (i.types[j].bitfield.inoutportreg - || i.types[j].bitfield.shiftcount - || i.types[j].bitfield.acc - || i.types[j].bitfield.floatacc) - i.reg_operands--; - - /* ImmExt should be processed after SSE2AVX. */ - if (!i.tm.opcode_modifier.sse2avx - && i.tm.opcode_modifier.immext) - process_immext (); - - /* For insns with operands there are more diddles to do to the opcode. */ - if (i.operands) - { - if (!process_operands ()) - return; - } - else if (!quiet_warnings && i.tm.opcode_modifier.ugh) - { - /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc. */ - as_warn (_("translating to `%sp'"), i.tm.name); - } - - if (i.tm.opcode_modifier.vex) - build_vex_prefix (t); - - /* Handle conversion of 'int $3' --> special int3 insn. XOP or FMA4 - instructions may define INT_OPCODE as well, so avoid this corner - case for those instructions that use MODRM. */ - if (i.tm.base_opcode == INT_OPCODE - && !i.tm.opcode_modifier.modrm - && i.op[0].imms->X_add_number == 3) - { - i.tm.base_opcode = INT3_OPCODE; - i.imm_operands = 0; - } - - if ((i.tm.opcode_modifier.jump - || i.tm.opcode_modifier.jumpbyte - || i.tm.opcode_modifier.jumpdword) - && i.op[0].disps->X_op == O_constant) - { - /* Convert "jmp constant" (and "call constant") to a jump (call) to - the absolute address given by the constant. Since ix86 jumps and - calls are pc relative, we need to generate a reloc. */ - i.op[0].disps->X_add_symbol = &abs_symbol; - i.op[0].disps->X_op = O_symbol; - } - - if (i.tm.opcode_modifier.rex64) - i.rex |= REX_W; - - /* For 8 bit registers we need an empty rex prefix. Also if the - instruction already has a prefix, we need to convert old - registers to new ones. */ - - if ((i.types[0].bitfield.reg8 - && (i.op[0].regs->reg_flags & RegRex64) != 0) - || (i.types[1].bitfield.reg8 - && (i.op[1].regs->reg_flags & RegRex64) != 0) - || ((i.types[0].bitfield.reg8 - || i.types[1].bitfield.reg8) - && i.rex != 0)) - { - int x; - - i.rex |= REX_OPCODE; - for (x = 0; x < 2; x++) - { - /* Look for 8 bit operand that uses old registers. */ - if (i.types[x].bitfield.reg8 - && (i.op[x].regs->reg_flags & RegRex64) == 0) - { - /* In case it is "hi" register, give up. */ - if (i.op[x].regs->reg_num > 3) - as_bad (_("can't encode register '%s%s' in an " - "instruction requiring REX prefix."), - register_prefix, i.op[x].regs->reg_name); - - /* Otherwise it is equivalent to the extended register. - Since the encoding doesn't change this is merely - cosmetic cleanup for debug output. */ - - i.op[x].regs = i.op[x].regs + 8; - } - } - } - - if (i.rex != 0) - add_prefix (REX_OPCODE | i.rex); - - /* We are ready to output the insn. */ - output_insn (); -} - -static char * -parse_insn (char *line, char *mnemonic) -{ - char *l = line; - char *token_start = l; - char *mnem_p; - int supported; - const insn_template *t; - char *dot_p = NULL; - - /* Non-zero if we found a prefix only acceptable with string insns. */ - const char *expecting_string_instruction = NULL; - - while (1) - { - mnem_p = mnemonic; - while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0) - { - if (*mnem_p == '.') - dot_p = mnem_p; - mnem_p++; - if (mnem_p >= mnemonic + MAX_MNEM_SIZE) - { - as_bad (_("no such instruction: `%s'"), token_start); - return NULL; - } - l++; - } - if (!is_space_char (*l) - && *l != END_OF_INSN - && (intel_syntax - || (*l != PREFIX_SEPARATOR - && *l != ','))) - { - as_bad (_("invalid character %s in mnemonic"), - output_invalid (*l)); - return NULL; - } - if (token_start == l) - { - if (!intel_syntax && *l == PREFIX_SEPARATOR) - as_bad (_("expecting prefix; got nothing")); - else - as_bad (_("expecting mnemonic; got nothing")); - return NULL; - } - - /* Look up instruction (or prefix) via hash table. */ - current_templates = (const templates *) hash_find (op_hash, mnemonic); - - if (*l != END_OF_INSN - && (!is_space_char (*l) || l[1] != END_OF_INSN) - && current_templates - && current_templates->start->opcode_modifier.isprefix) - { - if (!cpu_flags_check_cpu64 (current_templates->start->cpu_flags)) - { - as_bad ((flag_code != CODE_64BIT - ? _("`%s' is only supported in 64-bit mode") - : _("`%s' is not supported in 64-bit mode")), - current_templates->start->name); - return NULL; - } - /* If we are in 16-bit mode, do not allow addr16 or data16. - Similarly, in 32-bit mode, do not allow addr32 or data32. */ - if ((current_templates->start->opcode_modifier.size16 - || current_templates->start->opcode_modifier.size32) - && flag_code != CODE_64BIT - && (current_templates->start->opcode_modifier.size32 - ^ (flag_code == CODE_16BIT))) - { - as_bad (_("redundant %s prefix"), - current_templates->start->name); - return NULL; - } - /* Add prefix, checking for repeated prefixes. */ - switch (add_prefix (current_templates->start->base_opcode)) - { - case PREFIX_EXIST: - return NULL; - case PREFIX_REP: - expecting_string_instruction = current_templates->start->name; - break; - default: - break; - } - /* Skip past PREFIX_SEPARATOR and reset token_start. */ - token_start = ++l; - } - else - break; - } - - if (!current_templates) - { - /* Check if we should swap operand or force 32bit displacement in - encoding. */ - if (mnem_p - 2 == dot_p && dot_p[1] == 's') - i.swap_operand = 1; - else if (mnem_p - 4 == dot_p - && dot_p[1] == 'd' - && dot_p[2] == '3' - && dot_p[3] == '2') - i.disp32_encoding = 1; - else - goto check_suffix; - mnem_p = dot_p; - *dot_p = '\0'; - current_templates = (const templates *) hash_find (op_hash, mnemonic); - } - - if (!current_templates) - { -check_suffix: - /* See if we can get a match by trimming off a suffix. */ - switch (mnem_p[-1]) - { - case WORD_MNEM_SUFFIX: - if (intel_syntax && (intel_float_operand (mnemonic) & 2)) - i.suffix = SHORT_MNEM_SUFFIX; - else - case BYTE_MNEM_SUFFIX: - case QWORD_MNEM_SUFFIX: - i.suffix = mnem_p[-1]; - mnem_p[-1] = '\0'; - current_templates = (const templates *) hash_find (op_hash, - mnemonic); - break; - case SHORT_MNEM_SUFFIX: - case LONG_MNEM_SUFFIX: - if (!intel_syntax) - { - i.suffix = mnem_p[-1]; - mnem_p[-1] = '\0'; - current_templates = (const templates *) hash_find (op_hash, - mnemonic); - } - break; - - /* Intel Syntax. */ - case 'd': - if (intel_syntax) - { - if (intel_float_operand (mnemonic) == 1) - i.suffix = SHORT_MNEM_SUFFIX; - else - i.suffix = LONG_MNEM_SUFFIX; - mnem_p[-1] = '\0'; - current_templates = (const templates *) hash_find (op_hash, - mnemonic); - } - break; - } - if (!current_templates) - { - as_bad (_("no such instruction: `%s'"), token_start); - return NULL; - } - } - - if (current_templates->start->opcode_modifier.jump - || current_templates->start->opcode_modifier.jumpbyte) - { - /* Check for a branch hint. We allow ",pt" and ",pn" for - predict taken and predict not taken respectively. - I'm not sure that branch hints actually do anything on loop - and jcxz insns (JumpByte) for current Pentium4 chips. They - may work in the future and it doesn't hurt to accept them - now. */ - if (l[0] == ',' && l[1] == 'p') - { - if (l[2] == 't') - { - if (!add_prefix (DS_PREFIX_OPCODE)) - return NULL; - l += 3; - } - else if (l[2] == 'n') - { - if (!add_prefix (CS_PREFIX_OPCODE)) - return NULL; - l += 3; - } - } - } - /* Any other comma loses. */ - if (*l == ',') - { - as_bad (_("invalid character %s in mnemonic"), - output_invalid (*l)); - return NULL; - } - - /* Check if instruction is supported on specified architecture. */ - supported = 0; - for (t = current_templates->start; t < current_templates->end; ++t) - { - supported |= cpu_flags_match (t); - if (supported == CPU_FLAGS_PERFECT_MATCH) - goto skip; - } - - if (!(supported & CPU_FLAGS_64BIT_MATCH)) - { - as_bad (flag_code == CODE_64BIT - ? _("`%s' is not supported in 64-bit mode") - : _("`%s' is only supported in 64-bit mode"), - current_templates->start->name); - return NULL; - } - if (supported != CPU_FLAGS_PERFECT_MATCH) - { - as_bad (_("`%s' is not supported on `%s%s'"), - current_templates->start->name, - cpu_arch_name ? cpu_arch_name : default_arch, - cpu_sub_arch_name ? cpu_sub_arch_name : ""); - return NULL; - } - -skip: - if (!cpu_arch_flags.bitfield.cpui386 - && (flag_code != CODE_16BIT)) - { - as_warn (_("use .code16 to ensure correct addressing mode")); - } - - /* Check for rep/repne without a string instruction. */ - if (expecting_string_instruction) - { - static templates override; - - for (t = current_templates->start; t < current_templates->end; ++t) - if (t->opcode_modifier.isstring) - break; - if (t >= current_templates->end) - { - as_bad (_("expecting string instruction after `%s'"), - expecting_string_instruction); - return NULL; - } - for (override.start = t; t < current_templates->end; ++t) - if (!t->opcode_modifier.isstring) - break; - override.end = t; - current_templates = &override; - } - - return l; -} - -static char * -parse_operands (char *l, const char *mnemonic) -{ - char *token_start; - - /* 1 if operand is pending after ','. */ - unsigned int expecting_operand = 0; - - /* Non-zero if operand parens not balanced. */ - unsigned int paren_not_balanced; - - while (*l != END_OF_INSN) - { - /* Skip optional white space before operand. */ - if (is_space_char (*l)) - ++l; - if (!is_operand_char (*l) && *l != END_OF_INSN) - { - as_bad (_("invalid character %s before operand %d"), - output_invalid (*l), - i.operands + 1); - return NULL; - } - token_start = l; /* after white space */ - paren_not_balanced = 0; - while (paren_not_balanced || *l != ',') - { - if (*l == END_OF_INSN) - { - if (paren_not_balanced) - { - if (!intel_syntax) - as_bad (_("unbalanced parenthesis in operand %d."), - i.operands + 1); - else - as_bad (_("unbalanced brackets in operand %d."), - i.operands + 1); - return NULL; - } - else - break; /* we are done */ - } - else if (!is_operand_char (*l) && !is_space_char (*l)) - { - as_bad (_("invalid character %s in operand %d"), - output_invalid (*l), - i.operands + 1); - return NULL; - } - if (!intel_syntax) - { - if (*l == '(') - ++paren_not_balanced; - if (*l == ')') - --paren_not_balanced; - } - else - { - if (*l == '[') - ++paren_not_balanced; - if (*l == ']') - --paren_not_balanced; - } - l++; - } - if (l != token_start) - { /* Yes, we've read in another operand. */ - unsigned int operand_ok; - this_operand = i.operands++; - i.types[this_operand].bitfield.unspecified = 1; - if (i.operands > MAX_OPERANDS) - { - as_bad (_("spurious operands; (%d operands/instruction max)"), - MAX_OPERANDS); - return NULL; - } - /* Now parse operand adding info to 'i' as we go along. */ - END_STRING_AND_SAVE (l); - - if (intel_syntax) - operand_ok = - i386_intel_operand (token_start, - intel_float_operand (mnemonic)); - else - operand_ok = i386_att_operand (token_start); - - RESTORE_END_STRING (l); - if (!operand_ok) - return NULL; - } - else - { - if (expecting_operand) - { - expecting_operand_after_comma: - as_bad (_("expecting operand after ','; got nothing")); - return NULL; - } - if (*l == ',') - { - as_bad (_("expecting operand before ','; got nothing")); - return NULL; - } - } - - /* Now *l must be either ',' or END_OF_INSN. */ - if (*l == ',') - { - if (*++l == END_OF_INSN) - { - /* Just skip it, if it's \n complain. */ - goto expecting_operand_after_comma; - } - expecting_operand = 1; - } - } - return l; -} - -static void -swap_2_operands (int xchg1, int xchg2) -{ - union i386_op temp_op; - i386_operand_type temp_type; - enum bfd_reloc_code_real temp_reloc; - - temp_type = i.types[xchg2]; - i.types[xchg2] = i.types[xchg1]; - i.types[xchg1] = temp_type; - temp_op = i.op[xchg2]; - i.op[xchg2] = i.op[xchg1]; - i.op[xchg1] = temp_op; - temp_reloc = i.reloc[xchg2]; - i.reloc[xchg2] = i.reloc[xchg1]; - i.reloc[xchg1] = temp_reloc; -} - -static void -swap_operands (void) -{ - switch (i.operands) - { - case 5: - case 4: - swap_2_operands (1, i.operands - 2); - case 3: - case 2: - swap_2_operands (0, i.operands - 1); - break; - default: - abort (); - } - - if (i.mem_operands == 2) - { - const seg_entry *temp_seg; - temp_seg = i.seg[0]; - i.seg[0] = i.seg[1]; - i.seg[1] = temp_seg; - } -} - -/* Try to ensure constant immediates are represented in the smallest - opcode possible. */ -static void -optimize_imm (void) -{ - char guess_suffix = 0; - int op; - - if (i.suffix) - guess_suffix = i.suffix; - else if (i.reg_operands) - { - /* Figure out a suffix from the last register operand specified. - We can't do this properly yet, ie. excluding InOutPortReg, - but the following works for instructions with immediates. - In any case, we can't set i.suffix yet. */ - for (op = i.operands; --op >= 0;) - if (i.types[op].bitfield.reg8) - { - guess_suffix = BYTE_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg16) - { - guess_suffix = WORD_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg32) - { - guess_suffix = LONG_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg64) - { - guess_suffix = QWORD_MNEM_SUFFIX; - break; - } - } - else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)) - guess_suffix = WORD_MNEM_SUFFIX; - - for (op = i.operands; --op >= 0;) - if (operand_type_check (i.types[op], imm)) - { - switch (i.op[op].imms->X_op) - { - case O_constant: - /* If a suffix is given, this operand may be shortened. */ - switch (guess_suffix) - { - case LONG_MNEM_SUFFIX: - i.types[op].bitfield.imm32 = 1; - i.types[op].bitfield.imm64 = 1; - break; - case WORD_MNEM_SUFFIX: - i.types[op].bitfield.imm16 = 1; - i.types[op].bitfield.imm32 = 1; - i.types[op].bitfield.imm32s = 1; - i.types[op].bitfield.imm64 = 1; - break; - case BYTE_MNEM_SUFFIX: - i.types[op].bitfield.imm8 = 1; - i.types[op].bitfield.imm8s = 1; - i.types[op].bitfield.imm16 = 1; - i.types[op].bitfield.imm32 = 1; - i.types[op].bitfield.imm32s = 1; - i.types[op].bitfield.imm64 = 1; - break; - } - - /* If this operand is at most 16 bits, convert it - to a signed 16 bit number before trying to see - whether it will fit in an even smaller size. - This allows a 16-bit operand such as $0xffe0 to - be recognised as within Imm8S range. */ - if ((i.types[op].bitfield.imm16) - && (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0) - { - i.op[op].imms->X_add_number = - (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000); - } - if ((i.types[op].bitfield.imm32) - && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1)) - == 0)) - { - i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number - ^ ((offsetT) 1 << 31)) - - ((offsetT) 1 << 31)); - } - i.types[op] - = operand_type_or (i.types[op], - smallest_imm_type (i.op[op].imms->X_add_number)); - - /* We must avoid matching of Imm32 templates when 64bit - only immediate is available. */ - if (guess_suffix == QWORD_MNEM_SUFFIX) - i.types[op].bitfield.imm32 = 0; - break; - - case O_absent: - case O_register: - abort (); - - /* Symbols and expressions. */ - default: - /* Convert symbolic operand to proper sizes for matching, but don't - prevent matching a set of insns that only supports sizes other - than those matching the insn suffix. */ - { - i386_operand_type mask, allowed; - const insn_template *t; - - operand_type_set (&mask, 0); - operand_type_set (&allowed, 0); - - for (t = current_templates->start; - t < current_templates->end; - ++t) - allowed = operand_type_or (allowed, - t->operand_types[op]); - switch (guess_suffix) - { - case QWORD_MNEM_SUFFIX: - mask.bitfield.imm64 = 1; - mask.bitfield.imm32s = 1; - break; - case LONG_MNEM_SUFFIX: - mask.bitfield.imm32 = 1; - break; - case WORD_MNEM_SUFFIX: - mask.bitfield.imm16 = 1; - break; - case BYTE_MNEM_SUFFIX: - mask.bitfield.imm8 = 1; - break; - default: - break; - } - allowed = operand_type_and (mask, allowed); - if (!operand_type_all_zero (&allowed)) - i.types[op] = operand_type_and (i.types[op], mask); - } - break; - } - } -} - -/* Try to use the smallest displacement type too. */ -static void -optimize_disp (void) -{ - int op; - - for (op = i.operands; --op >= 0;) - if (operand_type_check (i.types[op], disp)) - { - if (i.op[op].disps->X_op == O_constant) - { - offsetT op_disp = i.op[op].disps->X_add_number; - - if (i.types[op].bitfield.disp16 - && (op_disp & ~(offsetT) 0xffff) == 0) - { - /* If this operand is at most 16 bits, convert - to a signed 16 bit number and don't use 64bit - displacement. */ - op_disp = (((op_disp & 0xffff) ^ 0x8000) - 0x8000); - i.types[op].bitfield.disp64 = 0; - } - if (i.types[op].bitfield.disp32 - && (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0) - { - /* If this operand is at most 32 bits, convert - to a signed 32 bit number and don't use 64bit - displacement. */ - op_disp &= (((offsetT) 2 << 31) - 1); - op_disp = (op_disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31); - i.types[op].bitfield.disp64 = 0; - } - if (!op_disp && i.types[op].bitfield.baseindex) - { - i.types[op].bitfield.disp8 = 0; - i.types[op].bitfield.disp16 = 0; - i.types[op].bitfield.disp32 = 0; - i.types[op].bitfield.disp32s = 0; - i.types[op].bitfield.disp64 = 0; - i.op[op].disps = 0; - i.disp_operands--; - } - else if (flag_code == CODE_64BIT) - { - if (fits_in_signed_long (op_disp)) - { - i.types[op].bitfield.disp64 = 0; - i.types[op].bitfield.disp32s = 1; - } - if (i.prefix[ADDR_PREFIX] - && fits_in_unsigned_long (op_disp)) - i.types[op].bitfield.disp32 = 1; - } - if ((i.types[op].bitfield.disp32 - || i.types[op].bitfield.disp32s - || i.types[op].bitfield.disp16) - && fits_in_signed_byte (op_disp)) - i.types[op].bitfield.disp8 = 1; - } - else if (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL - || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL) - { - fix_new_exp (frag_now, frag_more (0) - frag_now->fr_literal, 0, - i.op[op].disps, 0, i.reloc[op]); - i.types[op].bitfield.disp8 = 0; - i.types[op].bitfield.disp16 = 0; - i.types[op].bitfield.disp32 = 0; - i.types[op].bitfield.disp32s = 0; - i.types[op].bitfield.disp64 = 0; - } - else - /* We only support 64bit displacement on constants. */ - i.types[op].bitfield.disp64 = 0; - } -} - -/* Check if operands are valid for the instruction. */ - -static int -check_VecOperands (const insn_template *t) -{ - /* Without VSIB byte, we can't have a vector register for index. */ - if (!t->opcode_modifier.vecsib - && i.index_reg - && (i.index_reg->reg_type.bitfield.regxmm - || i.index_reg->reg_type.bitfield.regymm)) - { - i.error = unsupported_vector_index_register; - return 1; - } - - /* For VSIB byte, we need a vector register for index and no PC - relative addressing is allowed. */ - if (t->opcode_modifier.vecsib - && (!i.index_reg - || !((t->opcode_modifier.vecsib == VecSIB128 - && i.index_reg->reg_type.bitfield.regxmm) - || (t->opcode_modifier.vecsib == VecSIB256 - && i.index_reg->reg_type.bitfield.regymm)) - || (i.base_reg && i.base_reg->reg_num == RegRip))) - { - i.error = invalid_vsib_address; - return 1; - } - - return 0; -} - -/* Check if operands are valid for the instruction. Update VEX - operand types. */ - -static int -VEX_check_operands (const insn_template *t) -{ - if (!t->opcode_modifier.vex) - return 0; - - /* Only check VEX_Imm4, which must be the first operand. */ - if (t->operand_types[0].bitfield.vec_imm4) - { - if (i.op[0].imms->X_op != O_constant - || !fits_in_imm4 (i.op[0].imms->X_add_number)) - { - i.error = bad_imm4; - return 1; - } - - /* Turn off Imm8 so that update_imm won't complain. */ - i.types[0] = vec_imm4; - } - - return 0; -} - -static const insn_template * -match_template (void) -{ - /* Points to template once we've found it. */ - const insn_template *t; - i386_operand_type overlap0, overlap1, overlap2, overlap3; - i386_operand_type overlap4; - unsigned int found_reverse_match; - i386_opcode_modifier suffix_check; - i386_operand_type operand_types [MAX_OPERANDS]; - int addr_prefix_disp; - unsigned int j; - unsigned int found_cpu_match; - unsigned int check_register; - -#if MAX_OPERANDS != 5 -# error "MAX_OPERANDS must be 5." -#endif - - found_reverse_match = 0; - addr_prefix_disp = -1; - - memset (&suffix_check, 0, sizeof (suffix_check)); - if (i.suffix == BYTE_MNEM_SUFFIX) - suffix_check.no_bsuf = 1; - else if (i.suffix == WORD_MNEM_SUFFIX) - suffix_check.no_wsuf = 1; - else if (i.suffix == SHORT_MNEM_SUFFIX) - suffix_check.no_ssuf = 1; - else if (i.suffix == LONG_MNEM_SUFFIX) - suffix_check.no_lsuf = 1; - else if (i.suffix == QWORD_MNEM_SUFFIX) - suffix_check.no_qsuf = 1; - else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX) - suffix_check.no_ldsuf = 1; - - /* Must have right number of operands. */ - i.error = number_of_operands_mismatch; - - for (t = current_templates->start; t < current_templates->end; t++) - { - addr_prefix_disp = -1; - - if (i.operands != t->operands) - continue; - - /* Check processor support. */ - i.error = unsupported; - found_cpu_match = (cpu_flags_match (t) - == CPU_FLAGS_PERFECT_MATCH); - if (!found_cpu_match) - continue; - - /* Check old gcc support. */ - i.error = old_gcc_only; - if (!old_gcc && t->opcode_modifier.oldgcc) - continue; - - /* Check AT&T mnemonic. */ - i.error = unsupported_with_intel_mnemonic; - if (intel_mnemonic && t->opcode_modifier.attmnemonic) - continue; - - /* Check AT&T/Intel syntax. */ - i.error = unsupported_syntax; - if ((intel_syntax && t->opcode_modifier.attsyntax) - || (!intel_syntax && t->opcode_modifier.intelsyntax)) - continue; - - /* Check the suffix, except for some instructions in intel mode. */ - i.error = invalid_instruction_suffix; - if ((!intel_syntax || !t->opcode_modifier.ignoresize) - && ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf) - || (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf) - || (t->opcode_modifier.no_lsuf && suffix_check.no_lsuf) - || (t->opcode_modifier.no_ssuf && suffix_check.no_ssuf) - || (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf) - || (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf))) - continue; - - if (!operand_size_match (t)) - continue; - - for (j = 0; j < MAX_OPERANDS; j++) - operand_types[j] = t->operand_types[j]; - - /* In general, don't allow 64-bit operands in 32-bit mode. */ - if (i.suffix == QWORD_MNEM_SUFFIX - && flag_code != CODE_64BIT - && (intel_syntax - ? (!t->opcode_modifier.ignoresize - && !intel_float_operand (t->name)) - : intel_float_operand (t->name) != 2) - && ((!operand_types[0].bitfield.regmmx - && !operand_types[0].bitfield.regxmm - && !operand_types[0].bitfield.regymm) - || (!operand_types[t->operands > 1].bitfield.regmmx - && !!operand_types[t->operands > 1].bitfield.regxmm - && !!operand_types[t->operands > 1].bitfield.regymm)) - && (t->base_opcode != 0x0fc7 - || t->extension_opcode != 1 /* cmpxchg8b */)) - continue; - - /* In general, don't allow 32-bit operands on pre-386. */ - else if (i.suffix == LONG_MNEM_SUFFIX - && !cpu_arch_flags.bitfield.cpui386 - && (intel_syntax - ? (!t->opcode_modifier.ignoresize - && !intel_float_operand (t->name)) - : intel_float_operand (t->name) != 2) - && ((!operand_types[0].bitfield.regmmx - && !operand_types[0].bitfield.regxmm) - || (!operand_types[t->operands > 1].bitfield.regmmx - && !!operand_types[t->operands > 1].bitfield.regxmm))) - continue; - - /* Do not verify operands when there are none. */ - else - { - if (!t->operands) - /* We've found a match; break out of loop. */ - break; - } - - /* Address size prefix will turn Disp64/Disp32/Disp16 operand - into Disp32/Disp16/Disp32 operand. */ - if (i.prefix[ADDR_PREFIX] != 0) - { - /* There should be only one Disp operand. */ - switch (flag_code) - { - case CODE_16BIT: - for (j = 0; j < MAX_OPERANDS; j++) - { - if (operand_types[j].bitfield.disp16) - { - addr_prefix_disp = j; - operand_types[j].bitfield.disp32 = 1; - operand_types[j].bitfield.disp16 = 0; - break; - } - } - break; - case CODE_32BIT: - for (j = 0; j < MAX_OPERANDS; j++) - { - if (operand_types[j].bitfield.disp32) - { - addr_prefix_disp = j; - operand_types[j].bitfield.disp32 = 0; - operand_types[j].bitfield.disp16 = 1; - break; - } - } - break; - case CODE_64BIT: - for (j = 0; j < MAX_OPERANDS; j++) - { - if (operand_types[j].bitfield.disp64) - { - addr_prefix_disp = j; - operand_types[j].bitfield.disp64 = 0; - operand_types[j].bitfield.disp32 = 1; - break; - } - } - break; - } - } - - /* We check register size if needed. */ - check_register = t->opcode_modifier.checkregsize; - overlap0 = operand_type_and (i.types[0], operand_types[0]); - switch (t->operands) - { - case 1: - if (!operand_type_match (overlap0, i.types[0])) - continue; - break; - case 2: - /* xchg %eax, %eax is a special case. It is an aliase for nop - only in 32bit mode and we can use opcode 0x90. In 64bit - mode, we can't use 0x90 for xchg %eax, %eax since it should - zero-extend %eax to %rax. */ - if (flag_code == CODE_64BIT - && t->base_opcode == 0x90 - && operand_type_equal (&i.types [0], &acc32) - && operand_type_equal (&i.types [1], &acc32)) - continue; - if (i.swap_operand) - { - /* If we swap operand in encoding, we either match - the next one or reverse direction of operands. */ - if (t->opcode_modifier.s) - continue; - else if (t->opcode_modifier.d) - goto check_reverse; - } - - case 3: - /* If we swap operand in encoding, we match the next one. */ - if (i.swap_operand && t->opcode_modifier.s) - continue; - case 4: - case 5: - overlap1 = operand_type_and (i.types[1], operand_types[1]); - if (!operand_type_match (overlap0, i.types[0]) - || !operand_type_match (overlap1, i.types[1]) - || (check_register - && !operand_type_register_match (overlap0, i.types[0], - operand_types[0], - overlap1, i.types[1], - operand_types[1]))) - { - /* Check if other direction is valid ... */ - if (!t->opcode_modifier.d && !t->opcode_modifier.floatd) - continue; - -check_reverse: - /* Try reversing direction of operands. */ - overlap0 = operand_type_and (i.types[0], operand_types[1]); - overlap1 = operand_type_and (i.types[1], operand_types[0]); - if (!operand_type_match (overlap0, i.types[0]) - || !operand_type_match (overlap1, i.types[1]) - || (check_register - && !operand_type_register_match (overlap0, - i.types[0], - operand_types[1], - overlap1, - i.types[1], - operand_types[0]))) - { - /* Does not match either direction. */ - continue; - } - /* found_reverse_match holds which of D or FloatDR - we've found. */ - if (t->opcode_modifier.d) - found_reverse_match = Opcode_D; - else if (t->opcode_modifier.floatd) - found_reverse_match = Opcode_FloatD; - else - found_reverse_match = 0; - if (t->opcode_modifier.floatr) - found_reverse_match |= Opcode_FloatR; - } - else - { - /* Found a forward 2 operand match here. */ - switch (t->operands) - { - case 5: - overlap4 = operand_type_and (i.types[4], - operand_types[4]); - case 4: - overlap3 = operand_type_and (i.types[3], - operand_types[3]); - case 3: - overlap2 = operand_type_and (i.types[2], - operand_types[2]); - break; - } - - switch (t->operands) - { - case 5: - if (!operand_type_match (overlap4, i.types[4]) - || !operand_type_register_match (overlap3, - i.types[3], - operand_types[3], - overlap4, - i.types[4], - operand_types[4])) - continue; - case 4: - if (!operand_type_match (overlap3, i.types[3]) - || (check_register - && !operand_type_register_match (overlap2, - i.types[2], - operand_types[2], - overlap3, - i.types[3], - operand_types[3]))) - continue; - case 3: - /* Here we make use of the fact that there are no - reverse match 3 operand instructions, and all 3 - operand instructions only need to be checked for - register consistency between operands 2 and 3. */ - if (!operand_type_match (overlap2, i.types[2]) - || (check_register - && !operand_type_register_match (overlap1, - i.types[1], - operand_types[1], - overlap2, - i.types[2], - operand_types[2]))) - continue; - break; - } - } - /* Found either forward/reverse 2, 3 or 4 operand match here: - slip through to break. */ - } - if (!found_cpu_match) - { - found_reverse_match = 0; - continue; - } - - /* Check if vector operands are valid. */ - if (check_VecOperands (t)) - continue; - - /* Check if VEX operands are valid. */ - if (VEX_check_operands (t)) - continue; - - /* We've found a match; break out of loop. */ - break; - } - - if (t == current_templates->end) - { - /* We found no match. */ - const char *err_msg; - switch (i.error) - { - default: - abort (); - case operand_size_mismatch: - err_msg = _("operand size mismatch"); - break; - case operand_type_mismatch: - err_msg = _("operand type mismatch"); - break; - case register_type_mismatch: - err_msg = _("register type mismatch"); - break; - case number_of_operands_mismatch: - err_msg = _("number of operands mismatch"); - break; - case invalid_instruction_suffix: - err_msg = _("invalid instruction suffix"); - break; - case bad_imm4: - err_msg = _("Imm4 isn't the first operand"); - break; - case old_gcc_only: - err_msg = _("only supported with old gcc"); - break; - case unsupported_with_intel_mnemonic: - err_msg = _("unsupported with Intel mnemonic"); - break; - case unsupported_syntax: - err_msg = _("unsupported syntax"); - break; - case unsupported: - err_msg = _("unsupported"); - break; - case invalid_vsib_address: - err_msg = _("invalid VSIB address"); - break; - case unsupported_vector_index_register: - err_msg = _("unsupported vector index register"); - break; - } - as_bad (_("%s for `%s'"), err_msg, - current_templates->start->name); - return NULL; - } - - if (!quiet_warnings) - { - if (!intel_syntax - && (i.types[0].bitfield.jumpabsolute - != operand_types[0].bitfield.jumpabsolute)) - { - as_warn (_("indirect %s without `*'"), t->name); - } - - if (t->opcode_modifier.isprefix - && t->opcode_modifier.ignoresize) - { - /* Warn them that a data or address size prefix doesn't - affect assembly of the next line of code. */ - as_warn (_("stand-alone `%s' prefix"), t->name); - } - } - - /* Copy the template we found. */ - i.tm = *t; - - if (addr_prefix_disp != -1) - i.tm.operand_types[addr_prefix_disp] - = operand_types[addr_prefix_disp]; - - if (found_reverse_match) - { - /* If we found a reverse match we must alter the opcode - direction bit. found_reverse_match holds bits to change - (different for int & float insns). */ - - i.tm.base_opcode ^= found_reverse_match; - - i.tm.operand_types[0] = operand_types[1]; - i.tm.operand_types[1] = operand_types[0]; - } - - return t; -} - -static int -check_string (void) -{ - int mem_op = operand_type_check (i.types[0], anymem) ? 0 : 1; - if (i.tm.operand_types[mem_op].bitfield.esseg) - { - if (i.seg[0] != NULL && i.seg[0] != &es) - { - as_bad (_("`%s' operand %d must use `%ses' segment"), - i.tm.name, - mem_op + 1, - register_prefix); - return 0; - } - /* There's only ever one segment override allowed per instruction. - This instruction possibly has a legal segment override on the - second operand, so copy the segment to where non-string - instructions store it, allowing common code. */ - i.seg[0] = i.seg[1]; - } - else if (i.tm.operand_types[mem_op + 1].bitfield.esseg) - { - if (i.seg[1] != NULL && i.seg[1] != &es) - { - as_bad (_("`%s' operand %d must use `%ses' segment"), - i.tm.name, - mem_op + 2, - register_prefix); - return 0; - } - } - return 1; -} - -static int -process_suffix (void) -{ - /* If matched instruction specifies an explicit instruction mnemonic - suffix, use it. */ - if (i.tm.opcode_modifier.size16) - i.suffix = WORD_MNEM_SUFFIX; - else if (i.tm.opcode_modifier.size32) - i.suffix = LONG_MNEM_SUFFIX; - else if (i.tm.opcode_modifier.size64) - i.suffix = QWORD_MNEM_SUFFIX; - else if (i.reg_operands) - { - /* If there's no instruction mnemonic suffix we try to invent one - based on register operands. */ - if (!i.suffix) - { - /* We take i.suffix from the last register operand specified, - Destination register type is more significant than source - register type. crc32 in SSE4.2 prefers source register - type. */ - if (i.tm.base_opcode == 0xf20f38f1) - { - if (i.types[0].bitfield.reg16) - i.suffix = WORD_MNEM_SUFFIX; - else if (i.types[0].bitfield.reg32) - i.suffix = LONG_MNEM_SUFFIX; - else if (i.types[0].bitfield.reg64) - i.suffix = QWORD_MNEM_SUFFIX; - } - else if (i.tm.base_opcode == 0xf20f38f0) - { - if (i.types[0].bitfield.reg8) - i.suffix = BYTE_MNEM_SUFFIX; - } - - if (!i.suffix) - { - int op; - - if (i.tm.base_opcode == 0xf20f38f1 - || i.tm.base_opcode == 0xf20f38f0) - { - /* We have to know the operand size for crc32. */ - as_bad (_("ambiguous memory operand size for `%s`"), - i.tm.name); - return 0; - } - - for (op = i.operands; --op >= 0;) - if (!i.tm.operand_types[op].bitfield.inoutportreg) - { - if (i.types[op].bitfield.reg8) - { - i.suffix = BYTE_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg16) - { - i.suffix = WORD_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg32) - { - i.suffix = LONG_MNEM_SUFFIX; - break; - } - else if (i.types[op].bitfield.reg64) - { - i.suffix = QWORD_MNEM_SUFFIX; - break; - } - } - } - } - else if (i.suffix == BYTE_MNEM_SUFFIX) - { - if (intel_syntax - && i.tm.opcode_modifier.ignoresize - && i.tm.opcode_modifier.no_bsuf) - i.suffix = 0; - else if (!check_byte_reg ()) - return 0; - } - else if (i.suffix == LONG_MNEM_SUFFIX) - { - if (intel_syntax - && i.tm.opcode_modifier.ignoresize - && i.tm.opcode_modifier.no_lsuf) - i.suffix = 0; - else if (!check_long_reg ()) - return 0; - } - else if (i.suffix == QWORD_MNEM_SUFFIX) - { - if (intel_syntax - && i.tm.opcode_modifier.ignoresize - && i.tm.opcode_modifier.no_qsuf) - i.suffix = 0; - else if (!check_qword_reg ()) - return 0; - } - else if (i.suffix == WORD_MNEM_SUFFIX) - { - if (intel_syntax - && i.tm.opcode_modifier.ignoresize - && i.tm.opcode_modifier.no_wsuf) - i.suffix = 0; - else if (!check_word_reg ()) - return 0; - } - else if (i.suffix == XMMWORD_MNEM_SUFFIX - || i.suffix == YMMWORD_MNEM_SUFFIX) - { - /* Skip if the instruction has x/y suffix. match_template - should check if it is a valid suffix. */ - } - else if (intel_syntax && i.tm.opcode_modifier.ignoresize) - /* Do nothing if the instruction is going to ignore the prefix. */ - ; - else - abort (); - } - else if (i.tm.opcode_modifier.defaultsize - && !i.suffix - /* exclude fldenv/frstor/fsave/fstenv */ - && i.tm.opcode_modifier.no_ssuf) - { - i.suffix = stackop_size; - } - else if (intel_syntax - && !i.suffix - && (i.tm.operand_types[0].bitfield.jumpabsolute - || i.tm.opcode_modifier.jumpbyte - || i.tm.opcode_modifier.jumpintersegment - || (i.tm.base_opcode == 0x0f01 /* [ls][gi]dt */ - && i.tm.extension_opcode <= 3))) - { - switch (flag_code) - { - case CODE_64BIT: - if (!i.tm.opcode_modifier.no_qsuf) - { - i.suffix = QWORD_MNEM_SUFFIX; - break; - } - case CODE_32BIT: - if (!i.tm.opcode_modifier.no_lsuf) - i.suffix = LONG_MNEM_SUFFIX; - break; - case CODE_16BIT: - if (!i.tm.opcode_modifier.no_wsuf) - i.suffix = WORD_MNEM_SUFFIX; - break; - } - } - - if (!i.suffix) - { - if (!intel_syntax) - { - if (i.tm.opcode_modifier.w) - { - as_bad (_("no instruction mnemonic suffix given and " - "no register operands; can't size instruction")); - return 0; - } - } - else - { - unsigned int suffixes; - - suffixes = !i.tm.opcode_modifier.no_bsuf; - if (!i.tm.opcode_modifier.no_wsuf) - suffixes |= 1 << 1; - if (!i.tm.opcode_modifier.no_lsuf) - suffixes |= 1 << 2; - if (!i.tm.opcode_modifier.no_ldsuf) - suffixes |= 1 << 3; - if (!i.tm.opcode_modifier.no_ssuf) - suffixes |= 1 << 4; - if (!i.tm.opcode_modifier.no_qsuf) - suffixes |= 1 << 5; - - /* There are more than suffix matches. */ - if (i.tm.opcode_modifier.w - || ((suffixes & (suffixes - 1)) - && !i.tm.opcode_modifier.defaultsize - && !i.tm.opcode_modifier.ignoresize)) - { - as_bad (_("ambiguous operand size for `%s'"), i.tm.name); - return 0; - } - } - } - - /* Change the opcode based on the operand size given by i.suffix; - We don't need to change things for byte insns. */ - - if (i.suffix - && i.suffix != BYTE_MNEM_SUFFIX - && i.suffix != XMMWORD_MNEM_SUFFIX - && i.suffix != YMMWORD_MNEM_SUFFIX) - { - /* It's not a byte, select word/dword operation. */ - if (i.tm.opcode_modifier.w) - { - if (i.tm.opcode_modifier.shortform) - i.tm.base_opcode |= 8; - else - i.tm.base_opcode |= 1; - } - - /* Now select between word & dword operations via the operand - size prefix, except for instructions that will ignore this - prefix anyway. */ - if (i.tm.opcode_modifier.addrprefixop0) - { - /* The address size override prefix changes the size of the - first operand. */ - if ((flag_code == CODE_32BIT - && i.op->regs[0].reg_type.bitfield.reg16) - || (flag_code != CODE_32BIT - && i.op->regs[0].reg_type.bitfield.reg32)) - if (!add_prefix (ADDR_PREFIX_OPCODE)) - return 0; - } - else if (i.suffix != QWORD_MNEM_SUFFIX - && i.suffix != LONG_DOUBLE_MNEM_SUFFIX - && !i.tm.opcode_modifier.ignoresize - && !i.tm.opcode_modifier.floatmf - && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) - || (flag_code == CODE_64BIT - && i.tm.opcode_modifier.jumpbyte))) - { - unsigned int prefix = DATA_PREFIX_OPCODE; - - if (i.tm.opcode_modifier.jumpbyte) /* jcxz, loop */ - prefix = ADDR_PREFIX_OPCODE; - - if (!add_prefix (prefix)) - return 0; - } - - /* Set mode64 for an operand. */ - if (i.suffix == QWORD_MNEM_SUFFIX - && flag_code == CODE_64BIT - && !i.tm.opcode_modifier.norex64) - { - /* Special case for xchg %rax,%rax. It is NOP and doesn't - need rex64. cmpxchg8b is also a special case. */ - if (! (i.operands == 2 - && i.tm.base_opcode == 0x90 - && i.tm.extension_opcode == None - && operand_type_equal (&i.types [0], &acc64) - && operand_type_equal (&i.types [1], &acc64)) - && ! (i.operands == 1 - && i.tm.base_opcode == 0xfc7 - && i.tm.extension_opcode == 1 - && !operand_type_check (i.types [0], reg) - && operand_type_check (i.types [0], anymem))) - i.rex |= REX_W; - } - - /* Size floating point instruction. */ - if (i.suffix == LONG_MNEM_SUFFIX) - if (i.tm.opcode_modifier.floatmf) - i.tm.base_opcode ^= 4; - } - - return 1; -} - -static int -check_byte_reg (void) -{ - int op; - - for (op = i.operands; --op >= 0;) - { - /* If this is an eight bit register, it's OK. If it's the 16 or - 32 bit version of an eight bit register, we will just use the - low portion, and that's OK too. */ - if (i.types[op].bitfield.reg8) - continue; - - /* crc32 doesn't generate this warning. */ - if (i.tm.base_opcode == 0xf20f38f0) - continue; - - if ((i.types[op].bitfield.reg16 - || i.types[op].bitfield.reg32 - || i.types[op].bitfield.reg64) - && i.op[op].regs->reg_num < 4) - { - /* Prohibit these changes in the 64bit mode, since the - lowering is more complicated. */ - if (flag_code == CODE_64BIT - && !i.tm.operand_types[op].bitfield.inoutportreg) - { - as_bad (_("incorrect register `%s%s' used with `%c' suffix"), - register_prefix, i.op[op].regs->reg_name, - i.suffix); - return 0; - } -#if REGISTER_WARNINGS - if (!quiet_warnings - && !i.tm.operand_types[op].bitfield.inoutportreg) - as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), - register_prefix, - (i.op[op].regs + (i.types[op].bitfield.reg16 - ? REGNAM_AL - REGNAM_AX - : REGNAM_AL - REGNAM_EAX))->reg_name, - register_prefix, - i.op[op].regs->reg_name, - i.suffix); -#endif - continue; - } - /* Any other register is bad. */ - if (i.types[op].bitfield.reg16 - || i.types[op].bitfield.reg32 - || i.types[op].bitfield.reg64 - || i.types[op].bitfield.regmmx - || i.types[op].bitfield.regxmm - || i.types[op].bitfield.regymm - || i.types[op].bitfield.sreg2 - || i.types[op].bitfield.sreg3 - || i.types[op].bitfield.control - || i.types[op].bitfield.debug - || i.types[op].bitfield.test - || i.types[op].bitfield.floatreg - || i.types[op].bitfield.floatacc) - { - as_bad (_("`%s%s' not allowed with `%s%c'"), - register_prefix, - i.op[op].regs->reg_name, - i.tm.name, - i.suffix); - return 0; - } - } - return 1; -} - -static int -check_long_reg (void) -{ - int op; - - for (op = i.operands; --op >= 0;) - /* Reject eight bit registers, except where the template requires - them. (eg. movzb) */ - if (i.types[op].bitfield.reg8 - && (i.tm.operand_types[op].bitfield.reg16 - || i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - as_bad (_("`%s%s' not allowed with `%s%c'"), - register_prefix, - i.op[op].regs->reg_name, - i.tm.name, - i.suffix); - return 0; - } - /* Warn if the e prefix on a general reg is missing. */ - else if ((!quiet_warnings || flag_code == CODE_64BIT) - && i.types[op].bitfield.reg16 - && (i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - /* Prohibit these changes in the 64bit mode, since the - lowering is more complicated. */ - if (flag_code == CODE_64BIT) - { - as_bad (_("incorrect register `%s%s' used with `%c' suffix"), - register_prefix, i.op[op].regs->reg_name, - i.suffix); - return 0; - } -#if REGISTER_WARNINGS - else - as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), - register_prefix, - (i.op[op].regs + REGNAM_EAX - REGNAM_AX)->reg_name, - register_prefix, - i.op[op].regs->reg_name, - i.suffix); -#endif - } - /* Warn if the r prefix on a general reg is missing. */ - else if (i.types[op].bitfield.reg64 - && (i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - if (intel_syntax - && i.tm.opcode_modifier.toqword - && !i.types[0].bitfield.regxmm) - { - /* Convert to QWORD. We want REX byte. */ - i.suffix = QWORD_MNEM_SUFFIX; - } - else - { - as_bad (_("incorrect register `%s%s' used with `%c' suffix"), - register_prefix, i.op[op].regs->reg_name, - i.suffix); - return 0; - } - } - return 1; -} - -static int -check_qword_reg (void) -{ - int op; - - for (op = i.operands; --op >= 0; ) - /* Reject eight bit registers, except where the template requires - them. (eg. movzb) */ - if (i.types[op].bitfield.reg8 - && (i.tm.operand_types[op].bitfield.reg16 - || i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - as_bad (_("`%s%s' not allowed with `%s%c'"), - register_prefix, - i.op[op].regs->reg_name, - i.tm.name, - i.suffix); - return 0; - } - /* Warn if the e prefix on a general reg is missing. */ - else if ((i.types[op].bitfield.reg16 - || i.types[op].bitfield.reg32) - && (i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - /* Prohibit these changes in the 64bit mode, since the - lowering is more complicated. */ - if (intel_syntax - && i.tm.opcode_modifier.todword - && !i.types[0].bitfield.regxmm) - { - /* Convert to DWORD. We don't want REX byte. */ - i.suffix = LONG_MNEM_SUFFIX; - } - else - { - as_bad (_("incorrect register `%s%s' used with `%c' suffix"), - register_prefix, i.op[op].regs->reg_name, - i.suffix); - return 0; - } - } - return 1; -} - -static int -check_word_reg (void) -{ - int op; - for (op = i.operands; --op >= 0;) - /* Reject eight bit registers, except where the template requires - them. (eg. movzb) */ - if (i.types[op].bitfield.reg8 - && (i.tm.operand_types[op].bitfield.reg16 - || i.tm.operand_types[op].bitfield.reg32 - || i.tm.operand_types[op].bitfield.acc)) - { - as_bad (_("`%s%s' not allowed with `%s%c'"), - register_prefix, - i.op[op].regs->reg_name, - i.tm.name, - i.suffix); - return 0; - } - /* Warn if the e prefix on a general reg is present. */ - else if ((!quiet_warnings || flag_code == CODE_64BIT) - && i.types[op].bitfield.reg32 - && (i.tm.operand_types[op].bitfield.reg16 - || i.tm.operand_types[op].bitfield.acc)) - { - /* Prohibit these changes in the 64bit mode, since the - lowering is more complicated. */ - if (flag_code == CODE_64BIT) - { - as_bad (_("incorrect register `%s%s' used with `%c' suffix"), - register_prefix, i.op[op].regs->reg_name, - i.suffix); - return 0; - } - else -#if REGISTER_WARNINGS - as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), - register_prefix, - (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name, - register_prefix, - i.op[op].regs->reg_name, - i.suffix); -#endif - } - return 1; -} - -static int -update_imm (unsigned int j) -{ - i386_operand_type overlap = i.types[j]; - if ((overlap.bitfield.imm8 - || overlap.bitfield.imm8s - || overlap.bitfield.imm16 - || overlap.bitfield.imm32 - || overlap.bitfield.imm32s - || overlap.bitfield.imm64) - && !operand_type_equal (&overlap, &imm8) - && !operand_type_equal (&overlap, &imm8s) - && !operand_type_equal (&overlap, &imm16) - && !operand_type_equal (&overlap, &imm32) - && !operand_type_equal (&overlap, &imm32s) - && !operand_type_equal (&overlap, &imm64)) - { - if (i.suffix) - { - i386_operand_type temp; - - operand_type_set (&temp, 0); - if (i.suffix == BYTE_MNEM_SUFFIX) - { - temp.bitfield.imm8 = overlap.bitfield.imm8; - temp.bitfield.imm8s = overlap.bitfield.imm8s; - } - else if (i.suffix == WORD_MNEM_SUFFIX) - temp.bitfield.imm16 = overlap.bitfield.imm16; - else if (i.suffix == QWORD_MNEM_SUFFIX) - { - temp.bitfield.imm64 = overlap.bitfield.imm64; - temp.bitfield.imm32s = overlap.bitfield.imm32s; - } - else - temp.bitfield.imm32 = overlap.bitfield.imm32; - overlap = temp; - } - else if (operand_type_equal (&overlap, &imm16_32_32s) - || operand_type_equal (&overlap, &imm16_32) - || operand_type_equal (&overlap, &imm16_32s)) - { - if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)) - overlap = imm16; - else - overlap = imm32s; - } - if (!operand_type_equal (&overlap, &imm8) - && !operand_type_equal (&overlap, &imm8s) - && !operand_type_equal (&overlap, &imm16) - && !operand_type_equal (&overlap, &imm32) - && !operand_type_equal (&overlap, &imm32s) - && !operand_type_equal (&overlap, &imm64)) - { - as_bad (_("no instruction mnemonic suffix given; " - "can't determine immediate size")); - return 0; - } - } - i.types[j] = overlap; - - return 1; -} - -static int -finalize_imm (void) -{ - unsigned int j, n; - - /* Update the first 2 immediate operands. */ - n = i.operands > 2 ? 2 : i.operands; - if (n) - { - for (j = 0; j < n; j++) - if (update_imm (j) == 0) - return 0; - - /* The 3rd operand can't be immediate operand. */ - gas_assert (operand_type_check (i.types[2], imm) == 0); - } - - return 1; -} - -static int -bad_implicit_operand (int xmm) -{ - const char *ireg = xmm ? "xmm0" : "ymm0"; - - if (intel_syntax) - as_bad (_("the last operand of `%s' must be `%s%s'"), - i.tm.name, register_prefix, ireg); - else - as_bad (_("the first operand of `%s' must be `%s%s'"), - i.tm.name, register_prefix, ireg); - return 0; -} - -static int -process_operands (void) -{ - /* Default segment register this instruction will use for memory - accesses. 0 means unknown. This is only for optimizing out - unnecessary segment overrides. */ - const seg_entry *default_seg = 0; - - if (i.tm.opcode_modifier.sse2avx && i.tm.opcode_modifier.vexvvvv) - { - unsigned int dupl = i.operands; - unsigned int dest = dupl - 1; - unsigned int j; - - /* The destination must be an xmm register. */ - gas_assert (i.reg_operands - && MAX_OPERANDS > dupl - && operand_type_equal (&i.types[dest], ®xmm)); - - if (i.tm.opcode_modifier.firstxmm0) - { - /* The first operand is implicit and must be xmm0. */ - gas_assert (operand_type_equal (&i.types[0], ®xmm)); - if (i.op[0].regs->reg_num != 0) - return bad_implicit_operand (1); - - if (i.tm.opcode_modifier.vexsources == VEX3SOURCES) - { - /* Keep xmm0 for instructions with VEX prefix and 3 - sources. */ - goto duplicate; - } - else - { - /* We remove the first xmm0 and keep the number of - operands unchanged, which in fact duplicates the - destination. */ - for (j = 1; j < i.operands; j++) - { - i.op[j - 1] = i.op[j]; - i.types[j - 1] = i.types[j]; - i.tm.operand_types[j - 1] = i.tm.operand_types[j]; - } - } - } - else if (i.tm.opcode_modifier.implicit1stxmm0) - { - gas_assert ((MAX_OPERANDS - 1) > dupl - && (i.tm.opcode_modifier.vexsources - == VEX3SOURCES)); - - /* Add the implicit xmm0 for instructions with VEX prefix - and 3 sources. */ - for (j = i.operands; j > 0; j--) - { - i.op[j] = i.op[j - 1]; - i.types[j] = i.types[j - 1]; - i.tm.operand_types[j] = i.tm.operand_types[j - 1]; - } - i.op[0].regs - = (const reg_entry *) hash_find (reg_hash, "xmm0"); - i.types[0] = regxmm; - i.tm.operand_types[0] = regxmm; - - i.operands += 2; - i.reg_operands += 2; - i.tm.operands += 2; - - dupl++; - dest++; - i.op[dupl] = i.op[dest]; - i.types[dupl] = i.types[dest]; - i.tm.operand_types[dupl] = i.tm.operand_types[dest]; - } - else - { -duplicate: - i.operands++; - i.reg_operands++; - i.tm.operands++; - - i.op[dupl] = i.op[dest]; - i.types[dupl] = i.types[dest]; - i.tm.operand_types[dupl] = i.tm.operand_types[dest]; - } - - if (i.tm.opcode_modifier.immext) - process_immext (); - } - else if (i.tm.opcode_modifier.firstxmm0) - { - unsigned int j; - - /* The first operand is implicit and must be xmm0/ymm0. */ - gas_assert (i.reg_operands - && (operand_type_equal (&i.types[0], ®xmm) - || operand_type_equal (&i.types[0], ®ymm))); - if (i.op[0].regs->reg_num != 0) - return bad_implicit_operand (i.types[0].bitfield.regxmm); - - for (j = 1; j < i.operands; j++) - { - i.op[j - 1] = i.op[j]; - i.types[j - 1] = i.types[j]; - - /* We need to adjust fields in i.tm since they are used by - build_modrm_byte. */ - i.tm.operand_types [j - 1] = i.tm.operand_types [j]; - } - - i.operands--; - i.reg_operands--; - i.tm.operands--; - } - else if (i.tm.opcode_modifier.regkludge) - { - /* The imul $imm, %reg instruction is converted into - imul $imm, %reg, %reg, and the clr %reg instruction - is converted into xor %reg, %reg. */ - - unsigned int first_reg_op; - - if (operand_type_check (i.types[0], reg)) - first_reg_op = 0; - else - first_reg_op = 1; - /* Pretend we saw the extra register operand. */ - gas_assert (i.reg_operands == 1 - && i.op[first_reg_op + 1].regs == 0); - i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs; - i.types[first_reg_op + 1] = i.types[first_reg_op]; - i.operands++; - i.reg_operands++; - } - - if (i.tm.opcode_modifier.shortform) - { - if (i.types[0].bitfield.sreg2 - || i.types[0].bitfield.sreg3) - { - if (i.tm.base_opcode == POP_SEG_SHORT - && i.op[0].regs->reg_num == 1) - { - as_bad (_("you can't `pop %scs'"), register_prefix); - return 0; - } - i.tm.base_opcode |= (i.op[0].regs->reg_num << 3); - if ((i.op[0].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - } - else - { - /* The register or float register operand is in operand - 0 or 1. */ - unsigned int op; - - if (i.types[0].bitfield.floatreg - || operand_type_check (i.types[0], reg)) - op = 0; - else - op = 1; - /* Register goes in low 3 bits of opcode. */ - i.tm.base_opcode |= i.op[op].regs->reg_num; - if ((i.op[op].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - if (!quiet_warnings && i.tm.opcode_modifier.ugh) - { - /* Warn about some common errors, but press on regardless. - The first case can be generated by gcc (<= 2.8.1). */ - if (i.operands == 2) - { - /* Reversed arguments on faddp, fsubp, etc. */ - as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name, - register_prefix, i.op[!intel_syntax].regs->reg_name, - register_prefix, i.op[intel_syntax].regs->reg_name); - } - else - { - /* Extraneous `l' suffix on fp insn. */ - as_warn (_("translating to `%s %s%s'"), i.tm.name, - register_prefix, i.op[0].regs->reg_name); - } - } - } - } - else if (i.tm.opcode_modifier.modrm) - { - /* The opcode is completed (modulo i.tm.extension_opcode which - must be put into the modrm byte). Now, we make the modrm and - index base bytes based on all the info we've collected. */ - - default_seg = build_modrm_byte (); - } - else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32) - { - default_seg = &ds; - } - else if (i.tm.opcode_modifier.isstring) - { - /* For the string instructions that allow a segment override - on one of their operands, the default segment is ds. */ - default_seg = &ds; - } - - if (i.tm.base_opcode == 0x8d /* lea */ - && i.seg[0] - && !quiet_warnings) - as_warn (_("segment override on `%s' is ineffectual"), i.tm.name); - - /* If a segment was explicitly specified, and the specified segment - is not the default, use an opcode prefix to select it. If we - never figured out what the default segment is, then default_seg - will be zero at this point, and the specified segment prefix will - always be used. */ - if ((i.seg[0]) && (i.seg[0] != default_seg)) - { - if (!add_prefix (i.seg[0]->seg_prefix)) - return 0; - } - return 1; -} - -static const seg_entry * -build_modrm_byte (void) -{ - const seg_entry *default_seg = 0; - unsigned int source, dest; - int vex_3_sources; - - /* The first operand of instructions with VEX prefix and 3 sources - must be VEX_Imm4. */ - vex_3_sources = i.tm.opcode_modifier.vexsources == VEX3SOURCES; - if (vex_3_sources) - { - unsigned int nds, reg_slot; - expressionS *exp; - - if (i.tm.opcode_modifier.veximmext - && i.tm.opcode_modifier.immext) - { - dest = i.operands - 2; - gas_assert (dest == 3); - } - else - dest = i.operands - 1; - nds = dest - 1; - - /* There are 2 kinds of instructions: - 1. 5 operands: 4 register operands or 3 register operands - plus 1 memory operand plus one Vec_Imm4 operand, VexXDS, and - VexW0 or VexW1. The destination must be either XMM or YMM - register. - 2. 4 operands: 4 register operands or 3 register operands - plus 1 memory operand, VexXDS, and VexImmExt */ - gas_assert ((i.reg_operands == 4 - || (i.reg_operands == 3 && i.mem_operands == 1)) - && i.tm.opcode_modifier.vexvvvv == VEXXDS - && (i.tm.opcode_modifier.veximmext - || (i.imm_operands == 1 - && i.types[0].bitfield.vec_imm4 - && (i.tm.opcode_modifier.vexw == VEXW0 - || i.tm.opcode_modifier.vexw == VEXW1) - && (operand_type_equal (&i.tm.operand_types[dest], ®xmm) - || operand_type_equal (&i.tm.operand_types[dest], ®ymm))))); - - if (i.imm_operands == 0) - { - /* When there is no immediate operand, generate an 8bit - immediate operand to encode the first operand. */ - exp = &im_expressions[i.imm_operands++]; - i.op[i.operands].imms = exp; - i.types[i.operands] = imm8; - i.operands++; - /* If VexW1 is set, the first operand is the source and - the second operand is encoded in the immediate operand. */ - if (i.tm.opcode_modifier.vexw == VEXW1) - { - source = 0; - reg_slot = 1; - } - else - { - source = 1; - reg_slot = 0; - } - - /* FMA swaps REG and NDS. */ - if (i.tm.cpu_flags.bitfield.cpufma) - { - unsigned int tmp; - tmp = reg_slot; - reg_slot = nds; - nds = tmp; - } - - gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot], - ®xmm) - || operand_type_equal (&i.tm.operand_types[reg_slot], - ®ymm)); - exp->X_op = O_constant; - exp->X_add_number - = ((i.op[reg_slot].regs->reg_num - + ((i.op[reg_slot].regs->reg_flags & RegRex) ? 8 : 0)) - << 4); - } - else - { - unsigned int imm_slot; - - if (i.tm.opcode_modifier.vexw == VEXW0) - { - /* If VexW0 is set, the third operand is the source and - the second operand is encoded in the immediate - operand. */ - source = 2; - reg_slot = 1; - } - else - { - /* VexW1 is set, the second operand is the source and - the third operand is encoded in the immediate - operand. */ - source = 1; - reg_slot = 2; - } - - if (i.tm.opcode_modifier.immext) - { - /* When ImmExt is set, the immdiate byte is the last - operand. */ - imm_slot = i.operands - 1; - source--; - reg_slot--; - } - else - { - imm_slot = 0; - - /* Turn on Imm8 so that output_imm will generate it. */ - i.types[imm_slot].bitfield.imm8 = 1; - } - - gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot], - ®xmm) - || operand_type_equal (&i.tm.operand_types[reg_slot], - ®ymm)); - i.op[imm_slot].imms->X_add_number - |= ((i.op[reg_slot].regs->reg_num - + ((i.op[reg_slot].regs->reg_flags & RegRex) ? 8 : 0)) - << 4); - } - - gas_assert (operand_type_equal (&i.tm.operand_types[nds], ®xmm) - || operand_type_equal (&i.tm.operand_types[nds], - ®ymm)); - i.vex.register_specifier = i.op[nds].regs; - } - else - source = dest = 0; - - /* i.reg_operands MUST be the number of real register operands; - implicit registers do not count. If there are 3 register - operands, it must be a instruction with VexNDS. For a - instruction with VexNDD, the destination register is encoded - in VEX prefix. If there are 4 register operands, it must be - a instruction with VEX prefix and 3 sources. */ - if (i.mem_operands == 0 - && ((i.reg_operands == 2 - && i.tm.opcode_modifier.vexvvvv <= VEXXDS) - || (i.reg_operands == 3 - && i.tm.opcode_modifier.vexvvvv == VEXXDS) - || (i.reg_operands == 4 && vex_3_sources))) - { - switch (i.operands) - { - case 2: - source = 0; - break; - case 3: - /* When there are 3 operands, one of them may be immediate, - which may be the first or the last operand. Otherwise, - the first operand must be shift count register (cl) or it - is an instruction with VexNDS. */ - gas_assert (i.imm_operands == 1 - || (i.imm_operands == 0 - && (i.tm.opcode_modifier.vexvvvv == VEXXDS - || i.types[0].bitfield.shiftcount))); - if (operand_type_check (i.types[0], imm) - || i.types[0].bitfield.shiftcount) - source = 1; - else - source = 0; - break; - case 4: - /* When there are 4 operands, the first two must be 8bit - immediate operands. The source operand will be the 3rd - one. - - For instructions with VexNDS, if the first operand - an imm8, the source operand is the 2nd one. If the last - operand is imm8, the source operand is the first one. */ - gas_assert ((i.imm_operands == 2 - && i.types[0].bitfield.imm8 - && i.types[1].bitfield.imm8) - || (i.tm.opcode_modifier.vexvvvv == VEXXDS - && i.imm_operands == 1 - && (i.types[0].bitfield.imm8 - || i.types[i.operands - 1].bitfield.imm8))); - if (i.imm_operands == 2) - source = 2; - else - { - if (i.types[0].bitfield.imm8) - source = 1; - else - source = 0; - } - break; - case 5: - break; - default: - abort (); - } - - if (!vex_3_sources) - { - dest = source + 1; - - if (i.tm.opcode_modifier.vexvvvv == VEXXDS) - { - /* For instructions with VexNDS, the register-only - source operand must be 32/64bit integer, XMM or - YMM register. It is encoded in VEX prefix. We - need to clear RegMem bit before calling - operand_type_equal. */ - - i386_operand_type op; - unsigned int vvvv; - - /* Check register-only source operand when two source - operands are swapped. */ - if (!i.tm.operand_types[source].bitfield.baseindex - && i.tm.operand_types[dest].bitfield.baseindex) - { - vvvv = source; - source = dest; - } - else - vvvv = dest; - - op = i.tm.operand_types[vvvv]; - op.bitfield.regmem = 0; - if ((dest + 1) >= i.operands - || (op.bitfield.reg32 != 1 - && !op.bitfield.reg64 != 1 - && !operand_type_equal (&op, ®xmm) - && !operand_type_equal (&op, ®ymm))) - abort (); - i.vex.register_specifier = i.op[vvvv].regs; - dest++; - } - } - - i.rm.mode = 3; - /* One of the register operands will be encoded in the i.tm.reg - field, the other in the combined i.tm.mode and i.tm.regmem - fields. If no form of this instruction supports a memory - destination operand, then we assume the source operand may - sometimes be a memory operand and so we need to store the - destination in the i.rm.reg field. */ - if (!i.tm.operand_types[dest].bitfield.regmem - && operand_type_check (i.tm.operand_types[dest], anymem) == 0) - { - i.rm.reg = i.op[dest].regs->reg_num; - i.rm.regmem = i.op[source].regs->reg_num; - if ((i.op[dest].regs->reg_flags & RegRex) != 0) - i.rex |= REX_R; - if ((i.op[source].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - } - else - { - i.rm.reg = i.op[source].regs->reg_num; - i.rm.regmem = i.op[dest].regs->reg_num; - if ((i.op[dest].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - if ((i.op[source].regs->reg_flags & RegRex) != 0) - i.rex |= REX_R; - } - if (flag_code != CODE_64BIT && (i.rex & (REX_R | REX_B))) - { - if (!i.types[0].bitfield.control - && !i.types[1].bitfield.control) - abort (); - i.rex &= ~(REX_R | REX_B); - add_prefix (LOCK_PREFIX_OPCODE); - } - } - else - { /* If it's not 2 reg operands... */ - unsigned int mem; - - if (i.mem_operands) - { - unsigned int fake_zero_displacement = 0; - unsigned int op; - - for (op = 0; op < i.operands; op++) - if (operand_type_check (i.types[op], anymem)) - break; - gas_assert (op < i.operands); - - if (i.tm.opcode_modifier.vecsib) - { - if (i.index_reg->reg_num == RegEiz - || i.index_reg->reg_num == RegRiz) - abort (); - - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - if (!i.base_reg) - { - i.sib.base = NO_BASE_REGISTER; - i.sib.scale = i.log2_scale_factor; - i.types[op].bitfield.disp8 = 0; - i.types[op].bitfield.disp16 = 0; - i.types[op].bitfield.disp64 = 0; - if (flag_code != CODE_64BIT) - { - /* Must be 32 bit */ - i.types[op].bitfield.disp32 = 1; - i.types[op].bitfield.disp32s = 0; - } - else - { - i.types[op].bitfield.disp32 = 0; - i.types[op].bitfield.disp32s = 1; - } - } - i.sib.index = i.index_reg->reg_num; - if ((i.index_reg->reg_flags & RegRex) != 0) - i.rex |= REX_X; - } - - default_seg = &ds; - - if (i.base_reg == 0) - { - i.rm.mode = 0; - if (!i.disp_operands) - { - fake_zero_displacement = 1; - /* Instructions with VSIB byte need 32bit displacement - if there is no base register. */ - if (i.tm.opcode_modifier.vecsib) - i.types[op].bitfield.disp32 = 1; - } - if (i.index_reg == 0) - { - gas_assert (!i.tm.opcode_modifier.vecsib); - /* Operand is just */ - if (flag_code == CODE_64BIT) - { - /* 64bit mode overwrites the 32bit absolute - addressing by RIP relative addressing and - absolute addressing is encoded by one of the - redundant SIB forms. */ - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.sib.base = NO_BASE_REGISTER; - i.sib.index = NO_INDEX_REGISTER; - i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) - ? disp32s : disp32); - } - else if ((flag_code == CODE_16BIT) - ^ (i.prefix[ADDR_PREFIX] != 0)) - { - i.rm.regmem = NO_BASE_REGISTER_16; - i.types[op] = disp16; - } - else - { - i.rm.regmem = NO_BASE_REGISTER; - i.types[op] = disp32; - } - } - else if (!i.tm.opcode_modifier.vecsib) - { - /* !i.base_reg && i.index_reg */ - if (i.index_reg->reg_num == RegEiz - || i.index_reg->reg_num == RegRiz) - i.sib.index = NO_INDEX_REGISTER; - else - i.sib.index = i.index_reg->reg_num; - i.sib.base = NO_BASE_REGISTER; - i.sib.scale = i.log2_scale_factor; - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - i.types[op].bitfield.disp8 = 0; - i.types[op].bitfield.disp16 = 0; - i.types[op].bitfield.disp64 = 0; - if (flag_code != CODE_64BIT) - { - /* Must be 32 bit */ - i.types[op].bitfield.disp32 = 1; - i.types[op].bitfield.disp32s = 0; - } - else - { - i.types[op].bitfield.disp32 = 0; - i.types[op].bitfield.disp32s = 1; - } - if ((i.index_reg->reg_flags & RegRex) != 0) - i.rex |= REX_X; - } - } - /* RIP addressing for 64bit mode. */ - else if (i.base_reg->reg_num == RegRip || - i.base_reg->reg_num == RegEip) - { - gas_assert (!i.tm.opcode_modifier.vecsib); - i.rm.regmem = NO_BASE_REGISTER; - i.types[op].bitfield.disp8 = 0; - i.types[op].bitfield.disp16 = 0; - i.types[op].bitfield.disp32 = 0; - i.types[op].bitfield.disp32s = 1; - i.types[op].bitfield.disp64 = 0; - i.flags[op] |= Operand_PCrel; - if (! i.disp_operands) - fake_zero_displacement = 1; - } - else if (i.base_reg->reg_type.bitfield.reg16) - { - gas_assert (!i.tm.opcode_modifier.vecsib); - switch (i.base_reg->reg_num) - { - case 3: /* (%bx) */ - if (i.index_reg == 0) - i.rm.regmem = 7; - else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */ - i.rm.regmem = i.index_reg->reg_num - 6; - break; - case 5: /* (%bp) */ - default_seg = &ss; - if (i.index_reg == 0) - { - i.rm.regmem = 6; - if (operand_type_check (i.types[op], disp) == 0) - { - /* fake (%bp) into 0(%bp) */ - i.types[op].bitfield.disp8 = 1; - fake_zero_displacement = 1; - } - } - else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */ - i.rm.regmem = i.index_reg->reg_num - 6 + 2; - break; - default: /* (%si) -> 4 or (%di) -> 5 */ - i.rm.regmem = i.base_reg->reg_num - 6 + 4; - } - i.rm.mode = mode_from_disp_size (i.types[op]); - } - else /* i.base_reg and 32/64 bit mode */ - { - if (flag_code == CODE_64BIT - && operand_type_check (i.types[op], disp)) - { - i386_operand_type temp; - operand_type_set (&temp, 0); - temp.bitfield.disp8 = i.types[op].bitfield.disp8; - i.types[op] = temp; - if (i.prefix[ADDR_PREFIX] == 0) - i.types[op].bitfield.disp32s = 1; - else - i.types[op].bitfield.disp32 = 1; - } - - if (!i.tm.opcode_modifier.vecsib) - i.rm.regmem = i.base_reg->reg_num; - if ((i.base_reg->reg_flags & RegRex) != 0) - i.rex |= REX_B; - i.sib.base = i.base_reg->reg_num; - /* x86-64 ignores REX prefix bit here to avoid decoder - complications. */ - if ((i.base_reg->reg_num & 7) == EBP_REG_NUM) - { - default_seg = &ss; - if (i.disp_operands == 0) - { - fake_zero_displacement = 1; - i.types[op].bitfield.disp8 = 1; - } - } - else if (i.base_reg->reg_num == ESP_REG_NUM) - { - default_seg = &ss; - } - i.sib.scale = i.log2_scale_factor; - if (i.index_reg == 0) - { - gas_assert (!i.tm.opcode_modifier.vecsib); - /* (%esp) becomes two byte modrm with no index - register. We've already stored the code for esp - in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING. - Any base register besides %esp will not use the - extra modrm byte. */ - i.sib.index = NO_INDEX_REGISTER; - } - else if (!i.tm.opcode_modifier.vecsib) - { - if (i.index_reg->reg_num == RegEiz - || i.index_reg->reg_num == RegRiz) - i.sib.index = NO_INDEX_REGISTER; - else - i.sib.index = i.index_reg->reg_num; - i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; - if ((i.index_reg->reg_flags & RegRex) != 0) - i.rex |= REX_X; - } - - if (i.disp_operands - && (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL - || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL)) - i.rm.mode = 0; - else - i.rm.mode = mode_from_disp_size (i.types[op]); - } - - if (fake_zero_displacement) - { - /* Fakes a zero displacement assuming that i.types[op] - holds the correct displacement size. */ - expressionS *exp; - - gas_assert (i.op[op].disps == 0); - exp = &disp_expressions[i.disp_operands++]; - i.op[op].disps = exp; - exp->X_op = O_constant; - exp->X_add_number = 0; - exp->X_add_symbol = (symbolS *) 0; - exp->X_op_symbol = (symbolS *) 0; - } - - mem = op; - } - else - mem = ~0; - - if (i.tm.opcode_modifier.vexsources == XOP2SOURCES) - { - if (operand_type_check (i.types[0], imm)) - i.vex.register_specifier = NULL; - else - { - /* VEX.vvvv encodes one of the sources when the first - operand is not an immediate. */ - if (i.tm.opcode_modifier.vexw == VEXW0) - i.vex.register_specifier = i.op[0].regs; - else - i.vex.register_specifier = i.op[1].regs; - } - - /* Destination is a XMM register encoded in the ModRM.reg - and VEX.R bit. */ - i.rm.reg = i.op[2].regs->reg_num; - if ((i.op[2].regs->reg_flags & RegRex) != 0) - i.rex |= REX_R; - - /* ModRM.rm and VEX.B encodes the other source. */ - if (!i.mem_operands) - { - i.rm.mode = 3; - - if (i.tm.opcode_modifier.vexw == VEXW0) - i.rm.regmem = i.op[1].regs->reg_num; - else - i.rm.regmem = i.op[0].regs->reg_num; - - if ((i.op[1].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - } - } - else if (i.tm.opcode_modifier.vexvvvv == VEXLWP) - { - i.vex.register_specifier = i.op[2].regs; - if (!i.mem_operands) - { - i.rm.mode = 3; - i.rm.regmem = i.op[1].regs->reg_num; - if ((i.op[1].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - } - } - /* Fill in i.rm.reg or i.rm.regmem field with register operand - (if any) based on i.tm.extension_opcode. Again, we must be - careful to make sure that segment/control/debug/test/MMX - registers are coded into the i.rm.reg field. */ - else if (i.reg_operands) - { - unsigned int op; - unsigned int vex_reg = ~0; - - for (op = 0; op < i.operands; op++) - if (i.types[op].bitfield.reg8 - || i.types[op].bitfield.reg16 - || i.types[op].bitfield.reg32 - || i.types[op].bitfield.reg64 - || i.types[op].bitfield.regmmx - || i.types[op].bitfield.regxmm - || i.types[op].bitfield.regymm - || i.types[op].bitfield.sreg2 - || i.types[op].bitfield.sreg3 - || i.types[op].bitfield.control - || i.types[op].bitfield.debug - || i.types[op].bitfield.test) - break; - - if (vex_3_sources) - op = dest; - else if (i.tm.opcode_modifier.vexvvvv == VEXXDS) - { - /* For instructions with VexNDS, the register-only - source operand is encoded in VEX prefix. */ - gas_assert (mem != (unsigned int) ~0); - - if (op > mem) - { - vex_reg = op++; - gas_assert (op < i.operands); - } - else - { - /* Check register-only source operand when two source - operands are swapped. */ - if (!i.tm.operand_types[op].bitfield.baseindex - && i.tm.operand_types[op + 1].bitfield.baseindex) - { - vex_reg = op; - op += 2; - gas_assert (mem == (vex_reg + 1) - && op < i.operands); - } - else - { - vex_reg = op + 1; - gas_assert (vex_reg < i.operands); - } - } - } - else if (i.tm.opcode_modifier.vexvvvv == VEXNDD) - { - /* For instructions with VexNDD, the register destination - is encoded in VEX prefix. */ - if (i.mem_operands == 0) - { - /* There is no memory operand. */ - gas_assert ((op + 2) == i.operands); - vex_reg = op + 1; - } - else - { - /* There are only 2 operands. */ - gas_assert (op < 2 && i.operands == 2); - vex_reg = 1; - } - } - else - gas_assert (op < i.operands); - - if (vex_reg != (unsigned int) ~0) - { - i386_operand_type *type = &i.tm.operand_types[vex_reg]; - - if (type->bitfield.reg32 != 1 - && type->bitfield.reg64 != 1 - && !operand_type_equal (type, ®xmm) - && !operand_type_equal (type, ®ymm)) - abort (); - - i.vex.register_specifier = i.op[vex_reg].regs; - } - - /* Don't set OP operand twice. */ - if (vex_reg != op) - { - /* If there is an extension opcode to put here, the - register number must be put into the regmem field. */ - if (i.tm.extension_opcode != None) - { - i.rm.regmem = i.op[op].regs->reg_num; - if ((i.op[op].regs->reg_flags & RegRex) != 0) - i.rex |= REX_B; - } - else - { - i.rm.reg = i.op[op].regs->reg_num; - if ((i.op[op].regs->reg_flags & RegRex) != 0) - i.rex |= REX_R; - } - } - - /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we - must set it to 3 to indicate this is a register operand - in the regmem field. */ - if (!i.mem_operands) - i.rm.mode = 3; - } - - /* Fill in i.rm.reg field with extension opcode (if any). */ - if (i.tm.extension_opcode != None) - i.rm.reg = i.tm.extension_opcode; - } - return default_seg; -} - -static void -output_branch (void) -{ - char *p; - int size; - int code16; - int prefix; - relax_substateT subtype; - symbolS *sym; - offsetT off; - - code16 = flag_code == CODE_16BIT ? CODE16 : 0; - size = i.disp32_encoding ? BIG : SMALL; - - prefix = 0; - if (i.prefix[DATA_PREFIX] != 0) - { - prefix = 1; - i.prefixes -= 1; - code16 ^= CODE16; - } - /* Pentium4 branch hints. */ - if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */ - || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */) - { - prefix++; - i.prefixes--; - } - if (i.prefix[REX_PREFIX] != 0) - { - prefix++; - i.prefixes--; - } - - if (i.prefixes != 0 && !intel_syntax) - as_warn (_("skipping prefixes on this instruction")); - - /* It's always a symbol; End frag & setup for relax. - Make sure there is enough room in this frag for the largest - instruction we may generate in md_convert_frag. This is 2 - bytes for the opcode and room for the prefix and largest - displacement. */ - frag_grow (prefix + 2 + 4); - /* Prefix and 1 opcode byte go in fr_fix. */ - p = frag_more (prefix + 1); - if (i.prefix[DATA_PREFIX] != 0) - *p++ = DATA_PREFIX_OPCODE; - if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE - || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE) - *p++ = i.prefix[SEG_PREFIX]; - if (i.prefix[REX_PREFIX] != 0) - *p++ = i.prefix[REX_PREFIX]; - *p = i.tm.base_opcode; - - if ((unsigned char) *p == JUMP_PC_RELATIVE) - subtype = ENCODE_RELAX_STATE (UNCOND_JUMP, size); - else if (cpu_arch_flags.bitfield.cpui386) - subtype = ENCODE_RELAX_STATE (COND_JUMP, size); - else - subtype = ENCODE_RELAX_STATE (COND_JUMP86, size); - subtype |= code16; - - sym = i.op[0].disps->X_add_symbol; - off = i.op[0].disps->X_add_number; - - if (i.op[0].disps->X_op != O_constant - && i.op[0].disps->X_op != O_symbol) - { - /* Handle complex expressions. */ - sym = make_expr_symbol (i.op[0].disps); - off = 0; - } - - /* 1 possible extra opcode + 4 byte displacement go in var part. - Pass reloc in fr_var. */ - frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p); -} - -static void -output_jump (void) -{ - char *p; - int size; - fixS *fixP; - - if (i.tm.opcode_modifier.jumpbyte) - { - /* This is a loop or jecxz type instruction. */ - size = 1; - if (i.prefix[ADDR_PREFIX] != 0) - { - FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE); - i.prefixes -= 1; - } - /* Pentium4 branch hints. */ - if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */ - || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */) - { - FRAG_APPEND_1_CHAR (i.prefix[SEG_PREFIX]); - i.prefixes--; - } - } - else - { - int code16; - - code16 = 0; - if (flag_code == CODE_16BIT) - code16 = CODE16; - - if (i.prefix[DATA_PREFIX] != 0) - { - FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE); - i.prefixes -= 1; - code16 ^= CODE16; - } - - size = 4; - if (code16) - size = 2; - } - - if (i.prefix[REX_PREFIX] != 0) - { - FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]); - i.prefixes -= 1; - } - - if (i.prefixes != 0 && !intel_syntax) - as_warn (_("skipping prefixes on this instruction")); - - p = frag_more (1 + size); - *p++ = i.tm.base_opcode; - - fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); - - /* All jumps handled here are signed, but don't use a signed limit - check for 32 and 16 bit jumps as we want to allow wrap around at - 4G and 64k respectively. */ - if (size == 1) - fixP->fx_signed = 1; -} - -static void -output_interseg_jump (void) -{ - char *p; - int size; - int prefix; - int code16; - - code16 = 0; - if (flag_code == CODE_16BIT) - code16 = CODE16; - - prefix = 0; - if (i.prefix[DATA_PREFIX] != 0) - { - prefix = 1; - i.prefixes -= 1; - code16 ^= CODE16; - } - if (i.prefix[REX_PREFIX] != 0) - { - prefix++; - i.prefixes -= 1; - } - - size = 4; - if (code16) - size = 2; - - if (i.prefixes != 0 && !intel_syntax) - as_warn (_("skipping prefixes on this instruction")); - - /* 1 opcode; 2 segment; offset */ - p = frag_more (prefix + 1 + 2 + size); - - if (i.prefix[DATA_PREFIX] != 0) - *p++ = DATA_PREFIX_OPCODE; - - if (i.prefix[REX_PREFIX] != 0) - *p++ = i.prefix[REX_PREFIX]; - - *p++ = i.tm.base_opcode; - if (i.op[1].imms->X_op == O_constant) - { - offsetT n = i.op[1].imms->X_add_number; - - if (size == 2 - && !fits_in_unsigned_word (n) - && !fits_in_signed_word (n)) - { - as_bad (_("16-bit jump out of range")); - return; - } - md_number_to_chars (p, n, size); - } - else - fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1])); - if (i.op[0].imms->X_op != O_constant) - as_bad (_("can't handle non absolute segment in `%s'"), - i.tm.name); - md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2); -} - -static void -output_insn (void) -{ - fragS *insn_start_frag; - offsetT insn_start_off; - - /* Tie dwarf2 debug info to the address at the start of the insn. - We can't do this after the insn has been output as the current - frag may have been closed off. eg. by frag_var. */ - dwarf2_emit_insn (0); - - insn_start_frag = frag_now; - insn_start_off = frag_now_fix (); - - /* Output jumps. */ - if (i.tm.opcode_modifier.jump) - output_branch (); - else if (i.tm.opcode_modifier.jumpbyte - || i.tm.opcode_modifier.jumpdword) - output_jump (); - else if (i.tm.opcode_modifier.jumpintersegment) - output_interseg_jump (); - else - { - /* Output normal instructions here. */ - char *p; - unsigned char *q; - unsigned int j; - unsigned int prefix; - - /* Since the VEX prefix contains the implicit prefix, we don't - need the explicit prefix. */ - if (!i.tm.opcode_modifier.vex) - { - switch (i.tm.opcode_length) - { - case 3: - if (i.tm.base_opcode & 0xff000000) - { - prefix = (i.tm.base_opcode >> 24) & 0xff; - goto check_prefix; - } - break; - case 2: - if ((i.tm.base_opcode & 0xff0000) != 0) - { - prefix = (i.tm.base_opcode >> 16) & 0xff; - if (i.tm.cpu_flags.bitfield.cpupadlock) - { -check_prefix: - if (prefix != REPE_PREFIX_OPCODE - || (i.prefix[REP_PREFIX] - != REPE_PREFIX_OPCODE)) - add_prefix (prefix); - } - else - add_prefix (prefix); - } - break; - case 1: - break; - default: - abort (); - } - - /* The prefix bytes. */ - for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++) - if (*q) - FRAG_APPEND_1_CHAR (*q); - } - - if (i.tm.opcode_modifier.vex) - { - for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++) - if (*q) - switch (j) - { - case REX_PREFIX: - /* REX byte is encoded in VEX prefix. */ - break; - case SEG_PREFIX: - case ADDR_PREFIX: - FRAG_APPEND_1_CHAR (*q); - break; - default: - /* There should be no other prefixes for instructions - with VEX prefix. */ - abort (); - } - - /* Now the VEX prefix. */ - p = frag_more (i.vex.length); - for (j = 0; j < i.vex.length; j++) - p[j] = i.vex.bytes[j]; - } - - /* Now the opcode; be careful about word order here! */ - if (i.tm.opcode_length == 1) - { - FRAG_APPEND_1_CHAR (i.tm.base_opcode); - } - else - { - switch (i.tm.opcode_length) - { - case 3: - p = frag_more (3); - *p++ = (i.tm.base_opcode >> 16) & 0xff; - break; - case 2: - p = frag_more (2); - break; - default: - abort (); - break; - } - - /* Put out high byte first: can't use md_number_to_chars! */ - *p++ = (i.tm.base_opcode >> 8) & 0xff; - *p = i.tm.base_opcode & 0xff; - } - - /* Now the modrm byte and sib byte (if present). */ - if (i.tm.opcode_modifier.modrm) - { - FRAG_APPEND_1_CHAR ((i.rm.regmem << 0 - | i.rm.reg << 3 - | i.rm.mode << 6)); - /* If i.rm.regmem == ESP (4) - && i.rm.mode != (Register mode) - && not 16 bit - ==> need second modrm byte. */ - if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING - && i.rm.mode != 3 - && !(i.base_reg && i.base_reg->reg_type.bitfield.reg16)) - FRAG_APPEND_1_CHAR ((i.sib.base << 0 - | i.sib.index << 3 - | i.sib.scale << 6)); - } - - if (i.disp_operands) - output_disp (insn_start_frag, insn_start_off); - - if (i.imm_operands) - output_imm (insn_start_frag, insn_start_off); - } - -#ifdef DEBUG386 - if (flag_debug) - { - pi ("" /*line*/, &i); - } -#endif /* DEBUG386 */ -} - -/* Return the size of the displacement operand N. */ - -static int -disp_size (unsigned int n) -{ - int size = 4; - if (i.types[n].bitfield.disp64) - size = 8; - else if (i.types[n].bitfield.disp8) - size = 1; - else if (i.types[n].bitfield.disp16) - size = 2; - return size; -} - -/* Return the size of the immediate operand N. */ - -static int -imm_size (unsigned int n) -{ - int size = 4; - if (i.types[n].bitfield.imm64) - size = 8; - else if (i.types[n].bitfield.imm8 || i.types[n].bitfield.imm8s) - size = 1; - else if (i.types[n].bitfield.imm16) - size = 2; - return size; -} - -static void -output_disp (fragS *insn_start_frag, offsetT insn_start_off) -{ - char *p; - unsigned int n; - - for (n = 0; n < i.operands; n++) - { - if (operand_type_check (i.types[n], disp)) - { - if (i.op[n].disps->X_op == O_constant) - { - int size = disp_size (n); - offsetT val; - - val = offset_in_range (i.op[n].disps->X_add_number, - size); - p = frag_more (size); - md_number_to_chars (p, val, size); - } - else - { - enum bfd_reloc_code_real reloc_type; - int size = disp_size (n); - int sign = i.types[n].bitfield.disp32s; - int pcrel = (i.flags[n] & Operand_PCrel) != 0; - - /* We can't have 8 bit displacement here. */ - gas_assert (!i.types[n].bitfield.disp8); - - /* The PC relative address is computed relative - to the instruction boundary, so in case immediate - fields follows, we need to adjust the value. */ - if (pcrel && i.imm_operands) - { - unsigned int n1; - int sz = 0; - - for (n1 = 0; n1 < i.operands; n1++) - if (operand_type_check (i.types[n1], imm)) - { - /* Only one immediate is allowed for PC - relative address. */ - gas_assert (sz == 0); - sz = imm_size (n1); - i.op[n].disps->X_add_number -= sz; - } - /* We should find the immediate. */ - gas_assert (sz != 0); - } - - p = frag_more (size); - reloc_type = reloc (size, pcrel, sign, i.reloc[n]); - if (GOT_symbol - && GOT_symbol == i.op[n].disps->X_add_symbol - && (((reloc_type == BFD_RELOC_32 - || reloc_type == BFD_RELOC_X86_64_32S - || (reloc_type == BFD_RELOC_64 - && object_64bit)) - && (i.op[n].disps->X_op == O_symbol - || (i.op[n].disps->X_op == O_add - && ((symbol_get_value_expression - (i.op[n].disps->X_op_symbol)->X_op) - == O_subtract)))) - || reloc_type == BFD_RELOC_32_PCREL)) - { - offsetT add; - - if (insn_start_frag == frag_now) - add = (p - frag_now->fr_literal) - insn_start_off; - else - { - fragS *fr; - - add = insn_start_frag->fr_fix - insn_start_off; - for (fr = insn_start_frag->fr_next; - fr && fr != frag_now; fr = fr->fr_next) - add += fr->fr_fix; - add += p - frag_now->fr_literal; - } - - if (!object_64bit) - { - reloc_type = BFD_RELOC_386_GOTPC; - i.op[n].imms->X_add_number += add; - } - else if (reloc_type == BFD_RELOC_64) - reloc_type = BFD_RELOC_X86_64_GOTPC64; - else - /* Don't do the adjustment for x86-64, as there - the pcrel addressing is relative to the _next_ - insn, and that is taken care of in other code. */ - reloc_type = BFD_RELOC_X86_64_GOTPC32; - } - fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[n].disps, pcrel, reloc_type); - } - } - } -} - -static void -output_imm (fragS *insn_start_frag, offsetT insn_start_off) -{ - char *p; - unsigned int n; - - for (n = 0; n < i.operands; n++) - { - if (operand_type_check (i.types[n], imm)) - { - if (i.op[n].imms->X_op == O_constant) - { - int size = imm_size (n); - offsetT val; - - val = offset_in_range (i.op[n].imms->X_add_number, - size); - p = frag_more (size); - md_number_to_chars (p, val, size); - } - else - { - /* Not absolute_section. - Need a 32-bit fixup (don't support 8bit - non-absolute imms). Try to support other - sizes ... */ - enum bfd_reloc_code_real reloc_type; - int size = imm_size (n); - int sign; - - if (i.types[n].bitfield.imm32s - && (i.suffix == QWORD_MNEM_SUFFIX - || (!i.suffix && i.tm.opcode_modifier.no_lsuf))) - sign = 1; - else - sign = 0; - - p = frag_more (size); - reloc_type = reloc (size, 0, sign, i.reloc[n]); - - /* This is tough to explain. We end up with this one if we - * have operands that look like - * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to - * obtain the absolute address of the GOT, and it is strongly - * preferable from a performance point of view to avoid using - * a runtime relocation for this. The actual sequence of - * instructions often look something like: - * - * call .L66 - * .L66: - * popl %ebx - * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx - * - * The call and pop essentially return the absolute address - * of the label .L66 and store it in %ebx. The linker itself - * will ultimately change the first operand of the addl so - * that %ebx points to the GOT, but to keep things simple, the - * .o file must have this operand set so that it generates not - * the absolute address of .L66, but the absolute address of - * itself. This allows the linker itself simply treat a GOTPC - * relocation as asking for a pcrel offset to the GOT to be - * added in, and the addend of the relocation is stored in the - * operand field for the instruction itself. - * - * Our job here is to fix the operand so that it would add - * the correct offset so that %ebx would point to itself. The - * thing that is tricky is that .-.L66 will point to the - * beginning of the instruction, so we need to further modify - * the operand so that it will point to itself. There are - * other cases where you have something like: - * - * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66] - * - * and here no correction would be required. Internally in - * the assembler we treat operands of this form as not being - * pcrel since the '.' is explicitly mentioned, and I wonder - * whether it would simplify matters to do it this way. Who - * knows. In earlier versions of the PIC patches, the - * pcrel_adjust field was used to store the correction, but - * since the expression is not pcrel, I felt it would be - * confusing to do it this way. */ - - if ((reloc_type == BFD_RELOC_32 - || reloc_type == BFD_RELOC_X86_64_32S - || reloc_type == BFD_RELOC_64) - && GOT_symbol - && GOT_symbol == i.op[n].imms->X_add_symbol - && (i.op[n].imms->X_op == O_symbol - || (i.op[n].imms->X_op == O_add - && ((symbol_get_value_expression - (i.op[n].imms->X_op_symbol)->X_op) - == O_subtract)))) - { - offsetT add; - - if (insn_start_frag == frag_now) - add = (p - frag_now->fr_literal) - insn_start_off; - else - { - fragS *fr; - - add = insn_start_frag->fr_fix - insn_start_off; - for (fr = insn_start_frag->fr_next; - fr && fr != frag_now; fr = fr->fr_next) - add += fr->fr_fix; - add += p - frag_now->fr_literal; - } - - if (!object_64bit) - reloc_type = BFD_RELOC_386_GOTPC; - else if (size == 4) - reloc_type = BFD_RELOC_X86_64_GOTPC32; - else if (size == 8) - reloc_type = BFD_RELOC_X86_64_GOTPC64; - i.op[n].imms->X_add_number += add; - } - fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[n].imms, 0, reloc_type); - } - } - } -} - -/* x86_cons_fix_new is called via the expression parsing code when a - reloc is needed. We use this hook to get the correct .got reloc. */ -static enum bfd_reloc_code_real got_reloc = NO_RELOC; -static int cons_sign = -1; - -void -x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, - expressionS *exp) -{ - enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, got_reloc); - - got_reloc = NO_RELOC; - -#ifdef TE_PE - if (exp->X_op == O_secrel) - { - exp->X_op = O_symbol; - r = BFD_RELOC_32_SECREL; - } -#endif - - fix_new_exp (frag, off, len, exp, 0, r); -} - -#if (!defined (OBJ_ELF) && !defined (OBJ_MAYBE_ELF)) || defined (LEX_AT) -# define lex_got(reloc, adjust, types) NULL -#else -/* Parse operands of the form - @GOTOFF+ - and similar .plt or .got references. - - If we find one, set up the correct relocation in RELOC and copy the - input string, minus the `@GOTOFF' into a malloc'd buffer for - parsing by the calling routine. Return this buffer, and if ADJUST - is non-null set it to the length of the string we removed from the - input line. Otherwise return NULL. */ -static char * -lex_got (enum bfd_reloc_code_real *rel, - int *adjust, - i386_operand_type *types) -{ - /* Some of the relocations depend on the size of what field is to - be relocated. But in our callers i386_immediate and i386_displacement - we don't yet know the operand size (this will be set by insn - matching). Hence we record the word32 relocation here, - and adjust the reloc according to the real size in reloc(). */ - static const struct { - const char *str; - int len; - const enum bfd_reloc_code_real rel[2]; - const i386_operand_type types64; - } gotrel[] = { - { STRING_COMMA_LEN ("PLTOFF"), { _dummy_first_bfd_reloc_code_real, - BFD_RELOC_X86_64_PLTOFF64 }, - OPERAND_TYPE_IMM64 }, - { STRING_COMMA_LEN ("PLT"), { BFD_RELOC_386_PLT32, - BFD_RELOC_X86_64_PLT32 }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("GOTPLT"), { _dummy_first_bfd_reloc_code_real, - BFD_RELOC_X86_64_GOTPLT64 }, - OPERAND_TYPE_IMM64_DISP64 }, - { STRING_COMMA_LEN ("GOTOFF"), { BFD_RELOC_386_GOTOFF, - BFD_RELOC_X86_64_GOTOFF64 }, - OPERAND_TYPE_IMM64_DISP64 }, - { STRING_COMMA_LEN ("GOTPCREL"), { _dummy_first_bfd_reloc_code_real, - BFD_RELOC_X86_64_GOTPCREL }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("TLSGD"), { BFD_RELOC_386_TLS_GD, - BFD_RELOC_X86_64_TLSGD }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("TLSLDM"), { BFD_RELOC_386_TLS_LDM, - _dummy_first_bfd_reloc_code_real }, - OPERAND_TYPE_NONE }, - { STRING_COMMA_LEN ("TLSLD"), { _dummy_first_bfd_reloc_code_real, - BFD_RELOC_X86_64_TLSLD }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("GOTTPOFF"), { BFD_RELOC_386_TLS_IE_32, - BFD_RELOC_X86_64_GOTTPOFF }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("TPOFF"), { BFD_RELOC_386_TLS_LE_32, - BFD_RELOC_X86_64_TPOFF32 }, - OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, - { STRING_COMMA_LEN ("NTPOFF"), { BFD_RELOC_386_TLS_LE, - _dummy_first_bfd_reloc_code_real }, - OPERAND_TYPE_NONE }, - { STRING_COMMA_LEN ("DTPOFF"), { BFD_RELOC_386_TLS_LDO_32, - BFD_RELOC_X86_64_DTPOFF32 }, - OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, - { STRING_COMMA_LEN ("GOTNTPOFF"),{ BFD_RELOC_386_TLS_GOTIE, - _dummy_first_bfd_reloc_code_real }, - OPERAND_TYPE_NONE }, - { STRING_COMMA_LEN ("INDNTPOFF"),{ BFD_RELOC_386_TLS_IE, - _dummy_first_bfd_reloc_code_real }, - OPERAND_TYPE_NONE }, - { STRING_COMMA_LEN ("GOT"), { BFD_RELOC_386_GOT32, - BFD_RELOC_X86_64_GOT32 }, - OPERAND_TYPE_IMM32_32S_64_DISP32 }, - { STRING_COMMA_LEN ("TLSDESC"), { BFD_RELOC_386_TLS_GOTDESC, - BFD_RELOC_X86_64_GOTPC32_TLSDESC }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - { STRING_COMMA_LEN ("TLSCALL"), { BFD_RELOC_386_TLS_DESC_CALL, - BFD_RELOC_X86_64_TLSDESC_CALL }, - OPERAND_TYPE_IMM32_32S_DISP32 }, - }; - char *cp; - unsigned int j; - - if (!IS_ELF) - return NULL; - - for (cp = input_line_pointer; *cp != '@'; cp++) - if (is_end_of_line[(unsigned char) *cp] || *cp == ',') - return NULL; - - for (j = 0; j < ARRAY_SIZE (gotrel); j++) - { - int len = gotrel[j].len; - if (strncasecmp (cp + 1, gotrel[j].str, len) == 0) - { - if (gotrel[j].rel[object_64bit] != 0) - { - int first, second; - char *tmpbuf, *past_reloc; - - *rel = gotrel[j].rel[object_64bit]; - if (adjust) - *adjust = len; - - if (types) - { - if (flag_code != CODE_64BIT) - { - types->bitfield.imm32 = 1; - types->bitfield.disp32 = 1; - } - else - *types = gotrel[j].types64; - } - - if (GOT_symbol == NULL) - GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); - - /* The length of the first part of our input line. */ - first = cp - input_line_pointer; - - /* The second part goes from after the reloc token until - (and including) an end_of_line char or comma. */ - past_reloc = cp + 1 + len; - cp = past_reloc; - while (!is_end_of_line[(unsigned char) *cp] && *cp != ',') - ++cp; - second = cp + 1 - past_reloc; - - /* Allocate and copy string. The trailing NUL shouldn't - be necessary, but be safe. */ - tmpbuf = (char *) xmalloc (first + second + 2); - memcpy (tmpbuf, input_line_pointer, first); - if (second != 0 && *past_reloc != ' ') - /* Replace the relocation token with ' ', so that - errors like foo@GOTOFF1 will be detected. */ - tmpbuf[first++] = ' '; - memcpy (tmpbuf + first, past_reloc, second); - tmpbuf[first + second] = '\0'; - return tmpbuf; - } - - as_bad (_("@%s reloc is not supported with %d-bit output format"), - gotrel[j].str, 1 << (5 + object_64bit)); - return NULL; - } - } - - /* Might be a symbol version string. Don't as_bad here. */ - return NULL; -} -#endif - -void -x86_cons (expressionS *exp, int size) -{ - intel_syntax = -intel_syntax; - - exp->X_md = 0; - if (size == 4 || (object_64bit && size == 8)) - { - /* Handle @GOTOFF and the like in an expression. */ - char *save; - char *gotfree_input_line; - int adjust = 0; - - save = input_line_pointer; - gotfree_input_line = lex_got (&got_reloc, &adjust, NULL); - if (gotfree_input_line) - input_line_pointer = gotfree_input_line; - - expression (exp); - - if (gotfree_input_line) - { - /* expression () has merrily parsed up to the end of line, - or a comma - in the wrong buffer. Transfer how far - input_line_pointer has moved to the right buffer. */ - input_line_pointer = (save - + (input_line_pointer - gotfree_input_line) - + adjust); - free (gotfree_input_line); - if (exp->X_op == O_constant - || exp->X_op == O_absent - || exp->X_op == O_illegal - || exp->X_op == O_register - || exp->X_op == O_big) - { - char c = *input_line_pointer; - *input_line_pointer = 0; - as_bad (_("missing or invalid expression `%s'"), save); - *input_line_pointer = c; - } - } - } - else - expression (exp); - - intel_syntax = -intel_syntax; - - if (intel_syntax) - i386_intel_simplify (exp); -} - -static void -signed_cons (int size) -{ - if (flag_code == CODE_64BIT) - cons_sign = 1; - cons (size); - cons_sign = -1; -} - -#ifdef TE_PE -static void -pe_directive_secrel (int dummy ATTRIBUTE_UNUSED) -{ - expressionS exp; - - do - { - expression (&exp); - if (exp.X_op == O_symbol) - exp.X_op = O_secrel; - - emit_expr (&exp, 4); - } - while (*input_line_pointer++ == ','); - - input_line_pointer--; - demand_empty_rest_of_line (); -} -#endif - -static int -i386_immediate (char *imm_start) -{ - char *save_input_line_pointer; - char *gotfree_input_line; - segT exp_seg = 0; - expressionS *exp; - i386_operand_type types; - - operand_type_set (&types, ~0); - - if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) - { - as_bad (_("at most %d immediate operands are allowed"), - MAX_IMMEDIATE_OPERANDS); - return 0; - } - - exp = &im_expressions[i.imm_operands++]; - i.op[this_operand].imms = exp; - - if (is_space_char (*imm_start)) - ++imm_start; - - save_input_line_pointer = input_line_pointer; - input_line_pointer = imm_start; - - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); - if (gotfree_input_line) - input_line_pointer = gotfree_input_line; - - exp_seg = expression (exp); - - SKIP_WHITESPACE (); - if (*input_line_pointer) - as_bad (_("junk `%s' after expression"), input_line_pointer); - - input_line_pointer = save_input_line_pointer; - if (gotfree_input_line) - { - free (gotfree_input_line); - - if (exp->X_op == O_constant || exp->X_op == O_register) - exp->X_op = O_illegal; - } - - return i386_finalize_immediate (exp_seg, exp, types, imm_start); -} - -static int -i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, - i386_operand_type types, const char *imm_start) -{ - if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big) - { - if (imm_start) - as_bad (_("missing or invalid immediate expression `%s'"), - imm_start); - return 0; - } - else if (exp->X_op == O_constant) - { - /* Size it properly later. */ - i.types[this_operand].bitfield.imm64 = 1; - /* If not 64bit, sign extend val. */ - if (flag_code != CODE_64BIT - && (exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0) - exp->X_add_number - = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31); - } -#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) - else if (OUTPUT_FLAVOR == bfd_target_aout_flavour - && exp_seg != absolute_section - && exp_seg != text_section - && exp_seg != data_section - && exp_seg != bss_section - && exp_seg != undefined_section - && !bfd_is_com_section (exp_seg)) - { - as_bad (_("unimplemented segment %s in operand"), exp_seg->name); - return 0; - } -#endif - else if (!intel_syntax && exp->X_op == O_register) - { - if (imm_start) - as_bad (_("illegal immediate register operand %s"), imm_start); - return 0; - } - else - { - /* This is an address. The size of the address will be - determined later, depending on destination register, - suffix, or the default for the section. */ - i.types[this_operand].bitfield.imm8 = 1; - i.types[this_operand].bitfield.imm16 = 1; - i.types[this_operand].bitfield.imm32 = 1; - i.types[this_operand].bitfield.imm32s = 1; - i.types[this_operand].bitfield.imm64 = 1; - i.types[this_operand] = operand_type_and (i.types[this_operand], - types); - } - - return 1; -} - -static char * -i386_scale (char *scale) -{ - offsetT val; - char *save = input_line_pointer; - - input_line_pointer = scale; - val = get_absolute_expression (); - - switch (val) - { - case 1: - i.log2_scale_factor = 0; - break; - case 2: - i.log2_scale_factor = 1; - break; - case 4: - i.log2_scale_factor = 2; - break; - case 8: - i.log2_scale_factor = 3; - break; - default: - { - char sep = *input_line_pointer; - - *input_line_pointer = '\0'; - as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"), - scale); - *input_line_pointer = sep; - input_line_pointer = save; - return NULL; - } - } - if (i.log2_scale_factor != 0 && i.index_reg == 0) - { - as_warn (_("scale factor of %d without an index register"), - 1 << i.log2_scale_factor); - i.log2_scale_factor = 0; - } - scale = input_line_pointer; - input_line_pointer = save; - return scale; -} - -static int -i386_displacement (char *disp_start, char *disp_end) -{ - expressionS *exp; - segT exp_seg = 0; - char *save_input_line_pointer; - char *gotfree_input_line; - int override; - i386_operand_type bigdisp, types = anydisp; - int ret; - - if (i.disp_operands == MAX_MEMORY_OPERANDS) - { - as_bad (_("at most %d displacement operands are allowed"), - MAX_MEMORY_OPERANDS); - return 0; - } - - operand_type_set (&bigdisp, 0); - if ((i.types[this_operand].bitfield.jumpabsolute) - || (!current_templates->start->opcode_modifier.jump - && !current_templates->start->opcode_modifier.jumpdword)) - { - bigdisp.bitfield.disp32 = 1; - override = (i.prefix[ADDR_PREFIX] != 0); - if (flag_code == CODE_64BIT) - { - if (!override) - { - bigdisp.bitfield.disp32s = 1; - bigdisp.bitfield.disp64 = 1; - } - } - else if ((flag_code == CODE_16BIT) ^ override) - { - bigdisp.bitfield.disp32 = 0; - bigdisp.bitfield.disp16 = 1; - } - } - else - { - /* For PC-relative branches, the width of the displacement - is dependent upon data size, not address size. */ - override = (i.prefix[DATA_PREFIX] != 0); - if (flag_code == CODE_64BIT) - { - if (override || i.suffix == WORD_MNEM_SUFFIX) - bigdisp.bitfield.disp16 = 1; - else - { - bigdisp.bitfield.disp32 = 1; - bigdisp.bitfield.disp32s = 1; - } - } - else - { - if (!override) - override = (i.suffix == (flag_code != CODE_16BIT - ? WORD_MNEM_SUFFIX - : LONG_MNEM_SUFFIX)); - bigdisp.bitfield.disp32 = 1; - if ((flag_code == CODE_16BIT) ^ override) - { - bigdisp.bitfield.disp32 = 0; - bigdisp.bitfield.disp16 = 1; - } - } - } - i.types[this_operand] = operand_type_or (i.types[this_operand], - bigdisp); - - exp = &disp_expressions[i.disp_operands]; - i.op[this_operand].disps = exp; - i.disp_operands++; - save_input_line_pointer = input_line_pointer; - input_line_pointer = disp_start; - END_STRING_AND_SAVE (disp_end); - -#ifndef GCC_ASM_O_HACK -#define GCC_ASM_O_HACK 0 -#endif -#if GCC_ASM_O_HACK - END_STRING_AND_SAVE (disp_end + 1); - if (i.types[this_operand].bitfield.baseIndex - && displacement_string_end[-1] == '+') - { - /* This hack is to avoid a warning when using the "o" - constraint within gcc asm statements. - For instance: - - #define _set_tssldt_desc(n,addr,limit,type) \ - __asm__ __volatile__ ( \ - "movw %w2,%0\n\t" \ - "movw %w1,2+%0\n\t" \ - "rorl $16,%1\n\t" \ - "movb %b1,4+%0\n\t" \ - "movb %4,5+%0\n\t" \ - "movb $0,6+%0\n\t" \ - "movb %h1,7+%0\n\t" \ - "rorl $16,%1" \ - : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type)) - - This works great except that the output assembler ends - up looking a bit weird if it turns out that there is - no offset. You end up producing code that looks like: - - #APP - movw $235,(%eax) - movw %dx,2+(%eax) - rorl $16,%edx - movb %dl,4+(%eax) - movb $137,5+(%eax) - movb $0,6+(%eax) - movb %dh,7+(%eax) - rorl $16,%edx - #NO_APP - - So here we provide the missing zero. */ - - *displacement_string_end = '0'; - } -#endif - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); - if (gotfree_input_line) - input_line_pointer = gotfree_input_line; - - exp_seg = expression (exp); - - SKIP_WHITESPACE (); - if (*input_line_pointer) - as_bad (_("junk `%s' after expression"), input_line_pointer); -#if GCC_ASM_O_HACK - RESTORE_END_STRING (disp_end + 1); -#endif - input_line_pointer = save_input_line_pointer; - if (gotfree_input_line) - { - free (gotfree_input_line); - - if (exp->X_op == O_constant || exp->X_op == O_register) - exp->X_op = O_illegal; - } - - ret = i386_finalize_displacement (exp_seg, exp, types, disp_start); - - RESTORE_END_STRING (disp_end); - - return ret; -} - -static int -i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, - i386_operand_type types, const char *disp_start) -{ - i386_operand_type bigdisp; - int ret = 1; - - /* We do this to make sure that the section symbol is in - the symbol table. We will ultimately change the relocation - to be relative to the beginning of the section. */ - if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF - || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL - || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) - { - if (exp->X_op != O_symbol) - goto inv_disp; - - if (S_IS_LOCAL (exp->X_add_symbol) - && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section - && S_GET_SEGMENT (exp->X_add_symbol) != expr_section) - section_symbol (S_GET_SEGMENT (exp->X_add_symbol)); - exp->X_op = O_subtract; - exp->X_op_symbol = GOT_symbol; - if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL) - i.reloc[this_operand] = BFD_RELOC_32_PCREL; - else if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) - i.reloc[this_operand] = BFD_RELOC_64; - else - i.reloc[this_operand] = BFD_RELOC_32; - } - - else if (exp->X_op == O_absent - || exp->X_op == O_illegal - || exp->X_op == O_big) - { - inv_disp: - as_bad (_("missing or invalid displacement expression `%s'"), - disp_start); - ret = 0; - } - - else if (flag_code == CODE_64BIT - && !i.prefix[ADDR_PREFIX] - && exp->X_op == O_constant) - { - /* Since displacement is signed extended to 64bit, don't allow - disp32 and turn off disp32s if they are out of range. */ - i.types[this_operand].bitfield.disp32 = 0; - if (!fits_in_signed_long (exp->X_add_number)) - { - i.types[this_operand].bitfield.disp32s = 0; - if (i.types[this_operand].bitfield.baseindex) - { - as_bad (_("0x%lx out range of signed 32bit displacement"), - (long) exp->X_add_number); - ret = 0; - } - } - } - -#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) - else if (exp->X_op != O_constant - && OUTPUT_FLAVOR == bfd_target_aout_flavour - && exp_seg != absolute_section - && exp_seg != text_section - && exp_seg != data_section - && exp_seg != bss_section - && exp_seg != undefined_section - && !bfd_is_com_section (exp_seg)) - { - as_bad (_("unimplemented segment %s in operand"), exp_seg->name); - ret = 0; - } -#endif - - /* Check if this is a displacement only operand. */ - bigdisp = i.types[this_operand]; - bigdisp.bitfield.disp8 = 0; - bigdisp.bitfield.disp16 = 0; - bigdisp.bitfield.disp32 = 0; - bigdisp.bitfield.disp32s = 0; - bigdisp.bitfield.disp64 = 0; - if (operand_type_all_zero (&bigdisp)) - i.types[this_operand] = operand_type_and (i.types[this_operand], - types); - - return ret; -} - -/* Make sure the memory operand we've been dealt is valid. - Return 1 on success, 0 on a failure. */ - -static int -i386_index_check (const char *operand_string) -{ - int ok; - const char *kind = "base/index"; -#if INFER_ADDR_PREFIX - int fudged = 0; - - tryprefix: -#endif - ok = 1; - if (current_templates->start->opcode_modifier.isstring - && !current_templates->start->opcode_modifier.immext - && (current_templates->end[-1].opcode_modifier.isstring - || i.mem_operands)) - { - /* Memory operands of string insns are special in that they only allow - a single register (rDI, rSI, or rBX) as their memory address. */ - unsigned int expected; - - kind = "string address"; - - if (current_templates->start->opcode_modifier.w) - { - i386_operand_type type = current_templates->end[-1].operand_types[0]; - - if (!type.bitfield.baseindex - || ((!i.mem_operands != !intel_syntax) - && current_templates->end[-1].operand_types[1] - .bitfield.baseindex)) - type = current_templates->end[-1].operand_types[1]; - expected = type.bitfield.esseg ? 7 /* rDI */ : 6 /* rSI */; - } - else - expected = 3 /* rBX */; - - if (!i.base_reg || i.index_reg - || operand_type_check (i.types[this_operand], disp)) - ok = -1; - else if (!(flag_code == CODE_64BIT - ? i.prefix[ADDR_PREFIX] - ? i.base_reg->reg_type.bitfield.reg32 - : i.base_reg->reg_type.bitfield.reg64 - : (flag_code == CODE_16BIT) ^ !i.prefix[ADDR_PREFIX] - ? i.base_reg->reg_type.bitfield.reg32 - : i.base_reg->reg_type.bitfield.reg16)) - ok = 0; - else if (i.base_reg->reg_num != expected) - ok = -1; - - if (ok < 0) - { - unsigned int j; - - for (j = 0; j < i386_regtab_size; ++j) - if ((flag_code == CODE_64BIT - ? i.prefix[ADDR_PREFIX] - ? i386_regtab[j].reg_type.bitfield.reg32 - : i386_regtab[j].reg_type.bitfield.reg64 - : (flag_code == CODE_16BIT) ^ !i.prefix[ADDR_PREFIX] - ? i386_regtab[j].reg_type.bitfield.reg32 - : i386_regtab[j].reg_type.bitfield.reg16) - && i386_regtab[j].reg_num == expected) - break; - gas_assert (j < i386_regtab_size); - as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"), - operand_string, - intel_syntax ? '[' : '(', - register_prefix, - i386_regtab[j].reg_name, - intel_syntax ? ']' : ')'); - ok = 1; - } - } - else if (flag_code == CODE_64BIT) - { - if ((i.base_reg - && ((i.prefix[ADDR_PREFIX] == 0 - && !i.base_reg->reg_type.bitfield.reg64) - || (i.prefix[ADDR_PREFIX] - && !i.base_reg->reg_type.bitfield.reg32)) - && (i.index_reg - || i.base_reg->reg_num != - (i.prefix[ADDR_PREFIX] == 0 ? RegRip : RegEip))) - || (i.index_reg - && !(i.index_reg->reg_type.bitfield.regxmm - || i.index_reg->reg_type.bitfield.regymm) - && (!i.index_reg->reg_type.bitfield.baseindex - || (i.prefix[ADDR_PREFIX] == 0 - && i.index_reg->reg_num != RegRiz - && !i.index_reg->reg_type.bitfield.reg64 - ) - || (i.prefix[ADDR_PREFIX] - && i.index_reg->reg_num != RegEiz - && !i.index_reg->reg_type.bitfield.reg32)))) - ok = 0; - } - else - { - if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0)) - { - /* 16bit checks. */ - if ((i.base_reg - && (!i.base_reg->reg_type.bitfield.reg16 - || !i.base_reg->reg_type.bitfield.baseindex)) - || (i.index_reg - && (!i.index_reg->reg_type.bitfield.reg16 - || !i.index_reg->reg_type.bitfield.baseindex - || !(i.base_reg - && i.base_reg->reg_num < 6 - && i.index_reg->reg_num >= 6 - && i.log2_scale_factor == 0)))) - ok = 0; - } - else - { - /* 32bit checks. */ - if ((i.base_reg - && !i.base_reg->reg_type.bitfield.reg32) - || (i.index_reg - && !i.index_reg->reg_type.bitfield.regxmm - && !i.index_reg->reg_type.bitfield.regymm - && ((!i.index_reg->reg_type.bitfield.reg32 - && i.index_reg->reg_num != RegEiz) - || !i.index_reg->reg_type.bitfield.baseindex))) - ok = 0; - } - } - if (!ok) - { -#if INFER_ADDR_PREFIX - if (!i.mem_operands && !i.prefix[ADDR_PREFIX]) - { - i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE; - i.prefixes += 1; - /* Change the size of any displacement too. At most one of - Disp16 or Disp32 is set. - FIXME. There doesn't seem to be any real need for separate - Disp16 and Disp32 flags. The same goes for Imm16 and Imm32. - Removing them would probably clean up the code quite a lot. */ - if (flag_code != CODE_64BIT - && (i.types[this_operand].bitfield.disp16 - || i.types[this_operand].bitfield.disp32)) - i.types[this_operand] - = operand_type_xor (i.types[this_operand], disp16_32); - fudged = 1; - goto tryprefix; - } - if (fudged) - as_bad (_("`%s' is not a valid %s expression"), - operand_string, - kind); - else -#endif - as_bad (_("`%s' is not a valid %s-bit %s expression"), - operand_string, - flag_code_names[i.prefix[ADDR_PREFIX] - ? flag_code == CODE_32BIT - ? CODE_16BIT - : CODE_32BIT - : flag_code], - kind); - } - return ok; -} - -/* Parse OPERAND_STRING into the i386_insn structure I. Returns zero - on error. */ - -static int -i386_att_operand (char *operand_string) -{ - const reg_entry *r; - char *end_op; - char *op_string = operand_string; - - if (is_space_char (*op_string)) - ++op_string; - - /* We check for an absolute prefix (differentiating, - for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ - if (*op_string == ABSOLUTE_PREFIX) - { - ++op_string; - if (is_space_char (*op_string)) - ++op_string; - i.types[this_operand].bitfield.jumpabsolute = 1; - } - - /* Check if operand is a register. */ - if ((r = parse_register (op_string, &end_op)) != NULL) - { - i386_operand_type temp; - - /* Check for a segment override by searching for ':' after a - segment register. */ - op_string = end_op; - if (is_space_char (*op_string)) - ++op_string; - if (*op_string == ':' - && (r->reg_type.bitfield.sreg2 - || r->reg_type.bitfield.sreg3)) - { - switch (r->reg_num) - { - case 0: - i.seg[i.mem_operands] = &es; - break; - case 1: - i.seg[i.mem_operands] = &cs; - break; - case 2: - i.seg[i.mem_operands] = &ss; - break; - case 3: - i.seg[i.mem_operands] = &ds; - break; - case 4: - i.seg[i.mem_operands] = &fs; - break; - case 5: - i.seg[i.mem_operands] = &gs; - break; - } - - /* Skip the ':' and whitespace. */ - ++op_string; - if (is_space_char (*op_string)) - ++op_string; - - if (!is_digit_char (*op_string) - && !is_identifier_char (*op_string) - && *op_string != '(' - && *op_string != ABSOLUTE_PREFIX) - { - as_bad (_("bad memory operand `%s'"), op_string); - return 0; - } - /* Handle case of %es:*foo. */ - if (*op_string == ABSOLUTE_PREFIX) - { - ++op_string; - if (is_space_char (*op_string)) - ++op_string; - i.types[this_operand].bitfield.jumpabsolute = 1; - } - goto do_memory_reference; - } - if (*op_string) - { - as_bad (_("junk `%s' after register"), op_string); - return 0; - } - temp = r->reg_type; - temp.bitfield.baseindex = 0; - i.types[this_operand] = operand_type_or (i.types[this_operand], - temp); - i.types[this_operand].bitfield.unspecified = 0; - i.op[this_operand].regs = r; - i.reg_operands++; - } - else if (*op_string == REGISTER_PREFIX) - { - as_bad (_("bad register name `%s'"), op_string); - return 0; - } - else if (*op_string == IMMEDIATE_PREFIX) - { - ++op_string; - if (i.types[this_operand].bitfield.jumpabsolute) - { - as_bad (_("immediate operand illegal with absolute jump")); - return 0; - } - if (!i386_immediate (op_string)) - return 0; - } - else if (is_digit_char (*op_string) - || is_identifier_char (*op_string) - || *op_string == '(') - { - /* This is a memory reference of some sort. */ - char *base_string; - - /* Start and end of displacement string expression (if found). */ - char *displacement_string_start; - char *displacement_string_end; - - do_memory_reference: - if ((i.mem_operands == 1 - && !current_templates->start->opcode_modifier.isstring) - || i.mem_operands == 2) - { - as_bad (_("too many memory references for `%s'"), - current_templates->start->name); - return 0; - } - - /* Check for base index form. We detect the base index form by - looking for an ')' at the end of the operand, searching - for the '(' matching it, and finding a REGISTER_PREFIX or ',' - after the '('. */ - base_string = op_string + strlen (op_string); - - --base_string; - if (is_space_char (*base_string)) - --base_string; - - /* If we only have a displacement, set-up for it to be parsed later. */ - displacement_string_start = op_string; - displacement_string_end = base_string + 1; - - if (*base_string == ')') - { - char *temp_string; - unsigned int parens_balanced = 1; - /* We've already checked that the number of left & right ()'s are - equal, so this loop will not be infinite. */ - do - { - base_string--; - if (*base_string == ')') - parens_balanced++; - if (*base_string == '(') - parens_balanced--; - } - while (parens_balanced); - - temp_string = base_string; - - /* Skip past '(' and whitespace. */ - ++base_string; - if (is_space_char (*base_string)) - ++base_string; - - if (*base_string == ',' - || ((i.base_reg = parse_register (base_string, &end_op)) - != NULL)) - { - displacement_string_end = temp_string; - - i.types[this_operand].bitfield.baseindex = 1; - - if (i.base_reg) - { - base_string = end_op; - if (is_space_char (*base_string)) - ++base_string; - } - - /* There may be an index reg or scale factor here. */ - if (*base_string == ',') - { - ++base_string; - if (is_space_char (*base_string)) - ++base_string; - - if ((i.index_reg = parse_register (base_string, &end_op)) - != NULL) - { - base_string = end_op; - if (is_space_char (*base_string)) - ++base_string; - if (*base_string == ',') - { - ++base_string; - if (is_space_char (*base_string)) - ++base_string; - } - else if (*base_string != ')') - { - as_bad (_("expecting `,' or `)' " - "after index register in `%s'"), - operand_string); - return 0; - } - } - else if (*base_string == REGISTER_PREFIX) - { - as_bad (_("bad register name `%s'"), base_string); - return 0; - } - - /* Check for scale factor. */ - if (*base_string != ')') - { - char *end_scale = i386_scale (base_string); - - if (!end_scale) - return 0; - - base_string = end_scale; - if (is_space_char (*base_string)) - ++base_string; - if (*base_string != ')') - { - as_bad (_("expecting `)' " - "after scale factor in `%s'"), - operand_string); - return 0; - } - } - else if (!i.index_reg) - { - as_bad (_("expecting index register or scale factor " - "after `,'; got '%c'"), - *base_string); - return 0; - } - } - else if (*base_string != ')') - { - as_bad (_("expecting `,' or `)' " - "after base register in `%s'"), - operand_string); - return 0; - } - } - else if (*base_string == REGISTER_PREFIX) - { - as_bad (_("bad register name `%s'"), base_string); - return 0; - } - } - - /* If there's an expression beginning the operand, parse it, - assuming displacement_string_start and - displacement_string_end are meaningful. */ - if (displacement_string_start != displacement_string_end) - { - if (!i386_displacement (displacement_string_start, - displacement_string_end)) - return 0; - } - - /* Special case for (%dx) while doing input/output op. */ - if (i.base_reg - && operand_type_equal (&i.base_reg->reg_type, - ®16_inoutportreg) - && i.index_reg == 0 - && i.log2_scale_factor == 0 - && i.seg[i.mem_operands] == 0 - && !operand_type_check (i.types[this_operand], disp)) - { - i.types[this_operand] = inoutportreg; - return 1; - } - - if (i386_index_check (operand_string) == 0) - return 0; - i.types[this_operand].bitfield.mem = 1; - i.mem_operands++; - } - else - { - /* It's not a memory operand; argh! */ - as_bad (_("invalid char %s beginning operand %d `%s'"), - output_invalid (*op_string), - this_operand + 1, - op_string); - return 0; - } - return 1; /* Normal return. */ -} - -/* md_estimate_size_before_relax() - - Called just before relax() for rs_machine_dependent frags. The x86 - assembler uses these frags to handle variable size jump - instructions. - - Any symbol that is now undefined will not become defined. - Return the correct fr_subtype in the frag. - Return the initial "guess for variable size of frag" to caller. - The guess is actually the growth beyond the fixed part. Whatever - we do to grow the fixed or variable part contributes to our - returned value. */ - -int -md_estimate_size_before_relax (fragS *fragP, segT segment) -{ - /* We've already got fragP->fr_subtype right; all we have to do is - check for un-relaxable symbols. On an ELF system, we can't relax - an externally visible symbol, because it may be overridden by a - shared library. */ - if (S_GET_SEGMENT (fragP->fr_symbol) != segment -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - || (IS_ELF - && (S_IS_EXTERNAL (fragP->fr_symbol) - || S_IS_WEAK (fragP->fr_symbol) - || ((symbol_get_bfdsym (fragP->fr_symbol)->flags - & BSF_GNU_INDIRECT_FUNCTION)))) -#endif -#if defined (OBJ_COFF) && defined (TE_PE) - || (OUTPUT_FLAVOR == bfd_target_coff_flavour - && S_IS_WEAK (fragP->fr_symbol)) -#endif - ) - { - /* Symbol is undefined in this segment, or we need to keep a - reloc so that weak symbols can be overridden. */ - int size = (fragP->fr_subtype & CODE16) ? 2 : 4; - enum bfd_reloc_code_real reloc_type; - unsigned char *opcode; - int old_fr_fix; - - if (fragP->fr_var != NO_RELOC) - reloc_type = (enum bfd_reloc_code_real) fragP->fr_var; - else if (size == 2) - reloc_type = BFD_RELOC_16_PCREL; - else - reloc_type = BFD_RELOC_32_PCREL; - - old_fr_fix = fragP->fr_fix; - opcode = (unsigned char *) fragP->fr_opcode; - - switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype)) - { - case UNCOND_JUMP: - /* Make jmp (0xeb) a (d)word displacement jump. */ - opcode[0] = 0xe9; - fragP->fr_fix += size; - fix_new (fragP, old_fr_fix, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - break; - - case COND_JUMP86: - if (size == 2 - && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC)) - { - /* Negate the condition, and branch past an - unconditional jump. */ - opcode[0] ^= 1; - opcode[1] = 3; - /* Insert an unconditional jump. */ - opcode[2] = 0xe9; - /* We added two extra opcode bytes, and have a two byte - offset. */ - fragP->fr_fix += 2 + 2; - fix_new (fragP, old_fr_fix + 2, 2, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - break; - } - /* Fall through. */ - - case COND_JUMP: - if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC) - { - fixS *fixP; - - fragP->fr_fix += 1; - fixP = fix_new (fragP, old_fr_fix, 1, - fragP->fr_symbol, - fragP->fr_offset, 1, - BFD_RELOC_8_PCREL); - fixP->fx_signed = 1; - break; - } - - /* This changes the byte-displacement jump 0x7N - to the (d)word-displacement jump 0x0f,0x8N. */ - opcode[1] = opcode[0] + 0x10; - opcode[0] = TWO_BYTE_OPCODE_ESCAPE; - /* We've added an opcode byte. */ - fragP->fr_fix += 1 + size; - fix_new (fragP, old_fr_fix + 1, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - break; - - default: - BAD_CASE (fragP->fr_subtype); - break; - } - frag_wane (fragP); - return fragP->fr_fix - old_fr_fix; - } - - /* Guess size depending on current relax state. Initially the relax - state will correspond to a short jump and we return 1, because - the variable part of the frag (the branch offset) is one byte - long. However, we can relax a section more than once and in that - case we must either set fr_subtype back to the unrelaxed state, - or return the value for the appropriate branch. */ - return md_relax_table[fragP->fr_subtype].rlx_length; -} - -/* Called after relax() is finished. - - In: Address of frag. - fr_type == rs_machine_dependent. - fr_subtype is what the address relaxed to. - - Out: Any fixSs and constants are set up. - Caller will turn frag into a ".space 0". */ - -void -md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, - fragS *fragP) -{ - unsigned char *opcode; - unsigned char *where_to_put_displacement = NULL; - offsetT target_address; - offsetT opcode_address; - unsigned int extension = 0; - offsetT displacement_from_opcode_start; - - opcode = (unsigned char *) fragP->fr_opcode; - - /* Address we want to reach in file space. */ - target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; - - /* Address opcode resides at in file space. */ - opcode_address = fragP->fr_address + fragP->fr_fix; - - /* Displacement from opcode start to fill into instruction. */ - displacement_from_opcode_start = target_address - opcode_address; - - if ((fragP->fr_subtype & BIG) == 0) - { - /* Don't have to change opcode. */ - extension = 1; /* 1 opcode + 1 displacement */ - where_to_put_displacement = &opcode[1]; - } - else - { - if (no_cond_jump_promotion - && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP) - as_warn_where (fragP->fr_file, fragP->fr_line, - _("long jump required")); - - switch (fragP->fr_subtype) - { - case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG): - extension = 4; /* 1 opcode + 4 displacement */ - opcode[0] = 0xe9; - where_to_put_displacement = &opcode[1]; - break; - - case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16): - extension = 2; /* 1 opcode + 2 displacement */ - opcode[0] = 0xe9; - where_to_put_displacement = &opcode[1]; - break; - - case ENCODE_RELAX_STATE (COND_JUMP, BIG): - case ENCODE_RELAX_STATE (COND_JUMP86, BIG): - extension = 5; /* 2 opcode + 4 displacement */ - opcode[1] = opcode[0] + 0x10; - opcode[0] = TWO_BYTE_OPCODE_ESCAPE; - where_to_put_displacement = &opcode[2]; - break; - - case ENCODE_RELAX_STATE (COND_JUMP, BIG16): - extension = 3; /* 2 opcode + 2 displacement */ - opcode[1] = opcode[0] + 0x10; - opcode[0] = TWO_BYTE_OPCODE_ESCAPE; - where_to_put_displacement = &opcode[2]; - break; - - case ENCODE_RELAX_STATE (COND_JUMP86, BIG16): - extension = 4; - opcode[0] ^= 1; - opcode[1] = 3; - opcode[2] = 0xe9; - where_to_put_displacement = &opcode[3]; - break; - - default: - BAD_CASE (fragP->fr_subtype); - break; - } - } - - /* If size if less then four we are sure that the operand fits, - but if it's 4, then it could be that the displacement is larger - then -/+ 2GB. */ - if (DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype) == 4 - && object_64bit - && ((addressT) (displacement_from_opcode_start - extension - + ((addressT) 1 << 31)) - > (((addressT) 2 << 31) - 1))) - { - as_bad_where (fragP->fr_file, fragP->fr_line, - _("jump target out of range")); - /* Make us emit 0. */ - displacement_from_opcode_start = extension; - } - /* Now put displacement after opcode. */ - md_number_to_chars ((char *) where_to_put_displacement, - (valueT) (displacement_from_opcode_start - extension), - DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); - fragP->fr_fix += extension; -} - -/* Apply a fixup (fixP) to segment data, once it has been determined - by our caller that we have all the info we need to fix it up. - - Parameter valP is the pointer to the value of the bits. - - On the 386, immediates, displacements, and data pointers are all in - the same (little-endian) format, so we don't need to care about which - we are handling. */ - -void -md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) -{ - char *p = fixP->fx_where + fixP->fx_frag->fr_literal; - valueT value = *valP; - -#if !defined (TE_Mach) - if (fixP->fx_pcrel) - { - switch (fixP->fx_r_type) - { - default: - break; - - case BFD_RELOC_64: - fixP->fx_r_type = BFD_RELOC_64_PCREL; - break; - case BFD_RELOC_32: - case BFD_RELOC_X86_64_32S: - fixP->fx_r_type = BFD_RELOC_32_PCREL; - break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_16_PCREL; - break; - case BFD_RELOC_8: - fixP->fx_r_type = BFD_RELOC_8_PCREL; - break; - } - } - - if (fixP->fx_addsy != NULL - && (fixP->fx_r_type == BFD_RELOC_32_PCREL - || fixP->fx_r_type == BFD_RELOC_64_PCREL - || fixP->fx_r_type == BFD_RELOC_16_PCREL - || fixP->fx_r_type == BFD_RELOC_8_PCREL) - && !use_rela_relocations) - { - /* This is a hack. There should be a better way to handle this. - This covers for the fact that bfd_install_relocation will - subtract the current location (for partial_inplace, PC relative - relocations); see more below. */ -#ifndef OBJ_AOUT - if (IS_ELF -#ifdef TE_PE - || OUTPUT_FLAVOR == bfd_target_coff_flavour -#endif - ) - value += fixP->fx_where + fixP->fx_frag->fr_address; -#endif -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - if (IS_ELF) - { - segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy); - - if ((sym_seg == seg - || (symbol_section_p (fixP->fx_addsy) - && sym_seg != absolute_section)) - && !generic_force_reloc (fixP)) - { - /* Yes, we add the values in twice. This is because - bfd_install_relocation subtracts them out again. I think - bfd_install_relocation is broken, but I don't dare change - it. FIXME. */ - value += fixP->fx_where + fixP->fx_frag->fr_address; - } - } -#endif -#if defined (OBJ_COFF) && defined (TE_PE) - /* For some reason, the PE format does not store a - section address offset for a PC relative symbol. */ - if (S_GET_SEGMENT (fixP->fx_addsy) != seg - || S_IS_WEAK (fixP->fx_addsy)) - value += md_pcrel_from (fixP); -#endif - } -#if defined (OBJ_COFF) && defined (TE_PE) - if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy)) - { - value -= S_GET_VALUE (fixP->fx_addsy); - } -#endif - - /* Fix a few things - the dynamic linker expects certain values here, - and we must not disappoint it. */ -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - if (IS_ELF && fixP->fx_addsy) - switch (fixP->fx_r_type) - { - case BFD_RELOC_386_PLT32: - case BFD_RELOC_X86_64_PLT32: - /* Make the jump instruction point to the address of the operand. At - runtime we merely add the offset to the actual PLT entry. */ - value = -4; - break; - - case BFD_RELOC_386_TLS_GD: - case BFD_RELOC_386_TLS_LDM: - case BFD_RELOC_386_TLS_IE_32: - case BFD_RELOC_386_TLS_IE: - case BFD_RELOC_386_TLS_GOTIE: - case BFD_RELOC_386_TLS_GOTDESC: - case BFD_RELOC_X86_64_TLSGD: - case BFD_RELOC_X86_64_TLSLD: - case BFD_RELOC_X86_64_GOTTPOFF: - case BFD_RELOC_X86_64_GOTPC32_TLSDESC: - value = 0; /* Fully resolved at runtime. No addend. */ - /* Fallthrough */ - case BFD_RELOC_386_TLS_LE: - case BFD_RELOC_386_TLS_LDO_32: - case BFD_RELOC_386_TLS_LE_32: - case BFD_RELOC_X86_64_DTPOFF32: - case BFD_RELOC_X86_64_DTPOFF64: - case BFD_RELOC_X86_64_TPOFF32: - case BFD_RELOC_X86_64_TPOFF64: - S_SET_THREAD_LOCAL (fixP->fx_addsy); - break; - - case BFD_RELOC_386_TLS_DESC_CALL: - case BFD_RELOC_X86_64_TLSDESC_CALL: - value = 0; /* Fully resolved at runtime. No addend. */ - S_SET_THREAD_LOCAL (fixP->fx_addsy); - fixP->fx_done = 0; - return; - - case BFD_RELOC_386_GOT32: - case BFD_RELOC_X86_64_GOT32: - value = 0; /* Fully resolved at runtime. No addend. */ - break; - - case BFD_RELOC_VTABLE_INHERIT: - case BFD_RELOC_VTABLE_ENTRY: - fixP->fx_done = 0; - return; - - default: - break; - } -#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */ - *valP = value; -#endif /* !defined (TE_Mach) */ - - /* Are we finished with this relocation now? */ - if (fixP->fx_addsy == NULL) - fixP->fx_done = 1; -#if defined (OBJ_COFF) && defined (TE_PE) - else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy)) - { - fixP->fx_done = 0; - /* Remember value for tc_gen_reloc. */ - fixP->fx_addnumber = value; - /* Clear out the frag for now. */ - value = 0; - } -#endif - else if (use_rela_relocations) - { - fixP->fx_no_overflow = 1; - /* Remember value for tc_gen_reloc. */ - fixP->fx_addnumber = value; - value = 0; - } - - md_number_to_chars (p, value, fixP->fx_size); -} - -char * -md_atof (int type, char *litP, int *sizeP) -{ - /* This outputs the LITTLENUMs in REVERSE order; - in accord with the bigendian 386. */ - return ieee_md_atof (type, litP, sizeP, FALSE); -} - -static char output_invalid_buf[sizeof (unsigned char) * 2 + 6]; - -static char * -output_invalid (int c) -{ - if (ISPRINT (c)) - snprintf (output_invalid_buf, sizeof (output_invalid_buf), - "'%c'", c); - else - snprintf (output_invalid_buf, sizeof (output_invalid_buf), - "(0x%x)", (unsigned char) c); - return output_invalid_buf; -} - -/* REG_STRING starts *before* REGISTER_PREFIX. */ - -static const reg_entry * -parse_real_register (char *reg_string, char **end_op) -{ - char *s = reg_string; - char *p; - char reg_name_given[MAX_REG_NAME_SIZE + 1]; - const reg_entry *r; - - /* Skip possible REGISTER_PREFIX and possible whitespace. */ - if (*s == REGISTER_PREFIX) - ++s; - - if (is_space_char (*s)) - ++s; - - p = reg_name_given; - while ((*p++ = register_chars[(unsigned char) *s]) != '\0') - { - if (p >= reg_name_given + MAX_REG_NAME_SIZE) - return (const reg_entry *) NULL; - s++; - } - - /* For naked regs, make sure that we are not dealing with an identifier. - This prevents confusing an identifier like `eax_var' with register - `eax'. */ - if (allow_naked_reg && identifier_chars[(unsigned char) *s]) - return (const reg_entry *) NULL; - - *end_op = s; - - r = (const reg_entry *) hash_find (reg_hash, reg_name_given); - - /* Handle floating point regs, allowing spaces in the (i) part. */ - if (r == i386_regtab /* %st is first entry of table */) - { - if (is_space_char (*s)) - ++s; - if (*s == '(') - { - ++s; - if (is_space_char (*s)) - ++s; - if (*s >= '0' && *s <= '7') - { - int fpr = *s - '0'; - ++s; - if (is_space_char (*s)) - ++s; - if (*s == ')') - { - *end_op = s + 1; - r = (const reg_entry *) hash_find (reg_hash, "st(0)"); - know (r); - return r + fpr; - } - } - /* We have "%st(" then garbage. */ - return (const reg_entry *) NULL; - } - } - - if (r == NULL || allow_pseudo_reg) - return r; - - if (operand_type_all_zero (&r->reg_type)) - return (const reg_entry *) NULL; - - if ((r->reg_type.bitfield.reg32 - || r->reg_type.bitfield.sreg3 - || r->reg_type.bitfield.control - || r->reg_type.bitfield.debug - || r->reg_type.bitfield.test) - && !cpu_arch_flags.bitfield.cpui386) - return (const reg_entry *) NULL; - - if (r->reg_type.bitfield.floatreg - && !cpu_arch_flags.bitfield.cpu8087 - && !cpu_arch_flags.bitfield.cpu287 - && !cpu_arch_flags.bitfield.cpu387) - return (const reg_entry *) NULL; - - if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx) - return (const reg_entry *) NULL; - - if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse) - return (const reg_entry *) NULL; - - if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuavx) - return (const reg_entry *) NULL; - - /* Don't allow fake index register unless allow_index_reg isn't 0. */ - if (!allow_index_reg - && (r->reg_num == RegEiz || r->reg_num == RegRiz)) - return (const reg_entry *) NULL; - - if (((r->reg_flags & (RegRex64 | RegRex)) - || r->reg_type.bitfield.reg64) - && (!cpu_arch_flags.bitfield.cpulm - || !operand_type_equal (&r->reg_type, &control)) - && flag_code != CODE_64BIT) - return (const reg_entry *) NULL; - - if (r->reg_type.bitfield.sreg3 && r->reg_num == RegFlat && !intel_syntax) - return (const reg_entry *) NULL; - - return r; -} - -/* REG_STRING starts *before* REGISTER_PREFIX. */ - -static const reg_entry * -parse_register (char *reg_string, char **end_op) -{ - const reg_entry *r; - - if (*reg_string == REGISTER_PREFIX || allow_naked_reg) - r = parse_real_register (reg_string, end_op); - else - r = NULL; - if (!r) - { - char *save = input_line_pointer; - char c; - symbolS *symbolP; - - input_line_pointer = reg_string; - c = get_symbol_end (); - symbolP = symbol_find (reg_string); - if (symbolP && S_GET_SEGMENT (symbolP) == reg_section) - { - const expressionS *e = symbol_get_value_expression (symbolP); - - know (e->X_op == O_register); - know (e->X_add_number >= 0 - && (valueT) e->X_add_number < i386_regtab_size); - r = i386_regtab + e->X_add_number; - *end_op = input_line_pointer; - } - *input_line_pointer = c; - input_line_pointer = save; - } - return r; -} - -int -i386_parse_name (char *name, expressionS *e, char *nextcharP) -{ - const reg_entry *r; - char *end = input_line_pointer; - - *end = *nextcharP; - r = parse_register (name, &input_line_pointer); - if (r && end <= input_line_pointer) - { - *nextcharP = *input_line_pointer; - *input_line_pointer = 0; - e->X_op = O_register; - e->X_add_number = r - i386_regtab; - return 1; - } - input_line_pointer = end; - *end = 0; - return intel_syntax ? i386_intel_parse_name (name, e) : 0; -} - -void -md_operand (expressionS *e) -{ - char *end; - const reg_entry *r; - - switch (*input_line_pointer) - { - case REGISTER_PREFIX: - r = parse_real_register (input_line_pointer, &end); - if (r) - { - e->X_op = O_register; - e->X_add_number = r - i386_regtab; - input_line_pointer = end; - } - break; - - case '[': - gas_assert (intel_syntax); - end = input_line_pointer++; - expression (e); - if (*input_line_pointer == ']') - { - ++input_line_pointer; - e->X_op_symbol = make_expr_symbol (e); - e->X_add_symbol = NULL; - e->X_add_number = 0; - e->X_op = O_index; - } - else - { - e->X_op = O_absent; - input_line_pointer = end; - } - break; - } -} - - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) -const char *md_shortopts = "kVQ:sqn"; -#else -const char *md_shortopts = "qn"; -#endif - -#define OPTION_32 (OPTION_MD_BASE + 0) -#define OPTION_64 (OPTION_MD_BASE + 1) -#define OPTION_DIVIDE (OPTION_MD_BASE + 2) -#define OPTION_MARCH (OPTION_MD_BASE + 3) -#define OPTION_MTUNE (OPTION_MD_BASE + 4) -#define OPTION_MMNEMONIC (OPTION_MD_BASE + 5) -#define OPTION_MSYNTAX (OPTION_MD_BASE + 6) -#define OPTION_MINDEX_REG (OPTION_MD_BASE + 7) -#define OPTION_MNAKED_REG (OPTION_MD_BASE + 8) -#define OPTION_MOLD_GCC (OPTION_MD_BASE + 9) -#define OPTION_MSSE2AVX (OPTION_MD_BASE + 10) -#define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11) -#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 12) -#define OPTION_X32 (OPTION_MD_BASE + 13) - -struct option md_longopts[] = -{ - {"32", no_argument, NULL, OPTION_32}, -#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP)) - {"64", no_argument, NULL, OPTION_64}, -#endif -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - {"x32", no_argument, NULL, OPTION_X32}, -#endif - {"divide", no_argument, NULL, OPTION_DIVIDE}, - {"march", required_argument, NULL, OPTION_MARCH}, - {"mtune", required_argument, NULL, OPTION_MTUNE}, - {"mmnemonic", required_argument, NULL, OPTION_MMNEMONIC}, - {"msyntax", required_argument, NULL, OPTION_MSYNTAX}, - {"mindex-reg", no_argument, NULL, OPTION_MINDEX_REG}, - {"mnaked-reg", no_argument, NULL, OPTION_MNAKED_REG}, - {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC}, - {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX}, - {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK}, - {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR}, - {NULL, no_argument, NULL, 0} -}; -size_t md_longopts_size = sizeof (md_longopts); - -int -md_parse_option (int c, char *arg) -{ - unsigned int j; - char *arch, *next; - - switch (c) - { - case 'n': - optimize_align_code = 0; - break; - - case 'q': - quiet_warnings = 1; - break; - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section - should be emitted or not. FIXME: Not implemented. */ - case 'Q': - break; - - /* -V: SVR4 argument to print version ID. */ - case 'V': - print_version_id (); - break; - - /* -k: Ignore for FreeBSD compatibility. */ - case 'k': - break; - - case 's': - /* -s: On i386 Solaris, this tells the native assembler to use - .stab instead of .stab.excl. We always use .stab anyhow. */ - break; -#endif -#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP)) - case OPTION_64: - { - const char **list, **l; - - list = bfd_target_list (); - for (l = list; *l != NULL; l++) - if (CONST_STRNEQ (*l, "elf64-x86-64") - || strcmp (*l, "coff-x86-64") == 0 - || strcmp (*l, "pe-x86-64") == 0 - || strcmp (*l, "pei-x86-64") == 0) - { - default_arch = "x86_64"; - break; - } - if (*l == NULL) - as_fatal (_("no compiled in support for x86_64")); - free (list); - } - break; -#endif - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - case OPTION_X32: - if (IS_ELF) - { - const char **list, **l; - - list = bfd_target_list (); - for (l = list; *l != NULL; l++) - if (CONST_STRNEQ (*l, "elf32-x86-64")) - { - default_arch = "x86_64:32"; - break; - } - if (*l == NULL) - as_fatal (_("no compiled in support for 32bit x86_64")); - free (list); - } - else - as_fatal (_("32bit x86_64 is only supported for ELF")); - break; -#endif - - case OPTION_32: - default_arch = "i386"; - break; - - case OPTION_DIVIDE: -#ifdef SVR4_COMMENT_CHARS - { - char *n, *t; - const char *s; - - n = (char *) xmalloc (strlen (i386_comment_chars) + 1); - t = n; - for (s = i386_comment_chars; *s != '\0'; s++) - if (*s != '/') - *t++ = *s; - *t = '\0'; - i386_comment_chars = n; - } -#endif - break; - - case OPTION_MARCH: - arch = xstrdup (arg); - do - { - if (*arch == '.') - as_fatal (_("invalid -march= option: `%s'"), arg); - next = strchr (arch, '+'); - if (next) - *next++ = '\0'; - for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) - { - if (strcmp (arch, cpu_arch [j].name) == 0) - { - /* Processor. */ - if (! cpu_arch[j].flags.bitfield.cpui386) - continue; - - cpu_arch_name = cpu_arch[j].name; - cpu_sub_arch_name = NULL; - cpu_arch_flags = cpu_arch[j].flags; - cpu_arch_isa = cpu_arch[j].type; - cpu_arch_isa_flags = cpu_arch[j].flags; - if (!cpu_arch_tune_set) - { - cpu_arch_tune = cpu_arch_isa; - cpu_arch_tune_flags = cpu_arch_isa_flags; - } - break; - } - else if (*cpu_arch [j].name == '.' - && strcmp (arch, cpu_arch [j].name + 1) == 0) - { - /* ISA entension. */ - i386_cpu_flags flags; - - if (!cpu_arch[j].negated) - flags = cpu_flags_or (cpu_arch_flags, - cpu_arch[j].flags); - else - flags = cpu_flags_and_not (cpu_arch_flags, - cpu_arch[j].flags); - if (!cpu_flags_equal (&flags, &cpu_arch_flags)) - { - if (cpu_sub_arch_name) - { - char *name = cpu_sub_arch_name; - cpu_sub_arch_name = concat (name, - cpu_arch[j].name, - (const char *) NULL); - free (name); - } - else - cpu_sub_arch_name = xstrdup (cpu_arch[j].name); - cpu_arch_flags = flags; - cpu_arch_isa_flags = flags; - } - break; - } - } - - if (j >= ARRAY_SIZE (cpu_arch)) - as_fatal (_("invalid -march= option: `%s'"), arg); - - arch = next; - } - while (next != NULL ); - break; - - case OPTION_MTUNE: - if (*arg == '.') - as_fatal (_("invalid -mtune= option: `%s'"), arg); - for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) - { - if (strcmp (arg, cpu_arch [j].name) == 0) - { - cpu_arch_tune_set = 1; - cpu_arch_tune = cpu_arch [j].type; - cpu_arch_tune_flags = cpu_arch[j].flags; - break; - } - } - if (j >= ARRAY_SIZE (cpu_arch)) - as_fatal (_("invalid -mtune= option: `%s'"), arg); - break; - - case OPTION_MMNEMONIC: - if (strcasecmp (arg, "att") == 0) - intel_mnemonic = 0; - else if (strcasecmp (arg, "intel") == 0) - intel_mnemonic = 1; - else - as_fatal (_("invalid -mmnemonic= option: `%s'"), arg); - break; - - case OPTION_MSYNTAX: - if (strcasecmp (arg, "att") == 0) - intel_syntax = 0; - else if (strcasecmp (arg, "intel") == 0) - intel_syntax = 1; - else - as_fatal (_("invalid -msyntax= option: `%s'"), arg); - break; - - case OPTION_MINDEX_REG: - allow_index_reg = 1; - break; - - case OPTION_MNAKED_REG: - allow_naked_reg = 1; - break; - - case OPTION_MOLD_GCC: - old_gcc = 1; - break; - - case OPTION_MSSE2AVX: - sse2avx = 1; - break; - - case OPTION_MSSE_CHECK: - if (strcasecmp (arg, "error") == 0) - sse_check = sse_check_error; - else if (strcasecmp (arg, "warning") == 0) - sse_check = sse_check_warning; - else if (strcasecmp (arg, "none") == 0) - sse_check = sse_check_none; - else - as_fatal (_("invalid -msse-check= option: `%s'"), arg); - break; - - case OPTION_MAVXSCALAR: - if (strcasecmp (arg, "128") == 0) - avxscalar = vex128; - else if (strcasecmp (arg, "256") == 0) - avxscalar = vex256; - else - as_fatal (_("invalid -mavxscalar= option: `%s'"), arg); - break; - - default: - return 0; - } - return 1; -} - -#define MESSAGE_TEMPLATE \ -" " - -static void -show_arch (FILE *stream, int ext, int check) -{ - static char message[] = MESSAGE_TEMPLATE; - char *start = message + 27; - char *p; - int size = sizeof (MESSAGE_TEMPLATE); - int left; - const char *name; - int len; - unsigned int j; - - p = start; - left = size - (start - message); - for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) - { - /* Should it be skipped? */ - if (cpu_arch [j].skip) - continue; - - name = cpu_arch [j].name; - len = cpu_arch [j].len; - if (*name == '.') - { - /* It is an extension. Skip if we aren't asked to show it. */ - if (ext) - { - name++; - len--; - } - else - continue; - } - else if (ext) - { - /* It is an processor. Skip if we show only extension. */ - continue; - } - else if (check && ! cpu_arch[j].flags.bitfield.cpui386) - { - /* It is an impossible processor - skip. */ - continue; - } - - /* Reserve 2 spaces for ", " or ",\0" */ - left -= len + 2; - - /* Check if there is any room. */ - if (left >= 0) - { - if (p != start) - { - *p++ = ','; - *p++ = ' '; - } - p = mempcpy (p, name, len); - } - else - { - /* Output the current message now and start a new one. */ - *p++ = ','; - *p = '\0'; - fprintf (stream, "%s\n", message); - p = start; - left = size - (start - message) - len - 2; - - gas_assert (left >= 0); - - p = mempcpy (p, name, len); - } - } - - *p = '\0'; - fprintf (stream, "%s\n", message); -} - -void -md_show_usage (FILE *stream) -{ -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - fprintf (stream, _("\ - -Q ignored\n\ - -V print assembler version number\n\ - -k ignored\n")); -#endif - fprintf (stream, _("\ - -n Do not optimize code alignment\n\ - -q quieten some warnings\n")); -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - fprintf (stream, _("\ - -s ignored\n")); -#endif -#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP)) - fprintf (stream, _("\ - --32/--64/--x32 generate 32bit/64bit/x32 code\n")); -#endif -#ifdef SVR4_COMMENT_CHARS - fprintf (stream, _("\ - --divide do not treat `/' as a comment character\n")); -#else - fprintf (stream, _("\ - --divide ignored\n")); -#endif - fprintf (stream, _("\ - -march=CPU[,+EXTENSION...]\n\ - generate code for CPU and EXTENSION, CPU is one of:\n")); - show_arch (stream, 0, 1); - fprintf (stream, _("\ - EXTENSION is combination of:\n")); - show_arch (stream, 1, 0); - fprintf (stream, _("\ - -mtune=CPU optimize for CPU, CPU is one of:\n")); - show_arch (stream, 0, 0); - fprintf (stream, _("\ - -msse2avx encode SSE instructions with VEX prefix\n")); - fprintf (stream, _("\ - -msse-check=[none|error|warning]\n\ - check SSE instructions\n")); - fprintf (stream, _("\ - -mavxscalar=[128|256] encode scalar AVX instructions with specific vector\n\ - length\n")); - fprintf (stream, _("\ - -mmnemonic=[att|intel] use AT&T/Intel mnemonic\n")); - fprintf (stream, _("\ - -msyntax=[att|intel] use AT&T/Intel syntax\n")); - fprintf (stream, _("\ - -mindex-reg support pseudo index registers\n")); - fprintf (stream, _("\ - -mnaked-reg don't require `%%' prefix for registers\n")); - fprintf (stream, _("\ - -mold-gcc support old (<= 2.8.1) versions of gcc\n")); -} - -#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ - || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) - -/* Pick the target format to use. */ - -const char * -i386_target_format (void) -{ - if (!strncmp (default_arch, "x86_64", 6)) - { - update_code_flag (CODE_64BIT, 1); - if (default_arch[6] == '\0') - x86_elf_abi = X86_64_ABI; - else - x86_elf_abi = X86_64_X32_ABI; - } - else if (!strcmp (default_arch, "i386")) - update_code_flag (CODE_32BIT, 1); - else - as_fatal (_("unknown architecture")); - - if (cpu_flags_all_zero (&cpu_arch_isa_flags)) - cpu_arch_isa_flags = cpu_arch[flag_code == CODE_64BIT].flags; - if (cpu_flags_all_zero (&cpu_arch_tune_flags)) - cpu_arch_tune_flags = cpu_arch[flag_code == CODE_64BIT].flags; - - switch (OUTPUT_FLAVOR) - { -#if defined (OBJ_MAYBE_AOUT) || defined (OBJ_AOUT) - case bfd_target_aout_flavour: - return AOUT_TARGET_FORMAT; -#endif -#if defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF) -# if defined (TE_PE) || defined (TE_PEP) - case bfd_target_coff_flavour: - return flag_code == CODE_64BIT ? "pe-x86-64" : "pe-i386"; -# elif defined (TE_GO32) - case bfd_target_coff_flavour: - return "coff-go32"; -# else - case bfd_target_coff_flavour: - return "coff-i386"; -# endif -#endif -#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) - case bfd_target_elf_flavour: - { - const char *format; - - switch (x86_elf_abi) - { - default: - format = ELF_TARGET_FORMAT; - break; - case X86_64_ABI: - use_rela_relocations = 1; - object_64bit = 1; - format = ELF_TARGET_FORMAT64; - break; - case X86_64_X32_ABI: - use_rela_relocations = 1; - object_64bit = 1; - disallow_64bit_reloc = 1; - format = ELF_TARGET_FORMAT32; - break; - } - if (cpu_arch_isa == PROCESSOR_L1OM) - { - if (x86_elf_abi != X86_64_ABI) - as_fatal (_("Intel L1OM is 64bit only")); - return ELF_TARGET_L1OM_FORMAT; - } - if (cpu_arch_isa == PROCESSOR_K1OM) - { - if (x86_elf_abi != X86_64_ABI) - as_fatal (_("Intel K1OM is 64bit only")); - return ELF_TARGET_K1OM_FORMAT; - } - else - return format; - } -#endif -#if defined (OBJ_MACH_O) - case bfd_target_mach_o_flavour: - return flag_code == CODE_64BIT ? "mach-o-x86-64" : "mach-o-i386"; -#endif - default: - abort (); - return NULL; - } -} - -#endif /* OBJ_MAYBE_ more than one */ - -#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) -void -i386_elf_emit_arch_note (void) -{ - if (IS_ELF && cpu_arch_name != NULL) - { - char *p; - asection *seg = now_seg; - subsegT subseg = now_subseg; - Elf_Internal_Note i_note; - Elf_External_Note e_note; - asection *note_secp; - int len; - - /* Create the .note section. */ - note_secp = subseg_new (".note", 0); - bfd_set_section_flags (stdoutput, - note_secp, - SEC_HAS_CONTENTS | SEC_READONLY); - - /* Process the arch string. */ - len = strlen (cpu_arch_name); - - i_note.namesz = len + 1; - i_note.descsz = 0; - i_note.type = NT_ARCH; - p = frag_more (sizeof (e_note.namesz)); - md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz)); - p = frag_more (sizeof (e_note.descsz)); - md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz)); - p = frag_more (sizeof (e_note.type)); - md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type)); - p = frag_more (len + 1); - strcpy (p, cpu_arch_name); - - frag_align (2, 0, 0); - - subseg_set (seg, subseg); - } -} -#endif - -symbolS * -md_undefined_symbol (char *name) -{ - if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0] - && name[1] == GLOBAL_OFFSET_TABLE_NAME[1] - && name[2] == GLOBAL_OFFSET_TABLE_NAME[2] - && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0) - { - if (!GOT_symbol) - { - if (symbol_find (name)) - as_bad (_("GOT already in symbol table")); - GOT_symbol = symbol_new (name, undefined_section, - (valueT) 0, &zero_address_frag); - }; - return GOT_symbol; - } - return 0; -} - -/* Round up a section size to the appropriate boundary. */ - -valueT -md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) -{ -#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) - if (OUTPUT_FLAVOR == bfd_target_aout_flavour) - { - /* For a.out, force the section size to be aligned. If we don't do - this, BFD will align it for us, but it will not write out the - final bytes of the section. This may be a bug in BFD, but it is - easier to fix it here since that is how the other a.out targets - work. */ - int align; - - align = bfd_get_section_alignment (stdoutput, segment); - size = ((size + (1 << align) - 1) & ((valueT) -1 << align)); - } -#endif - - return size; -} - -/* On the i386, PC-relative offsets are relative to the start of the - next instruction. That is, the address of the offset, plus its - size, since the offset is always the last part of the insn. */ - -long -md_pcrel_from (fixS *fixP) -{ - return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; -} - -#ifndef I386COFF - -static void -s_bss (int ignore ATTRIBUTE_UNUSED) -{ - int temp; - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) - if (IS_ELF) - obj_elf_section_change_hook (); -#endif - temp = get_absolute_expression (); - subseg_set (bss_section, (subsegT) temp); - demand_empty_rest_of_line (); -} - -#endif - -void -i386_validate_fix (fixS *fixp) -{ - if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol) - { - if (fixp->fx_r_type == BFD_RELOC_32_PCREL) - { - if (!object_64bit) - abort (); - fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL; - } - else - { - if (!object_64bit) - fixp->fx_r_type = BFD_RELOC_386_GOTOFF; - else - fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64; - } - fixp->fx_subsy = 0; - } -} - -arelent * -tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) -{ - arelent *rel; - bfd_reloc_code_real_type code; - - switch (fixp->fx_r_type) - { - case BFD_RELOC_X86_64_PLT32: - case BFD_RELOC_X86_64_GOT32: - case BFD_RELOC_X86_64_GOTPCREL: - case BFD_RELOC_386_PLT32: - case BFD_RELOC_386_GOT32: - case BFD_RELOC_386_GOTOFF: - case BFD_RELOC_386_GOTPC: - case BFD_RELOC_386_TLS_GD: - case BFD_RELOC_386_TLS_LDM: - case BFD_RELOC_386_TLS_LDO_32: - case BFD_RELOC_386_TLS_IE_32: - case BFD_RELOC_386_TLS_IE: - case BFD_RELOC_386_TLS_GOTIE: - case BFD_RELOC_386_TLS_LE_32: - case BFD_RELOC_386_TLS_LE: - case BFD_RELOC_386_TLS_GOTDESC: - case BFD_RELOC_386_TLS_DESC_CALL: - case BFD_RELOC_X86_64_TLSGD: - case BFD_RELOC_X86_64_TLSLD: - case BFD_RELOC_X86_64_DTPOFF32: - case BFD_RELOC_X86_64_DTPOFF64: - case BFD_RELOC_X86_64_GOTTPOFF: - case BFD_RELOC_X86_64_TPOFF32: - case BFD_RELOC_X86_64_TPOFF64: - case BFD_RELOC_X86_64_GOTOFF64: - case BFD_RELOC_X86_64_GOTPC32: - case BFD_RELOC_X86_64_GOT64: - case BFD_RELOC_X86_64_GOTPCREL64: - case BFD_RELOC_X86_64_GOTPC64: - case BFD_RELOC_X86_64_GOTPLT64: - case BFD_RELOC_X86_64_PLTOFF64: - case BFD_RELOC_X86_64_GOTPC32_TLSDESC: - case BFD_RELOC_X86_64_TLSDESC_CALL: - case BFD_RELOC_RVA: - case BFD_RELOC_VTABLE_ENTRY: - case BFD_RELOC_VTABLE_INHERIT: -#ifdef TE_PE - case BFD_RELOC_32_SECREL: -#endif - code = fixp->fx_r_type; - break; - case BFD_RELOC_X86_64_32S: - if (!fixp->fx_pcrel) - { - /* Don't turn BFD_RELOC_X86_64_32S into BFD_RELOC_32. */ - code = fixp->fx_r_type; - break; - } - default: - if (fixp->fx_pcrel) - { - switch (fixp->fx_size) - { - default: - as_bad_where (fixp->fx_file, fixp->fx_line, - _("can not do %d byte pc-relative relocation"), - fixp->fx_size); - code = BFD_RELOC_32_PCREL; - break; - case 1: code = BFD_RELOC_8_PCREL; break; - case 2: code = BFD_RELOC_16_PCREL; break; - case 4: code = BFD_RELOC_32_PCREL; break; -#ifdef BFD64 - case 8: code = BFD_RELOC_64_PCREL; break; -#endif - } - } - else - { - switch (fixp->fx_size) - { - default: - as_bad_where (fixp->fx_file, fixp->fx_line, - _("can not do %d byte relocation"), - fixp->fx_size); - code = BFD_RELOC_32; - break; - case 1: code = BFD_RELOC_8; break; - case 2: code = BFD_RELOC_16; break; - case 4: code = BFD_RELOC_32; break; -#ifdef BFD64 - case 8: code = BFD_RELOC_64; break; -#endif - } - } - break; - } - - if ((code == BFD_RELOC_32 - || code == BFD_RELOC_32_PCREL - || code == BFD_RELOC_X86_64_32S) - && GOT_symbol - && fixp->fx_addsy == GOT_symbol) - { - if (!object_64bit) - code = BFD_RELOC_386_GOTPC; - else - code = BFD_RELOC_X86_64_GOTPC32; - } - if ((code == BFD_RELOC_64 || code == BFD_RELOC_64_PCREL) - && GOT_symbol - && fixp->fx_addsy == GOT_symbol) - { - code = BFD_RELOC_X86_64_GOTPC64; - } - - rel = (arelent *) xmalloc (sizeof (arelent)); - rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); - *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); - - rel->address = fixp->fx_frag->fr_address + fixp->fx_where; - - if (!use_rela_relocations) - { - /* HACK: Since i386 ELF uses Rel instead of Rela, encode the - vtable entry to be used in the relocation's section offset. */ - if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) - rel->address = fixp->fx_offset; -#if defined (OBJ_COFF) && defined (TE_PE) - else if (fixp->fx_addsy && S_IS_WEAK (fixp->fx_addsy)) - rel->addend = fixp->fx_addnumber - (S_GET_VALUE (fixp->fx_addsy) * 2); - else -#endif - rel->addend = 0; - } - /* Use the rela in 64bit mode. */ - else - { - if (disallow_64bit_reloc) - switch (code) - { - case BFD_RELOC_X86_64_DTPOFF64: - case BFD_RELOC_X86_64_TPOFF64: - case BFD_RELOC_64_PCREL: - case BFD_RELOC_X86_64_GOTOFF64: - case BFD_RELOC_X86_64_GOT64: - case BFD_RELOC_X86_64_GOTPCREL64: - case BFD_RELOC_X86_64_GOTPC64: - case BFD_RELOC_X86_64_GOTPLT64: - case BFD_RELOC_X86_64_PLTOFF64: - as_bad_where (fixp->fx_file, fixp->fx_line, - _("cannot represent relocation type %s in x32 mode"), - bfd_get_reloc_code_name (code)); - break; - default: - break; - } - - if (!fixp->fx_pcrel) - rel->addend = fixp->fx_offset; - else - switch (code) - { - case BFD_RELOC_X86_64_PLT32: - case BFD_RELOC_X86_64_GOT32: - case BFD_RELOC_X86_64_GOTPCREL: - case BFD_RELOC_X86_64_TLSGD: - case BFD_RELOC_X86_64_TLSLD: - case BFD_RELOC_X86_64_GOTTPOFF: - case BFD_RELOC_X86_64_GOTPC32_TLSDESC: - case BFD_RELOC_X86_64_TLSDESC_CALL: - rel->addend = fixp->fx_offset - fixp->fx_size; - break; - default: - rel->addend = (section->vma - - fixp->fx_size - + fixp->fx_addnumber - + md_pcrel_from (fixp)); - break; - } - } - - rel->howto = bfd_reloc_type_lookup (stdoutput, code); - if (rel->howto == NULL) - { - as_bad_where (fixp->fx_file, fixp->fx_line, - _("cannot represent relocation type %s"), - bfd_get_reloc_code_name (code)); - /* Set howto to a garbage value so that we can keep going. */ - rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32); - gas_assert (rel->howto != NULL); - } - - return rel; -} - -#include "tc-i386-intel.c" - -void -tc_x86_parse_to_dw2regnum (expressionS *exp) -{ - int saved_naked_reg; - char saved_register_dot; - - saved_naked_reg = allow_naked_reg; - allow_naked_reg = 1; - saved_register_dot = register_chars['.']; - register_chars['.'] = '.'; - allow_pseudo_reg = 1; - expression_and_evaluate (exp); - allow_pseudo_reg = 0; - register_chars['.'] = saved_register_dot; - allow_naked_reg = saved_naked_reg; - - if (exp->X_op == O_register && exp->X_add_number >= 0) - { - if ((addressT) exp->X_add_number < i386_regtab_size) - { - exp->X_op = O_constant; - exp->X_add_number = i386_regtab[exp->X_add_number] - .dw2_regnum[flag_code >> 1]; - } - else - exp->X_op = O_illegal; - } -} - -void -tc_x86_frame_initial_instructions (void) -{ - static unsigned int sp_regno[2]; - - if (!sp_regno[flag_code >> 1]) - { - char *saved_input = input_line_pointer; - char sp[][4] = {"esp", "rsp"}; - expressionS exp; - - input_line_pointer = sp[flag_code >> 1]; - tc_x86_parse_to_dw2regnum (&exp); - gas_assert (exp.X_op == O_constant); - sp_regno[flag_code >> 1] = exp.X_add_number; - input_line_pointer = saved_input; - } - - cfi_add_CFA_def_cfa (sp_regno[flag_code >> 1], -x86_cie_data_alignment); - cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment); -} - -int -x86_dwarf2_addr_size (void) -{ -#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) - if (x86_elf_abi == X86_64_X32_ABI) - return 4; -#endif - return bfd_arch_bits_per_address (stdoutput) / 8; -} - -int -i386_elf_section_type (const char *str, size_t len) -{ - if (flag_code == CODE_64BIT - && len == sizeof ("unwind") - 1 - && strncmp (str, "unwind", 6) == 0) - return SHT_X86_64_UNWIND; - - return -1; -} - -#ifdef TE_SOLARIS -void -i386_solaris_fix_up_eh_frame (segT sec) -{ - if (flag_code == CODE_64BIT) - elf_section_type (sec) = SHT_X86_64_UNWIND; -} -#endif - -#ifdef TE_PE -void -tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size) -{ - expressionS exp; - - exp.X_op = O_secrel; - exp.X_add_symbol = symbol; - exp.X_add_number = 0; - emit_expr (&exp, size); -} -#endif - -#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) -/* For ELF on x86-64, add support for SHF_X86_64_LARGE. */ - -bfd_vma -x86_64_section_letter (int letter, char **ptr_msg) -{ - if (flag_code == CODE_64BIT) - { - if (letter == 'l') - return SHF_X86_64_LARGE; - - *ptr_msg = _("bad .section directive: want a,l,w,x,M,S,G,T in string"); - } - else - *ptr_msg = _("bad .section directive: want a,w,x,M,S,G,T in string"); - return -1; -} - -bfd_vma -x86_64_section_word (char *str, size_t len) -{ - if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large")) - return SHF_X86_64_LARGE; - - return -1; -} - -static void -handle_large_common (int small ATTRIBUTE_UNUSED) -{ - if (flag_code != CODE_64BIT) - { - s_comm_internal (0, elf_common_parse); - as_warn (_(".largecomm supported only in 64bit mode, producing .comm")); - } - else - { - static segT lbss_section; - asection *saved_com_section_ptr = elf_com_section_ptr; - asection *saved_bss_section = bss_section; - - if (lbss_section == NULL) - { - flagword applicable; - segT seg = now_seg; - subsegT subseg = now_subseg; - - /* The .lbss section is for local .largecomm symbols. */ - lbss_section = subseg_new (".lbss", 0); - applicable = bfd_applicable_section_flags (stdoutput); - bfd_set_section_flags (stdoutput, lbss_section, - applicable & SEC_ALLOC); - seg_info (lbss_section)->bss = 1; - - subseg_set (seg, subseg); - } - - elf_com_section_ptr = &_bfd_elf_large_com_section; - bss_section = lbss_section; - - s_comm_internal (0, elf_common_parse); - - elf_com_section_ptr = saved_com_section_ptr; - bss_section = saved_bss_section; - } -} -#endif /* OBJ_ELF || OBJ_MAYBE_ELF */ diff --git a/contrib/binutils-2.22/gas/config/tc-i386.h b/contrib/binutils-2.22/gas/config/tc-i386.h deleted file mode 100644 index 6a6b31d648..0000000000 --- a/contrib/binutils-2.22/gas/config/tc-i386.h +++ /dev/null @@ -1,317 +0,0 @@ -/* tc-i386.h -- Header file for tc-i386.c - Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#ifndef TC_I386 -#define TC_I386 1 - -#include "opcodes/i386-opc.h" - -struct fix; - -#define TARGET_BYTES_BIG_ENDIAN 0 - -#define TARGET_ARCH (i386_arch ()) -#define TARGET_MACH (i386_mach ()) -extern enum bfd_architecture i386_arch (void); -extern unsigned long i386_mach (void); - -#ifdef TE_FreeBSD -#define AOUT_TARGET_FORMAT "a.out-i386-freebsd" -#endif -#ifdef TE_NetBSD -#define AOUT_TARGET_FORMAT "a.out-i386-netbsd" -#endif -#ifdef TE_386BSD -#define AOUT_TARGET_FORMAT "a.out-i386-bsd" -#endif -#ifdef TE_LINUX -#define AOUT_TARGET_FORMAT "a.out-i386-linux" -#endif -#ifdef TE_Mach -#define AOUT_TARGET_FORMAT "a.out-mach3" -#endif -#ifdef TE_DYNIX -#define AOUT_TARGET_FORMAT "a.out-i386-dynix" -#endif -#ifndef AOUT_TARGET_FORMAT -#define AOUT_TARGET_FORMAT "a.out-i386" -#endif - -#ifdef TE_FreeBSD -#define ELF_TARGET_FORMAT "elf32-i386-freebsd" -#define ELF_TARGET_FORMAT64 "elf64-x86-64-freebsd" -#elif defined (TE_VXWORKS) -#define ELF_TARGET_FORMAT "elf32-i386-vxworks" -#endif - -#ifdef TE_SOLARIS -#define ELF_TARGET_FORMAT "elf32-i386-sol2" -#define ELF_TARGET_FORMAT64 "elf64-x86-64-sol2" -#endif - -#ifndef ELF_TARGET_FORMAT -#define ELF_TARGET_FORMAT "elf32-i386" -#endif - -#ifndef ELF_TARGET_FORMAT64 -#define ELF_TARGET_FORMAT64 "elf64-x86-64" -#endif - -#ifndef ELF_TARGET_FORMAT32 -#define ELF_TARGET_FORMAT32 "elf32-x86-64" -#endif - -#ifndef ELF_TARGET_L1OM_FORMAT -#define ELF_TARGET_L1OM_FORMAT "elf64-l1om" -#endif - -#ifndef ELF_TARGET_K1OM_FORMAT -#define ELF_TARGET_K1OM_FORMAT "elf64-k1om" -#endif - -#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ - || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ - || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) -extern const char *i386_target_format (void); -#define TARGET_FORMAT i386_target_format () -#else -#ifdef TE_GO32 -#define TARGET_FORMAT "coff-go32" -#endif -#ifdef OBJ_AOUT -#define TARGET_FORMAT AOUT_TARGET_FORMAT -#endif -#endif - -#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)) -#define md_end i386_elf_emit_arch_note -extern void i386_elf_emit_arch_note (void); -#endif - -#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0 - -/* '$' may be used as immediate prefix. */ -#undef LOCAL_LABELS_DOLLAR -#define LOCAL_LABELS_DOLLAR 0 -#undef LOCAL_LABELS_FB -#define LOCAL_LABELS_FB 1 - -extern const char extra_symbol_chars[]; -#define tc_symbol_chars extra_symbol_chars - -extern const char *i386_comment_chars; -#define tc_comment_chars i386_comment_chars - -/* The name of the global offset table generated by the compiler. Allow - this to be overridden if need be. */ -#ifndef GLOBAL_OFFSET_TABLE_NAME -#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" -#endif - -#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT) -#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES) -#endif -extern void x86_cons (expressionS *, int); - -#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP) -extern void x86_cons_fix_new - (fragS *, unsigned int, unsigned int, expressionS *); - -#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */ - -#define NO_RELOC BFD_RELOC_NONE - -void i386_validate_fix (struct fix *); -#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX) - -#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X) -extern int tc_i386_fix_adjustable (struct fix *); - -/* Values passed to md_apply_fix don't include the symbol value. */ -#define MD_APPLY_SYM_VALUE(FIX) 0 - -/* ELF wants external syms kept, as does PE COFF. */ -#if defined (TE_PE) && defined (STRICT_PE_FORMAT) -#define EXTERN_FORCE_RELOC \ - (OUTPUT_FLAVOR == bfd_target_elf_flavour \ - || OUTPUT_FLAVOR == bfd_target_coff_flavour) -#else -#define EXTERN_FORCE_RELOC \ - (OUTPUT_FLAVOR == bfd_target_elf_flavour) -#endif - -/* This expression evaluates to true if the relocation is for a local - object for which we still want to do the relocation at runtime. - False if we are willing to perform this relocation while building - the .o file. GOTOFF and GOT32 do not need to be checked here because - they are not pcrel. .*/ - -#define TC_FORCE_RELOCATION_LOCAL(FIX) \ - (!(FIX)->fx_pcrel \ - || (FIX)->fx_r_type == BFD_RELOC_386_PLT32 \ - || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC \ - || (FIX)->fx_r_type == BFD_RELOC_X86_64_GOTPCREL \ - || TC_FORCE_RELOCATION (FIX)) - -extern int i386_parse_name (char *, expressionS *, char *); -#define md_parse_name(s, e, m, c) i386_parse_name (s, e, c) - -extern operatorT i386_operator (const char *name, unsigned int operands, char *); -#define md_operator i386_operator - -extern int i386_need_index_operator (void); -#define md_need_index_operator i386_need_index_operator - -#define md_register_arithmetic 0 - -extern const struct relax_type md_relax_table[]; -#define TC_GENERIC_RELAX_TABLE md_relax_table - -extern int optimize_align_code; - -#define md_do_align(n, fill, len, max, around) \ -if ((n) \ - && !need_pass_2 \ - && optimize_align_code \ - && (!(fill) \ - || ((char)*(fill) == (char)0x90 && (len) == 1)) \ - && subseg_text_p (now_seg)) \ - { \ - frag_align_code ((n), (max)); \ - goto around; \ - } - -#define MAX_MEM_FOR_RS_ALIGN_CODE 31 - -extern void i386_align_code (fragS *, int); - -#define HANDLE_ALIGN(fragP) \ -if (fragP->fr_type == rs_align_code) \ - i386_align_code (fragP, (fragP->fr_next->fr_address \ - - fragP->fr_address \ - - fragP->fr_fix)); - -void i386_print_statistics (FILE *); -#define tc_print_statistics i386_print_statistics - -#define md_number_to_chars number_to_chars_littleendian - -enum processor_type -{ - PROCESSOR_UNKNOWN, - PROCESSOR_I386, - PROCESSOR_I486, - PROCESSOR_PENTIUM, - PROCESSOR_PENTIUMPRO, - PROCESSOR_PENTIUM4, - PROCESSOR_NOCONA, - PROCESSOR_CORE, - PROCESSOR_CORE2, - PROCESSOR_COREI7, - PROCESSOR_L1OM, - PROCESSOR_K1OM, - PROCESSOR_K6, - PROCESSOR_ATHLON, - PROCESSOR_K8, - PROCESSOR_GENERIC32, - PROCESSOR_GENERIC64, - PROCESSOR_AMDFAM10, - PROCESSOR_BD -}; - -extern enum processor_type cpu_arch_tune; -extern enum processor_type cpu_arch_isa; -extern i386_cpu_flags cpu_arch_isa_flags; - -struct i386_tc_frag_data -{ - enum processor_type isa; - i386_cpu_flags isa_flags; - enum processor_type tune; -}; - -/* We need to emit the right NOP pattern in .align frags. This is - done after the text-to-bits assembly pass, so we need to mark it with - the isa/tune settings at the time the .align was assembled. */ -#define TC_FRAG_TYPE struct i386_tc_frag_data - -#define TC_FRAG_INIT(FRAGP) \ - do \ - { \ - (FRAGP)->tc_frag_data.isa = cpu_arch_isa; \ - (FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags; \ - (FRAGP)->tc_frag_data.tune = cpu_arch_tune; \ - } \ - while (0) - -#ifdef SCO_ELF -#define tc_init_after_args() sco_id () -extern void sco_id (void); -#endif - -#define WORKING_DOT_WORD 1 - -/* We want .cfi_* pseudo-ops for generating unwind info. */ -#define TARGET_USE_CFIPOP 1 - -extern unsigned int x86_dwarf2_return_column; -#define DWARF2_DEFAULT_RETURN_COLUMN x86_dwarf2_return_column - -extern int x86_cie_data_alignment; -#define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment - -extern int x86_dwarf2_addr_size (void); -#define DWARF2_ADDR_SIZE(bfd) x86_dwarf2_addr_size () - -#define tc_parse_to_dw2regnum tc_x86_parse_to_dw2regnum -extern void tc_x86_parse_to_dw2regnum (expressionS *); - -#define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions -extern void tc_x86_frame_initial_instructions (void); - -#define md_elf_section_type(str,len) i386_elf_section_type (str, len) -extern int i386_elf_section_type (const char *, size_t); - -#ifdef TE_SOLARIS -#define md_fix_up_eh_frame(sec) i386_solaris_fix_up_eh_frame (sec) -extern void i386_solaris_fix_up_eh_frame (segT); -#endif - -/* Support for SHF_X86_64_LARGE */ -extern bfd_vma x86_64_section_word (char *, size_t); -extern bfd_vma x86_64_section_letter (int, char **); -#define md_elf_section_letter(LETTER, PTR_MSG) x86_64_section_letter (LETTER, PTR_MSG) -#define md_elf_section_word(STR, LEN) x86_64_section_word (STR, LEN) - -#ifdef TE_PE - -#define O_secrel O_md1 - -#define TC_DWARF2_EMIT_OFFSET tc_pe_dwarf2_emit_offset -void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int); - -#endif /* TE_PE */ - -/* X_add_symbol:X_op_symbol (Intel mode only) */ -#define O_full_ptr O_md2 - -#endif /* TC_I386 */ diff --git a/contrib/binutils-2.22/gas/config/te-dragonfly.h b/contrib/binutils-2.22/gas/config/te-dragonfly.h deleted file mode 100644 index 45da36fee8..0000000000 --- a/contrib/binutils-2.22/gas/config/te-dragonfly.h +++ /dev/null @@ -1,30 +0,0 @@ -/* te-dragonfly.h -- DragonFlyBSD target environment declarations. - Copyright 2011 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Target environment for DragonFlyBSD. It is the same as the generic - target, except that it arranges via the TE_DragonFly define to - suppress the use of "/" as a comment character. Some code in the - DragonFlyBSD kernel uses "/" to mean division. (What a concept!) */ -#define TE_DragonFly 1 - -#define LOCAL_LABELS_DOLLAR 1 -#define LOCAL_LABELS_FB 1 - -#include "obj-format.h" diff --git a/contrib/binutils-2.22/gas/depend.c b/contrib/binutils-2.22/gas/depend.c deleted file mode 100644 index 7a3c54c4e1..0000000000 --- a/contrib/binutils-2.22/gas/depend.c +++ /dev/null @@ -1,208 +0,0 @@ -/* depend.c - Handle dependency tracking. - Copyright 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2007 - Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS 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, or (at your option) - any later version. - - GAS is distributed in the hope that 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 GAS; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ - -#include "as.h" -#include "filenames.h" - -/* The file to write to, or NULL if no dependencies being kept. */ -static char * dep_file = NULL; - -struct dependency - { - char * file; - struct dependency * next; - }; - -/* All the files we depend on. */ -static struct dependency * dep_chain = NULL; - -/* Current column in output file. */ -static int column = 0; - -static int quote_string_for_make (FILE *, char *); -static void wrap_output (FILE *, char *, int); - -/* Number of columns allowable. */ -#define MAX_COLUMNS 72 - -/* Start saving dependencies, to be written to FILENAME. If this is - never called, then dependency tracking is simply skipped. */ - -void -start_dependencies (char *filename) -{ - dep_file = filename; -} - -/* Noticed a new filename, so try to register it. */ - -void -register_dependency (char *filename) -{ - struct dependency *dep; - - if (dep_file == NULL) - return; - - for (dep = dep_chain; dep != NULL; dep = dep->next) - { - if (!filename_cmp (filename, dep->file)) - return; - } - - dep = (struct dependency *) xmalloc (sizeof (struct dependency)); - dep->file = xstrdup (filename); - dep->next = dep_chain; - dep_chain = dep; -} - -/* Quote a file name the way `make' wants it, and print it to FILE. - If FILE is NULL, do no printing, but return the length of the - quoted string. - - This code is taken from gcc with only minor changes. */ - -static int -quote_string_for_make (FILE *file, char *src) -{ - char *p = src; - int i = 0; - - for (;;) - { - char c = *p++; - - switch (c) - { - case '\0': - case ' ': - case '\t': - { - /* GNU make uses a weird quoting scheme for white space. - A space or tab preceded by 2N+1 backslashes represents - N backslashes followed by space; a space or tab - preceded by 2N backslashes represents N backslashes at - the end of a file name; and backslashes in other - contexts should not be doubled. */ - char *q; - - for (q = p - 1; src < q && q[-1] == '\\'; q--) - { - if (file) - putc ('\\', file); - i++; - } - } - if (!c) - return i; - if (file) - putc ('\\', file); - i++; - goto ordinary_char; - - case '$': - if (file) - putc (c, file); - i++; - /* Fall through. This can mishandle things like "$(" but - there's no easy fix. */ - default: - ordinary_char: - /* This can mishandle characters in the string "\0\n%*?[\\~"; - exactly which chars are mishandled depends on the `make' version. - We know of no portable solution for this; - even GNU make 3.76.1 doesn't solve the problem entirely. - (Also, '\0' is mishandled due to our calling conventions.) */ - if (file) - putc (c, file); - i++; - break; - } - } -} - -/* Append some output to the file, keeping track of columns and doing - wrapping as necessary. */ - -static void -wrap_output (FILE *f, char *string, int spacer) -{ - int len = quote_string_for_make (NULL, string); - - if (len == 0) - return; - - if (column - && (MAX_COLUMNS - - 1 /* spacer */ - - 2 /* ` \' */ - < column + len)) - { - fprintf (f, " \\\n "); - column = 0; - if (spacer == ' ') - spacer = '\0'; - } - - if (spacer == ' ') - { - putc (spacer, f); - ++column; - } - - quote_string_for_make (f, string); - column += len; - - if (spacer == ':') - { - putc (spacer, f); - ++column; - } -} - -/* Print dependency file. */ - -void -print_dependencies (void) -{ - FILE *f; - struct dependency *dep; - - if (dep_file == NULL) - return; - - f = fopen (dep_file, FOPEN_WT); - if (f == NULL) - { - as_warn (_("can't open `%s' for writing"), dep_file); - return; - } - - column = 0; - wrap_output (f, out_file_name, ':'); - for (dep = dep_chain; dep != NULL; dep = dep->next) - wrap_output (f, dep->file, ' '); - - putc ('\n', f); - - if (fclose (f)) - as_warn (_("can't close `%s'"), dep_file); -} diff --git a/contrib/binutils-2.22/gas/doc/Makefile.am b/contrib/binutils-2.22/gas/doc/Makefile.am deleted file mode 100644 index 87017fc90e..0000000000 --- a/contrib/binutils-2.22/gas/doc/Makefile.am +++ /dev/null @@ -1,117 +0,0 @@ -## Process this file with automake to generate Makefile.in - -AUTOMAKE_OPTIONS = 1.8 cygnus - -# What version of the manual you want; "all" includes everything -CONFIG=all - -# Options to extract the man page from as.texinfo -MANCONF = -Dman - -TEXI2POD = perl $(BASEDIR)/etc/texi2pod.pl $(AM_MAKEINFOFLAGS) - -POD2MAN = pod2man --center="GNU Development Tools" \ - --release="binutils-$(VERSION)" --section=1 - -man_MANS = as.1 - -info_TEXINFOS = as.texinfo -as_TEXINFOS = asconfig.texi $(CPU_DOCS) - -AM_MAKEINFOFLAGS = -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc -TEXI2DVI = texi2dvi -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -asconfig.texi: $(CONFIG).texi - rm -f asconfig.texi - cp $(srcdir)/$(CONFIG).texi ./asconfig.texi - chmod u+w ./asconfig.texi - -CPU_DOCS = \ - c-alpha.texi \ - c-arc.texi \ - c-arm.texi \ - c-avr.texi \ - c-bfin.texi \ - c-cr16.texi \ - c-d10v.texi \ - c-cris.texi \ - c-h8300.texi \ - c-hppa.texi \ - c-i370.texi \ - c-i386.texi \ - c-i860.texi \ - c-i960.texi \ - c-ip2k.texi \ - c-lm32.texi \ - c-m32c.texi \ - c-m32r.texi \ - c-m68hc11.texi \ - c-m68k.texi \ - c-microblaze.texi \ - c-mips.texi \ - c-mmix.texi \ - c-mt.texi \ - c-msp430.texi \ - c-ns32k.texi \ - c-pdp11.texi \ - c-pj.texi \ - c-ppc.texi \ - c-rx.texi \ - c-s390.texi \ - c-score.texi \ - c-sh.texi \ - c-sh64.texi \ - c-sparc.texi \ - c-tic54x.texi \ - c-tic6x.texi \ - c-tilegx.texi \ - c-tilepro.texi \ - c-vax.texi \ - c-v850.texi \ - c-xstormy16.texi \ - c-xtensa.texi \ - c-z80.texi \ - c-z8k.texi - -# We want install to imply install-info as per GNU standards, despite the -# cygnus option. -install-data-local: install-info - -# This one isn't ready for prime time yet. Not even a little bit. - -noinst_TEXINFOS = internals.texi - -MAINTAINERCLEANFILES = asconfig.texi - -BASEDIR = $(srcdir)/../.. -BFDDIR = $(BASEDIR)/bfd - -CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in - -# Maintenance - -# We need it for the taz target in ../../Makefile.in. -info-local: $(MANS) - -# Build the man page from the texinfo file -# The sed command removes the no-adjust Nroff command so that -# the man output looks standard. -as.1: $(srcdir)/as.texinfo asconfig.texi $(CPU_DOCS) - touch $@ - -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod - -($(POD2MAN) as.pod | \ - sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || \ - (rm -f $@.T$$$$ && exit 1) - rm -f as.pod - -MAINTAINERCLEANFILES += as.info - -# Automake 1.9 will only build info files in the objdir if they are -# mentioned in DISTCLEANFILES. It doesn't have to be unconditional, -# though, so we use a bogus condition. -if GENINSRC_NEVER -DISTCLEANFILES = as.info -endif diff --git a/contrib/binutils-2.22/gas/doc/Makefile.in b/contrib/binutils-2.22/gas/doc/Makefile.in deleted file mode 100644 index d7d0247bf4..0000000000 --- a/contrib/binutils-2.22/gas/doc/Makefile.in +++ /dev/null @@ -1,781 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = doc -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(as_TEXINFOS) -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ - $(top_srcdir)/../config/zlib.m4 \ - $(top_srcdir)/../bfd/warning.m4 \ - $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/gettext-sister.m4 \ - $(top_srcdir)/../config/largefile.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/nls.m4 \ - $(top_srcdir)/../config/override.m4 \ - $(top_srcdir)/../config/plugins.m4 \ - $(top_srcdir)/../config/po.m4 \ - $(top_srcdir)/../config/progtest.m4 \ - $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ - $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ - $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -depcomp = -am__depfiles_maybe = -SOURCES = -INFO_DEPS = as.info -TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex -am__TEXINFO_TEX_DIR = $(top_srcdir)/../texinfo -DVIS = as.dvi -PDFS = as.pdf -PSS = as.ps -HTMLS = as.html -TEXINFOS = as.texinfo -TEXI2PDF = $(TEXI2DVI) --pdf --batch -MAKEINFOHTML = $(MAKEINFO) --html -AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) -DVIPS = dvips -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -man1dir = $(mandir)/man1 -am__installdirs = "$(DESTDIR)$(man1dir)" -NROFF = nroff -MANS = $(man_MANS) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GDBINIT = @GDBINIT@ -GENCAT = @GENCAT@ -GMSGFMT = @GMSGFMT@ -GREP = @GREP@ -INCINTL = @INCINTL@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBINTL = @LIBINTL@ -LIBINTL_DEP = @LIBINTL_DEP@ -LIBM = @LIBM@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -MSGFMT = @MSGFMT@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NO_WERROR = @NO_WERROR@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OPCODES_LIB = @OPCODES_LIB@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -POSUB = @POSUB@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARN_CFLAGS = @WARN_CFLAGS@ -XGETTEXT = @XGETTEXT@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -atof = @atof@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -cgen_cpu_prefix = @cgen_cpu_prefix@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -extra_objects = @extra_objects@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -install_tooldir = @install_tooldir@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -obj_format = @obj_format@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_cpu_type = @target_cpu_type@ -target_os = @target_os@ -target_vendor = @target_vendor@ -te_file = @te_file@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = 1.8 cygnus - -# What version of the manual you want; "all" includes everything -CONFIG = all - -# Options to extract the man page from as.texinfo -MANCONF = -Dman -TEXI2POD = perl $(BASEDIR)/etc/texi2pod.pl $(AM_MAKEINFOFLAGS) -POD2MAN = pod2man --center="GNU Development Tools" \ - --release="binutils-$(VERSION)" --section=1 - -man_MANS = as.1 -info_TEXINFOS = as.texinfo -as_TEXINFOS = asconfig.texi $(CPU_DOCS) -AM_MAKEINFOFLAGS = -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -TEXI2DVI = texi2dvi -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \ - -I "$(top_srcdir)/../bfd/doc" -I ../../bfd/doc - -CPU_DOCS = \ - c-alpha.texi \ - c-arc.texi \ - c-arm.texi \ - c-avr.texi \ - c-bfin.texi \ - c-cr16.texi \ - c-d10v.texi \ - c-cris.texi \ - c-h8300.texi \ - c-hppa.texi \ - c-i370.texi \ - c-i386.texi \ - c-i860.texi \ - c-i960.texi \ - c-ip2k.texi \ - c-lm32.texi \ - c-m32c.texi \ - c-m32r.texi \ - c-m68hc11.texi \ - c-m68k.texi \ - c-microblaze.texi \ - c-mips.texi \ - c-mmix.texi \ - c-mt.texi \ - c-msp430.texi \ - c-ns32k.texi \ - c-pdp11.texi \ - c-pj.texi \ - c-ppc.texi \ - c-rx.texi \ - c-s390.texi \ - c-score.texi \ - c-sh.texi \ - c-sh64.texi \ - c-sparc.texi \ - c-tic54x.texi \ - c-tic6x.texi \ - c-tilegx.texi \ - c-tilepro.texi \ - c-vax.texi \ - c-v850.texi \ - c-xstormy16.texi \ - c-xtensa.texi \ - c-z80.texi \ - c-z8k.texi - - -# This one isn't ready for prime time yet. Not even a little bit. -noinst_TEXINFOS = internals.texi -MAINTAINERCLEANFILES = asconfig.texi as.info -BASEDIR = $(srcdir)/../.. -BFDDIR = $(BASEDIR)/bfd -CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/configure.in - -# Automake 1.9 will only build info files in the objdir if they are -# mentioned in DISTCLEANFILES. It doesn't have to be unconditional, -# though, so we use a bogus condition. -@GENINSRC_NEVER_TRUE@DISTCLEANFILES = as.info -all: all-am - -.SUFFIXES: -.SUFFIXES: .dvi .ps -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign doc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -as.info: as.texinfo $(as_TEXINFOS) - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ - rm -rf $$backupdir && mkdir $$backupdir && \ - if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ - for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ - if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ - done; \ - else :; fi && \ - if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo; \ - then \ - rc=0; \ - else \ - rc=$$?; \ - $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ - fi; \ - rm -rf $$backupdir; exit $$rc - -as.dvi: as.texinfo $(as_TEXINFOS) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) -o $@ `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo - -as.pdf: as.texinfo $(as_TEXINFOS) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) -o $@ `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo - -as.html: as.texinfo $(as_TEXINFOS) - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) `test -f 'as.texinfo' || echo '$(srcdir)/'`as.texinfo; \ - then \ - rm -rf $@; \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ - else \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ - exit 1; \ - fi -.dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< - -uninstall-dvi-am: - @$(NORMAL_UNINSTALL) - @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ - rm -f "$(DESTDIR)$(dvidir)/$$f"; \ - done - -uninstall-html-am: - @$(NORMAL_UNINSTALL) - @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ - rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ - done - -uninstall-info-am: - @$(PRE_UNINSTALL) - @if test -d '$(DESTDIR)$(infodir)' && \ - (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ - if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ - then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ - done; \ - else :; fi - @$(NORMAL_UNINSTALL) - @list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ - (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ - echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ - rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ - else :; fi); \ - done - -uninstall-pdf-am: - @$(NORMAL_UNINSTALL) - @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ - rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ - done - -uninstall-ps-am: - @$(NORMAL_UNINSTALL) - @list='$(PSS)'; test -n "$(psdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ - rm -f "$(DESTDIR)$(psdir)/$$f"; \ - done - -dist-info: $(INFO_DEPS) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; \ - for base in $$list; do \ - case $$base in \ - $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$base; then d=.; else d=$(srcdir); fi; \ - base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ - for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ - if test -f $$file; then \ - relfile=`expr "$$file" : "$$d/\(.*\)"`; \ - test -f "$(distdir)/$$relfile" || \ - cp -p $$file "$(distdir)/$$relfile"; \ - else :; fi; \ - done; \ - done - -mostlyclean-aminfo: - -rm -rf as.aux as.cp as.cps as.fn as.fns as.ky as.log as.pg as.pgs as.tmp \ - as.toc as.tp as.tps as.vr as.vrs - -clean-aminfo: - -test -z "as.dvi as.pdf as.ps as.html" \ - || rm -rf as.dvi as.pdf as.ps as.html - -maintainer-clean-aminfo: - @list='$(INFO_DEPS)'; for i in $$list; do \ - i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ - echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ - rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ - done - -clean-info: mostlyclean-aminfo clean-aminfo -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list=''; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - -check-am: -check: check-am -all-am: Makefile $(MANS) -installdirs: - for dir in "$(DESTDIR)$(man1dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: $(DVIS) - -html: html-am - -html-am: $(HTMLS) - -info: info-am - -info-am: $(INFO_DEPS) info-local - -install-data-am: install-data-local install-man - -install-dvi: install-dvi-am - -install-dvi-am: $(DVIS) - @$(NORMAL_INSTALL) - test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" - @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ - done -install-exec-am: - -install-html: install-html-am - -install-html-am: $(HTMLS) - @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" - @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ - for p in $$list; do \ - if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ - $(am__strip_dir) \ - if test -d "$$d$$p"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ - $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ - else \ - list2="$$list2 $$d$$p"; \ - fi; \ - done; \ - test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ - done; } -install-info: install-info-am - -install-info-am: $(INFO_DEPS) - @$(NORMAL_INSTALL) - test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ - for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$file; then d=.; else d=$(srcdir); fi; \ - file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ - for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ - $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ - if test -f $$ifile; then \ - echo "$$ifile"; \ - else : ; fi; \ - done; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done - @$(POST_INSTALL) - @if (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ - install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ - done; \ - else : ; fi -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: $(PDFS) - @$(NORMAL_INSTALL) - test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" - @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done -install-ps: install-ps-am - -install-ps-am: $(PSS) - @$(NORMAL_INSTALL) - test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" - @list='$(PSS)'; test -n "$(psdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-aminfo \ - maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: $(PDFS) - -ps: ps-am - -ps-am: $(PSS) - -uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ - uninstall-man uninstall-pdf-am uninstall-ps-am - -uninstall-man: uninstall-man1 - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ - clean-info clean-libtool dist-info distclean distclean-generic \ - distclean-libtool dvi dvi-am html html-am info info-am \ - info-local install install-am install-data install-data-am \ - install-data-local install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man1 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ - mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \ - pdf-am ps ps-am uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-man \ - uninstall-man1 uninstall-pdf-am uninstall-ps-am - - -asconfig.texi: $(CONFIG).texi - rm -f asconfig.texi - cp $(srcdir)/$(CONFIG).texi ./asconfig.texi - chmod u+w ./asconfig.texi - -# We want install to imply install-info as per GNU standards, despite the -# cygnus option. -install-data-local: install-info - -# Maintenance - -# We need it for the taz target in ../../Makefile.in. -info-local: $(MANS) - -# Build the man page from the texinfo file -# The sed command removes the no-adjust Nroff command so that -# the man output looks standard. -as.1: $(srcdir)/as.texinfo asconfig.texi $(CPU_DOCS) - touch $@ - -$(TEXI2POD) $(MANCONF) < $(srcdir)/as.texinfo > as.pod - -($(POD2MAN) as.pod | \ - sed -e '/^.if n .na/d' > $@.T$$$$ && \ - mv -f $@.T$$$$ $@) || \ - (rm -f $@.T$$$$ && exit 1) - rm -f as.pod - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/binutils-2.22/gas/doc/as.1 b/contrib/binutils-2.22/gas/doc/as.1 deleted file mode 100644 index 282c5d6558..0000000000 --- a/contrib/binutils-2.22/gas/doc/as.1 +++ /dev/null @@ -1,1786 +0,0 @@ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "AS 1" -.TH AS 1 "2011-11-21" "binutils-2.21.90" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -AS \- the portable GNU assembler. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -as [\fB\-a\fR[\fBcdghlns\fR][=\fIfile\fR]] [\fB\-\-alternate\fR] [\fB\-D\fR] - [\fB\-\-compress\-debug\-sections\fR] [\fB\-\-nocompress\-debug\-sections\fR] - [\fB\-\-debug\-prefix\-map\fR \fIold\fR=\fInew\fR] - [\fB\-\-defsym\fR \fIsym\fR=\fIval\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-\-gstabs\fR] - [\fB\-\-gstabs+\fR] [\fB\-\-gdwarf\-2\fR] [\fB\-\-help\fR] [\fB\-I\fR \fIdir\fR] [\fB\-J\fR] - [\fB\-K\fR] [\fB\-L\fR] [\fB\-\-listing\-lhs\-width\fR=\fI\s-1NUM\s0\fR] - [\fB\-\-listing\-lhs\-width2\fR=\fI\s-1NUM\s0\fR] [\fB\-\-listing\-rhs\-width\fR=\fI\s-1NUM\s0\fR] - [\fB\-\-listing\-cont\-lines\fR=\fI\s-1NUM\s0\fR] [\fB\-\-keep\-locals\fR] [\fB\-o\fR - \fIobjfile\fR] [\fB\-R\fR] [\fB\-\-reduce\-memory\-overheads\fR] [\fB\-\-statistics\fR] - [\fB\-v\fR] [\fB\-version\fR] [\fB\-\-version\fR] [\fB\-W\fR] [\fB\-\-warn\fR] - [\fB\-\-fatal\-warnings\fR] [\fB\-w\fR] [\fB\-x\fR] [\fB\-Z\fR] [\fB@\fR\fI\s-1FILE\s0\fR] - [\fB\-\-size\-check=[error|warning]\fR] - [\fB\-\-target\-help\fR] [\fItarget-options\fR] - [\fB\-\-\fR|\fIfiles\fR ...] -.PP -\&\fITarget Alpha options:\fR - [\fB\-m\fR\fIcpu\fR] - [\fB\-mdebug\fR | \fB\-no\-mdebug\fR] - [\fB\-replace\fR | \fB\-noreplace\fR] - [\fB\-relax\fR] [\fB\-g\fR] [\fB\-G\fR\fIsize\fR] - [\fB\-F\fR] [\fB\-32addr\fR] -.PP -\&\fITarget \s-1ARC\s0 options:\fR - [\fB\-marc[5|6|7|8]\fR] - [\fB\-EB\fR|\fB\-EL\fR] -.PP -\&\fITarget \s-1ARM\s0 options:\fR - [\fB\-mcpu\fR=\fIprocessor\fR[+\fIextension\fR...]] - [\fB\-march\fR=\fIarchitecture\fR[+\fIextension\fR...]] - [\fB\-mfpu\fR=\fIfloating-point-format\fR] - [\fB\-mfloat\-abi\fR=\fIabi\fR] - [\fB\-meabi\fR=\fIver\fR] - [\fB\-mthumb\fR] - [\fB\-EB\fR|\fB\-EL\fR] - [\fB\-mapcs\-32\fR|\fB\-mapcs\-26\fR|\fB\-mapcs\-float\fR| - \fB\-mapcs\-reentrant\fR] - [\fB\-mthumb\-interwork\fR] [\fB\-k\fR] -.PP -\&\fITarget Blackfin options:\fR - [\fB\-mcpu\fR=\fIprocessor\fR[\-\fIsirevision\fR]] - [\fB\-mfdpic\fR] - [\fB\-mno\-fdpic\fR] - [\fB\-mnopic\fR] -.PP -\&\fITarget \s-1CRIS\s0 options:\fR - [\fB\-\-underscore\fR | \fB\-\-no\-underscore\fR] - [\fB\-\-pic\fR] [\fB\-N\fR] - [\fB\-\-emulation=criself\fR | \fB\-\-emulation=crisaout\fR] - [\fB\-\-march=v0_v10\fR | \fB\-\-march=v10\fR | \fB\-\-march=v32\fR | \fB\-\-march=common_v10_v32\fR] -.PP -\&\fITarget D10V options:\fR - [\fB\-O\fR] -.PP -\&\fITarget D30V options:\fR - [\fB\-O\fR|\fB\-n\fR|\fB\-N\fR] -.PP -\&\fITarget H8/300 options:\fR - [\-h\-tick\-hex] -.PP -\&\fITarget i386 options:\fR - [\fB\-\-32\fR|\fB\-\-n32\fR|\fB\-\-64\fR] [\fB\-n\fR] - [\fB\-march\fR=\fI\s-1CPU\s0\fR[+\fI\s-1EXTENSION\s0\fR...]] [\fB\-mtune\fR=\fI\s-1CPU\s0\fR] -.PP -\&\fITarget i960 options:\fR - [\fB\-ACA\fR|\fB\-ACA_A\fR|\fB\-ACB\fR|\fB\-ACC\fR|\fB\-AKA\fR|\fB\-AKB\fR| - \fB\-AKC\fR|\fB\-AMC\fR] - [\fB\-b\fR] [\fB\-no\-relax\fR] -.PP -\&\fITarget \s-1IA\-64\s0 options:\fR - [\fB\-mconstant\-gp\fR|\fB\-mauto\-pic\fR] - [\fB\-milp32\fR|\fB\-milp64\fR|\fB\-mlp64\fR|\fB\-mp64\fR] - [\fB\-mle\fR|\fBmbe\fR] - [\fB\-mtune=itanium1\fR|\fB\-mtune=itanium2\fR] - [\fB\-munwind\-check=warning\fR|\fB\-munwind\-check=error\fR] - [\fB\-mhint.b=ok\fR|\fB\-mhint.b=warning\fR|\fB\-mhint.b=error\fR] - [\fB\-x\fR|\fB\-xexplicit\fR] [\fB\-xauto\fR] [\fB\-xdebug\fR] -.PP -\&\fITarget \s-1IP2K\s0 options:\fR - [\fB\-mip2022\fR|\fB\-mip2022ext\fR] -.PP -\&\fITarget M32C options:\fR - [\fB\-m32c\fR|\fB\-m16c\fR] [\-relax] [\-h\-tick\-hex] -.PP -\&\fITarget M32R options:\fR - [\fB\-\-m32rx\fR|\fB\-\-[no\-]warn\-explicit\-parallel\-conflicts\fR| - \fB\-\-W[n]p\fR] -.PP -\&\fITarget M680X0 options:\fR - [\fB\-l\fR] [\fB\-m68000\fR|\fB\-m68010\fR|\fB\-m68020\fR|...] -.PP -\&\fITarget M68HC11 options:\fR - [\fB\-m68hc11\fR|\fB\-m68hc12\fR|\fB\-m68hcs12\fR] - [\fB\-mshort\fR|\fB\-mlong\fR] - [\fB\-mshort\-double\fR|\fB\-mlong\-double\fR] - [\fB\-\-force\-long\-branches\fR] [\fB\-\-short\-branches\fR] - [\fB\-\-strict\-direct\-mode\fR] [\fB\-\-print\-insn\-syntax\fR] - [\fB\-\-print\-opcodes\fR] [\fB\-\-generate\-example\fR] -.PP -\&\fITarget \s-1MCORE\s0 options:\fR - [\fB\-jsri2bsr\fR] [\fB\-sifilter\fR] [\fB\-relax\fR] - [\fB\-mcpu=[210|340]\fR] -\&\fITarget \s-1MICROBLAZE\s0 options:\fR -.PP -\&\fITarget \s-1MIPS\s0 options:\fR - [\fB\-nocpp\fR] [\fB\-EL\fR] [\fB\-EB\fR] [\fB\-O\fR[\fIoptimization level\fR]] - [\fB\-g\fR[\fIdebug level\fR]] [\fB\-G\fR \fInum\fR] [\fB\-KPIC\fR] [\fB\-call_shared\fR] - [\fB\-non_shared\fR] [\fB\-xgot\fR [\fB\-mvxworks\-pic\fR] - [\fB\-mabi\fR=\fI\s-1ABI\s0\fR] [\fB\-32\fR] [\fB\-n32\fR] [\fB\-64\fR] [\fB\-mfp32\fR] [\fB\-mgp32\fR] - [\fB\-march\fR=\fI\s-1CPU\s0\fR] [\fB\-mtune\fR=\fI\s-1CPU\s0\fR] [\fB\-mips1\fR] [\fB\-mips2\fR] - [\fB\-mips3\fR] [\fB\-mips4\fR] [\fB\-mips5\fR] [\fB\-mips32\fR] [\fB\-mips32r2\fR] - [\fB\-mips64\fR] [\fB\-mips64r2\fR] - [\fB\-construct\-floats\fR] [\fB\-no\-construct\-floats\fR] - [\fB\-trap\fR] [\fB\-no\-break\fR] [\fB\-break\fR] [\fB\-no\-trap\fR] - [\fB\-mips16\fR] [\fB\-no\-mips16\fR] - [\fB\-mmicromips\fR] [\fB\-mno\-micromips\fR] - [\fB\-msmartmips\fR] [\fB\-mno\-smartmips\fR] - [\fB\-mips3d\fR] [\fB\-no\-mips3d\fR] - [\fB\-mdmx\fR] [\fB\-no\-mdmx\fR] - [\fB\-mdsp\fR] [\fB\-mno\-dsp\fR] - [\fB\-mdspr2\fR] [\fB\-mno\-dspr2\fR] - [\fB\-mmt\fR] [\fB\-mno\-mt\fR] - [\fB\-mmcu\fR] [\fB\-mno\-mcu\fR] - [\fB\-mfix7000\fR] [\fB\-mno\-fix7000\fR] - [\fB\-mfix\-vr4120\fR] [\fB\-mno\-fix\-vr4120\fR] - [\fB\-mfix\-vr4130\fR] [\fB\-mno\-fix\-vr4130\fR] - [\fB\-mdebug\fR] [\fB\-no\-mdebug\fR] - [\fB\-mpdr\fR] [\fB\-mno\-pdr\fR] -.PP -\&\fITarget \s-1MMIX\s0 options:\fR - [\fB\-\-fixed\-special\-register\-names\fR] [\fB\-\-globalize\-symbols\fR] - [\fB\-\-gnu\-syntax\fR] [\fB\-\-relax\fR] [\fB\-\-no\-predefined\-symbols\fR] - [\fB\-\-no\-expand\fR] [\fB\-\-no\-merge\-gregs\fR] [\fB\-x\fR] - [\fB\-\-linker\-allocated\-gregs\fR] -.PP -\&\fITarget \s-1PDP11\s0 options:\fR - [\fB\-mpic\fR|\fB\-mno\-pic\fR] [\fB\-mall\fR] [\fB\-mno\-extensions\fR] - [\fB\-m\fR\fIextension\fR|\fB\-mno\-\fR\fIextension\fR] - [\fB\-m\fR\fIcpu\fR] [\fB\-m\fR\fImachine\fR] -.PP -\&\fITarget picoJava options:\fR - [\fB\-mb\fR|\fB\-me\fR] -.PP -\&\fITarget PowerPC options:\fR - [\fB\-a32\fR|\fB\-a64\fR] - [\fB\-mpwrx\fR|\fB\-mpwr2\fR|\fB\-mpwr\fR|\fB\-m601\fR|\fB\-mppc\fR|\fB\-mppc32\fR|\fB\-m603\fR|\fB\-m604\fR|\fB\-m403\fR|\fB\-m405\fR| - \fB\-m440\fR|\fB\-m464\fR|\fB\-m476\fR|\fB\-m7400\fR|\fB\-m7410\fR|\fB\-m7450\fR|\fB\-m7455\fR|\fB\-m750cl\fR|\fB\-mppc64\fR| - \fB\-m620\fR|\fB\-me500\fR|\fB\-e500x2\fR|\fB\-me500mc\fR|\fB\-me500mc64\fR|\fB\-mppc64bridge\fR|\fB\-mbooke\fR| - \fB\-mpower4\fR|\fB\-mpr4\fR|\fB\-mpower5\fR|\fB\-mpwr5\fR|\fB\-mpwr5x\fR|\fB\-mpower6\fR|\fB\-mpwr6\fR| - \fB\-mpower7\fR|\fB\-mpw7\fR|\fB\-ma2\fR|\fB\-mcell\fR|\fB\-mspe\fR|\fB\-mtitan\fR|\fB\-me300\fR|\fB\-mcom\fR] - [\fB\-many\fR] [\fB\-maltivec\fR|\fB\-mvsx\fR] - [\fB\-mregnames\fR|\fB\-mno\-regnames\fR] - [\fB\-mrelocatable\fR|\fB\-mrelocatable\-lib\fR|\fB\-K \s-1PIC\s0\fR] [\fB\-memb\fR] - [\fB\-mlittle\fR|\fB\-mlittle\-endian\fR|\fB\-le\fR|\fB\-mbig\fR|\fB\-mbig\-endian\fR|\fB\-be\fR] - [\fB\-msolaris\fR|\fB\-mno\-solaris\fR] - [\fB\-nops=\fR\fIcount\fR] -.PP -\&\fITarget \s-1RX\s0 options:\fR - [\fB\-mlittle\-endian\fR|\fB\-mbig\-endian\fR] - [\fB\-m32bit\-ints\fR|\fB\-m16bit\-ints\fR] - [\fB\-m32bit\-doubles\fR|\fB\-m64bit\-doubles\fR] -.PP -\&\fITarget s390 options:\fR - [\fB\-m31\fR|\fB\-m64\fR] [\fB\-mesa\fR|\fB\-mzarch\fR] [\fB\-march\fR=\fI\s-1CPU\s0\fR] - [\fB\-mregnames\fR|\fB\-mno\-regnames\fR] - [\fB\-mwarn\-areg\-zero\fR] -.PP -\&\fITarget \s-1SCORE\s0 options:\fR - [\fB\-EB\fR][\fB\-EL\fR][\fB\-FIXDD\fR][\fB\-NWARN\fR] - [\fB\-SCORE5\fR][\fB\-SCORE5U\fR][\fB\-SCORE7\fR][\fB\-SCORE3\fR] - [\fB\-march=score7\fR][\fB\-march=score3\fR] - [\fB\-USE_R1\fR][\fB\-KPIC\fR][\fB\-O0\fR][\fB\-G\fR \fInum\fR][\fB\-V\fR] -.PP -\&\fITarget \s-1SPARC\s0 options:\fR - [\fB\-Av6\fR|\fB\-Av7\fR|\fB\-Av8\fR|\fB\-Asparclet\fR|\fB\-Asparclite\fR - \fB\-Av8plus\fR|\fB\-Av8plusa\fR|\fB\-Av9\fR|\fB\-Av9a\fR] - [\fB\-xarch=v8plus\fR|\fB\-xarch=v8plusa\fR] [\fB\-bump\fR] - [\fB\-32\fR|\fB\-64\fR] -.PP -\&\fITarget \s-1TIC54X\s0 options:\fR - [\fB\-mcpu=54[123589]\fR|\fB\-mcpu=54[56]lp\fR] [\fB\-mfar\-mode\fR|\fB\-mf\fR] - [\fB\-merrors\-to\-file\fR \fI\fR|\fB\-me\fR \fI\fR] -.PP -\&\fITarget \s-1TIC6X\s0 options:\fR - [\fB\-march=\fR\fIarch\fR] [\fB\-mbig\-endian\fR|\fB\-mlittle\-endian\fR] - [\fB\-mdsbt\fR|\fB\-mno\-dsbt\fR] [\fB\-mpid=no\fR|\fB\-mpid=near\fR|\fB\-mpid=far\fR] - [\fB\-mpic\fR|\fB\-mno\-pic\fR] -.PP -\&\fITarget TILE-Gx options:\fR - [\fB\-m32\fR|\fB\-m64\fR] -.PP -\&\fITarget Xtensa options:\fR - [\fB\-\-[no\-]text\-section\-literals\fR] [\fB\-\-[no\-]absolute\-literals\fR] - [\fB\-\-[no\-]target\-align\fR] [\fB\-\-[no\-]longcalls\fR] - [\fB\-\-[no\-]transform\fR] - [\fB\-\-rename\-section\fR \fIoldname\fR=\fInewname\fR] -.PP -\&\fITarget Z80 options:\fR - [\fB\-z80\fR] [\fB\-r800\fR] - [ \fB\-ignore\-undocumented\-instructions\fR] [\fB\-Wnud\fR] - [ \fB\-ignore\-unportable\-instructions\fR] [\fB\-Wnup\fR] - [ \fB\-warn\-undocumented\-instructions\fR] [\fB\-Wud\fR] - [ \fB\-warn\-unportable\-instructions\fR] [\fB\-Wup\fR] - [ \fB\-forbid\-undocumented\-instructions\fR] [\fB\-Fud\fR] - [ \fB\-forbid\-unportable\-instructions\fR] [\fB\-Fup\fR] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\s-1GNU\s0 \fBas\fR is really a family of assemblers. -If you use (or have used) the \s-1GNU\s0 assembler on one architecture, you -should find a fairly similar environment when you use it on another -architecture. Each version has much in common with the others, -including object file formats, most assembler directives (often called -\&\fIpseudo-ops\fR) and assembler syntax. -.PP -\&\fBas\fR is primarily intended to assemble the output of the -\&\s-1GNU\s0 C compiler \f(CW\*(C`gcc\*(C'\fR for use by the linker -\&\f(CW\*(C`ld\*(C'\fR. Nevertheless, we've tried to make \fBas\fR -assemble correctly everything that other assemblers for the same -machine would assemble. -Any exceptions are documented explicitly. -This doesn't mean \fBas\fR always uses the same syntax as another -assembler for the same architecture; for example, we know of several -incompatible versions of 680x0 assembly language syntax. -.PP -Each time you run \fBas\fR it assembles exactly one source -program. The source program is made up of one or more files. -(The standard input is also a file.) -.PP -You give \fBas\fR a command line that has zero or more input file -names. The input files are read (from left file name to right). A -command line argument (in any position) that has no special meaning -is taken to be an input file name. -.PP -If you give \fBas\fR no file names it attempts to read one input file -from the \fBas\fR standard input, which is normally your terminal. You -may have to type \fBctl-D\fR to tell \fBas\fR there is no more program -to assemble. -.PP -Use \fB\-\-\fR if you need to explicitly name the standard input file -in your command line. -.PP -If the source is empty, \fBas\fR produces a small, empty object -file. -.PP -\&\fBas\fR may write warnings and error messages to the standard error -file (usually your terminal). This should not happen when a compiler -runs \fBas\fR automatically. Warnings report an assumption made so -that \fBas\fR could keep assembling a flawed program; errors report a -grave problem that stops the assembly. -.PP -If you are invoking \fBas\fR via the \s-1GNU\s0 C compiler, -you can use the \fB\-Wa\fR option to pass arguments through to the assembler. -The assembler arguments must be separated from each other (and the \fB\-Wa\fR) -by commas. For example: -.PP -.Vb 1 -\& gcc \-c \-g \-O \-Wa,\-alh,\-L file.c -.Ve -.PP -This passes two options to the assembler: \fB\-alh\fR (emit a listing to -standard output with high-level and assembly source) and \fB\-L\fR (retain -local symbols in the symbol table). -.PP -Usually you do not need to use this \fB\-Wa\fR mechanism, since many compiler -command-line options are automatically passed to the assembler by the compiler. -(You can call the \s-1GNU\s0 compiler driver with the \fB\-v\fR option to see -precisely what options it passes to each compilation pass, including the -assembler.) -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.IP "\fB\-a[cdghlmns]\fR" 4 -.IX Item "-a[cdghlmns]" -Turn on listings, in any of a variety of ways: -.RS 4 -.IP "\fB\-ac\fR" 4 -.IX Item "-ac" -omit false conditionals -.IP "\fB\-ad\fR" 4 -.IX Item "-ad" -omit debugging directives -.IP "\fB\-ag\fR" 4 -.IX Item "-ag" -include general information, like as version and options passed -.IP "\fB\-ah\fR" 4 -.IX Item "-ah" -include high-level source -.IP "\fB\-al\fR" 4 -.IX Item "-al" -include assembly -.IP "\fB\-am\fR" 4 -.IX Item "-am" -include macro expansions -.IP "\fB\-an\fR" 4 -.IX Item "-an" -omit forms processing -.IP "\fB\-as\fR" 4 -.IX Item "-as" -include symbols -.IP "\fB=file\fR" 4 -.IX Item "=file" -set the name of the listing file -.RE -.RS 4 -.Sp -You may combine these options; for example, use \fB\-aln\fR for assembly -listing without forms processing. The \fB=file\fR option, if used, must be -the last one. By itself, \fB\-a\fR defaults to \fB\-ahls\fR. -.RE -.IP "\fB\-\-alternate\fR" 4 -.IX Item "--alternate" -Begin in alternate macro mode. -.IP "\fB\-\-compress\-debug\-sections\fR" 4 -.IX Item "--compress-debug-sections" -Compress \s-1DWARF\s0 debug sections using zlib. The debug sections are renamed -to begin with \fB.zdebug\fR, and the resulting object file may not be -compatible with older linkers and object file utilities. -.IP "\fB\-\-nocompress\-debug\-sections\fR" 4 -.IX Item "--nocompress-debug-sections" -Do not compress \s-1DWARF\s0 debug sections. This is the default. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -Ignored. This option is accepted for script compatibility with calls to -other assemblers. -.IP "\fB\-\-debug\-prefix\-map\fR \fIold\fR\fB=\fR\fInew\fR" 4 -.IX Item "--debug-prefix-map old=new" -When assembling files in directory \fI\fIold\fI\fR, record debugging -information describing them as in \fI\fInew\fI\fR instead. -.IP "\fB\-\-defsym\fR \fIsym\fR\fB=\fR\fIvalue\fR" 4 -.IX Item "--defsym sym=value" -Define the symbol \fIsym\fR to be \fIvalue\fR before assembling the input file. -\&\fIvalue\fR must be an integer constant. As in C, a leading \fB0x\fR -indicates a hexadecimal value, and a leading \fB0\fR indicates an octal -value. The value of the symbol can be overridden inside a source file via the -use of a \f(CW\*(C`.set\*(C'\fR pseudo-op. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -\&\*(L"fast\*(R"\-\-\-skip whitespace and comment preprocessing (assume source is -compiler output). -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-gen\-debug\fR" 4 -.IX Item "--gen-debug" -.PD -Generate debugging information for each assembler source line using whichever -debug format is preferred by the target. This currently means either \s-1STABS\s0, -\&\s-1ECOFF\s0 or \s-1DWARF2\s0. -.IP "\fB\-\-gstabs\fR" 4 -.IX Item "--gstabs" -Generate stabs debugging information for each assembler line. This -may help debugging assembler code, if the debugger can handle it. -.IP "\fB\-\-gstabs+\fR" 4 -.IX Item "--gstabs+" -Generate stabs debugging information for each assembler line, with \s-1GNU\s0 -extensions that probably only gdb can handle, and that could make other -debuggers crash or refuse to read your program. This -may help debugging assembler code. Currently the only \s-1GNU\s0 extension is -the location of the current working directory at assembling time. -.IP "\fB\-\-gdwarf\-2\fR" 4 -.IX Item "--gdwarf-2" -Generate \s-1DWARF2\s0 debugging information for each assembler line. This -may help debugging assembler code, if the debugger can handle it. Note\-\-\-this -option is only supported by some targets, not all of them. -.IP "\fB\-\-size\-check=error\fR" 4 -.IX Item "--size-check=error" -.PD 0 -.IP "\fB\-\-size\-check=warning\fR" 4 -.IX Item "--size-check=warning" -.PD -Issue an error or warning for invalid \s-1ELF\s0 .size directive. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Print a summary of the command line options and exit. -.IP "\fB\-\-target\-help\fR" 4 -.IX Item "--target-help" -Print a summary of all target specific options and exit. -.IP "\fB\-I\fR \fIdir\fR" 4 -.IX Item "-I dir" -Add directory \fIdir\fR to the search list for \f(CW\*(C`.include\*(C'\fR directives. -.IP "\fB\-J\fR" 4 -.IX Item "-J" -Don't warn about signed overflow. -.IP "\fB\-K\fR" 4 -.IX Item "-K" -Issue warnings when difference tables altered for long displacements. -.IP "\fB\-L\fR" 4 -.IX Item "-L" -.PD 0 -.IP "\fB\-\-keep\-locals\fR" 4 -.IX Item "--keep-locals" -.PD -Keep (in the symbol table) local symbols. These symbols start with -system-specific local label prefixes, typically \fB.L\fR for \s-1ELF\s0 systems -or \fBL\fR for traditional a.out systems. -.IP "\fB\-\-listing\-lhs\-width=\fR\fInumber\fR" 4 -.IX Item "--listing-lhs-width=number" -Set the maximum width, in words, of the output data column for an assembler -listing to \fInumber\fR. -.IP "\fB\-\-listing\-lhs\-width2=\fR\fInumber\fR" 4 -.IX Item "--listing-lhs-width2=number" -Set the maximum width, in words, of the output data column for continuation -lines in an assembler listing to \fInumber\fR. -.IP "\fB\-\-listing\-rhs\-width=\fR\fInumber\fR" 4 -.IX Item "--listing-rhs-width=number" -Set the maximum width of an input source line, as displayed in a listing, to -\&\fInumber\fR bytes. -.IP "\fB\-\-listing\-cont\-lines=\fR\fInumber\fR" 4 -.IX Item "--listing-cont-lines=number" -Set the maximum number of lines printed in a listing for a single line of input -to \fInumber\fR + 1. -.IP "\fB\-o\fR \fIobjfile\fR" 4 -.IX Item "-o objfile" -Name the object-file output from \fBas\fR \fIobjfile\fR. -.IP "\fB\-R\fR" 4 -.IX Item "-R" -Fold the data section into the text section. -.Sp -Set the default size of \s-1GAS\s0's hash tables to a prime number close to -\&\fInumber\fR. Increasing this value can reduce the length of time it takes the -assembler to perform its tasks, at the expense of increasing the assembler's -memory requirements. Similarly reducing this value can reduce the memory -requirements at the expense of speed. -.IP "\fB\-\-reduce\-memory\-overheads\fR" 4 -.IX Item "--reduce-memory-overheads" -This option reduces \s-1GAS\s0's memory requirements, at the expense of making the -assembly processes slower. Currently this switch is a synonym for -\&\fB\-\-hash\-size=4051\fR, but in the future it may have other effects as well. -.IP "\fB\-\-statistics\fR" 4 -.IX Item "--statistics" -Print the maximum space (in bytes) and total time (in seconds) used by -assembly. -.IP "\fB\-\-strip\-local\-absolute\fR" 4 -.IX Item "--strip-local-absolute" -Remove local absolute symbols from the outgoing symbol table. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-version\fR" 4 -.IX Item "-version" -.PD -Print the \fBas\fR version. -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -Print the \fBas\fR version and exit. -.IP "\fB\-W\fR" 4 -.IX Item "-W" -.PD 0 -.IP "\fB\-\-no\-warn\fR" 4 -.IX Item "--no-warn" -.PD -Suppress warning messages. -.IP "\fB\-\-fatal\-warnings\fR" 4 -.IX Item "--fatal-warnings" -Treat warnings as errors. -.IP "\fB\-\-warn\fR" 4 -.IX Item "--warn" -Don't suppress warning messages or treat them as errors. -.IP "\fB\-w\fR" 4 -.IX Item "-w" -Ignored. -.IP "\fB\-x\fR" 4 -.IX Item "-x" -Ignored. -.IP "\fB\-Z\fR" 4 -.IX Item "-Z" -Generate an object file even after errors. -.IP "\fB\-\- |\fR \fIfiles\fR \fB...\fR" 4 -.IX Item "-- | files ..." -Standard input, or source files to assemble. -.PP -The following options are available when as is configured for an Alpha -processor. -.IP "\fB\-m\fR\fIcpu\fR" 4 -.IX Item "-mcpu" -This option specifies the target processor. If an attempt is made to -assemble an instruction which will not execute on the target processor, -the assembler may either expand the instruction as a macro or issue an -error message. This option is equivalent to the \f(CW\*(C`.arch\*(C'\fR directive. -.Sp -The following processor names are recognized: -\&\f(CW21064\fR, -\&\f(CW\*(C`21064a\*(C'\fR, -\&\f(CW21066\fR, -\&\f(CW21068\fR, -\&\f(CW21164\fR, -\&\f(CW\*(C`21164a\*(C'\fR, -\&\f(CW\*(C`21164pc\*(C'\fR, -\&\f(CW21264\fR, -\&\f(CW\*(C`21264a\*(C'\fR, -\&\f(CW\*(C`21264b\*(C'\fR, -\&\f(CW\*(C`ev4\*(C'\fR, -\&\f(CW\*(C`ev5\*(C'\fR, -\&\f(CW\*(C`lca45\*(C'\fR, -\&\f(CW\*(C`ev5\*(C'\fR, -\&\f(CW\*(C`ev56\*(C'\fR, -\&\f(CW\*(C`pca56\*(C'\fR, -\&\f(CW\*(C`ev6\*(C'\fR, -\&\f(CW\*(C`ev67\*(C'\fR, -\&\f(CW\*(C`ev68\*(C'\fR. -The special name \f(CW\*(C`all\*(C'\fR may be used to allow the assembler to accept -instructions valid for any Alpha processor. -.Sp -In order to support existing practice in \s-1OSF/1\s0 with respect to \f(CW\*(C`.arch\*(C'\fR, -and existing practice within \fB\s-1MILO\s0\fR (the Linux \s-1ARC\s0 bootloader), the -numbered processor names (e.g. 21064) enable the processor-specific PALcode -instructions, while the \*(L"electro-vlasic\*(R" names (e.g. \f(CW\*(C`ev4\*(C'\fR) do not. -.IP "\fB\-mdebug\fR" 4 -.IX Item "-mdebug" -.PD 0 -.IP "\fB\-no\-mdebug\fR" 4 -.IX Item "-no-mdebug" -.PD -Enables or disables the generation of \f(CW\*(C`.mdebug\*(C'\fR encapsulation for -stabs directives and procedure descriptors. The default is to automatically -enable \f(CW\*(C`.mdebug\*(C'\fR when the first stabs directive is seen. -.IP "\fB\-relax\fR" 4 -.IX Item "-relax" -This option forces all relocations to be put into the object file, instead -of saving space and resolving some relocations at assembly time. Note that -this option does not propagate all symbol arithmetic into the object file, -because not all symbol arithmetic can be represented. However, the option -can still be useful in specific applications. -.IP "\fB\-replace\fR" 4 -.IX Item "-replace" -.PD 0 -.IP "\fB\-noreplace\fR" 4 -.IX Item "-noreplace" -.PD -Enables or disables the optimization of procedure calls, both at assemblage -and at link time. These options are only available for \s-1VMS\s0 targets and -\&\f(CW\*(C`\-replace\*(C'\fR is the default. See section 1.4.1 of the OpenVMS Linker -Utility Manual. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -This option is used when the compiler generates debug information. When -\&\fBgcc\fR is using \fBmips-tfile\fR to generate debug -information for \s-1ECOFF\s0, local labels must be passed through to the object -file. Otherwise this option has no effect. -.IP "\fB\-G\fR\fIsize\fR" 4 -.IX Item "-Gsize" -A local common symbol larger than \fIsize\fR is placed in \f(CW\*(C`.bss\*(C'\fR, -while smaller symbols are placed in \f(CW\*(C`.sbss\*(C'\fR. -.IP "\fB\-F\fR" 4 -.IX Item "-F" -.PD 0 -.IP "\fB\-32addr\fR" 4 -.IX Item "-32addr" -.PD -These options are ignored for backward compatibility. -.PP -The following options are available when as is configured for -an \s-1ARC\s0 processor. -.IP "\fB\-marc[5|6|7|8]\fR" 4 -.IX Item "-marc[5|6|7|8]" -This option selects the core processor variant. -.IP "\fB\-EB | \-EL\fR" 4 -.IX Item "-EB | -EL" -Select either big-endian (\-EB) or little-endian (\-EL) output. -.PP -The following options are available when as is configured for the \s-1ARM\s0 -processor family. -.IP "\fB\-mcpu=\fR\fIprocessor\fR\fB[+\fR\fIextension\fR\fB...]\fR" 4 -.IX Item "-mcpu=processor[+extension...]" -Specify which \s-1ARM\s0 processor variant is the target. -.IP "\fB\-march=\fR\fIarchitecture\fR\fB[+\fR\fIextension\fR\fB...]\fR" 4 -.IX Item "-march=architecture[+extension...]" -Specify which \s-1ARM\s0 architecture variant is used by the target. -.IP "\fB\-mfpu=\fR\fIfloating-point-format\fR" 4 -.IX Item "-mfpu=floating-point-format" -Select which Floating Point architecture is the target. -.IP "\fB\-mfloat\-abi=\fR\fIabi\fR" 4 -.IX Item "-mfloat-abi=abi" -Select which floating point \s-1ABI\s0 is in use. -.IP "\fB\-mthumb\fR" 4 -.IX Item "-mthumb" -Enable Thumb only instruction decoding. -.IP "\fB\-mapcs\-32 | \-mapcs\-26 | \-mapcs\-float | \-mapcs\-reentrant\fR" 4 -.IX Item "-mapcs-32 | -mapcs-26 | -mapcs-float | -mapcs-reentrant" -Select which procedure calling convention is in use. -.IP "\fB\-EB | \-EL\fR" 4 -.IX Item "-EB | -EL" -Select either big-endian (\-EB) or little-endian (\-EL) output. -.IP "\fB\-mthumb\-interwork\fR" 4 -.IX Item "-mthumb-interwork" -Specify that the code has been generated with interworking between Thumb and -\&\s-1ARM\s0 code in mind. -.IP "\fB\-k\fR" 4 -.IX Item "-k" -Specify that \s-1PIC\s0 code has been generated. -.PP -The following options are available when as is configured for -the Blackfin processor family. -.IP "\fB\-mcpu=\fR\fIprocessor\fR[\fB\-\fR\fIsirevision\fR]" 4 -.IX Item "-mcpu=processor[-sirevision]" -This option specifies the target processor. The optional \fIsirevision\fR -is not used in assembler. It's here such that \s-1GCC\s0 can easily pass down its -\&\f(CW\*(C`\-mcpu=\*(C'\fR option. The assembler will issue an -error message if an attempt is made to assemble an instruction which -will not execute on the target processor. The following processor names are -recognized: -\&\f(CW\*(C`bf504\*(C'\fR, -\&\f(CW\*(C`bf506\*(C'\fR, -\&\f(CW\*(C`bf512\*(C'\fR, -\&\f(CW\*(C`bf514\*(C'\fR, -\&\f(CW\*(C`bf516\*(C'\fR, -\&\f(CW\*(C`bf518\*(C'\fR, -\&\f(CW\*(C`bf522\*(C'\fR, -\&\f(CW\*(C`bf523\*(C'\fR, -\&\f(CW\*(C`bf524\*(C'\fR, -\&\f(CW\*(C`bf525\*(C'\fR, -\&\f(CW\*(C`bf526\*(C'\fR, -\&\f(CW\*(C`bf527\*(C'\fR, -\&\f(CW\*(C`bf531\*(C'\fR, -\&\f(CW\*(C`bf532\*(C'\fR, -\&\f(CW\*(C`bf533\*(C'\fR, -\&\f(CW\*(C`bf534\*(C'\fR, -\&\f(CW\*(C`bf535\*(C'\fR (not implemented yet), -\&\f(CW\*(C`bf536\*(C'\fR, -\&\f(CW\*(C`bf537\*(C'\fR, -\&\f(CW\*(C`bf538\*(C'\fR, -\&\f(CW\*(C`bf539\*(C'\fR, -\&\f(CW\*(C`bf542\*(C'\fR, -\&\f(CW\*(C`bf542m\*(C'\fR, -\&\f(CW\*(C`bf544\*(C'\fR, -\&\f(CW\*(C`bf544m\*(C'\fR, -\&\f(CW\*(C`bf547\*(C'\fR, -\&\f(CW\*(C`bf547m\*(C'\fR, -\&\f(CW\*(C`bf548\*(C'\fR, -\&\f(CW\*(C`bf548m\*(C'\fR, -\&\f(CW\*(C`bf549\*(C'\fR, -\&\f(CW\*(C`bf549m\*(C'\fR, -\&\f(CW\*(C`bf561\*(C'\fR, -and -\&\f(CW\*(C`bf592\*(C'\fR. -.IP "\fB\-mfdpic\fR" 4 -.IX Item "-mfdpic" -Assemble for the \s-1FDPIC\s0 \s-1ABI\s0. -.IP "\fB\-mno\-fdpic\fR" 4 -.IX Item "-mno-fdpic" -.PD 0 -.IP "\fB\-mnopic\fR" 4 -.IX Item "-mnopic" -.PD -Disable \-mfdpic. -.PP -See the info pages for documentation of the CRIS-specific options. -.PP -The following options are available when as is configured for -a D10V processor. -.IP "\fB\-O\fR" 4 -.IX Item "-O" -Optimize output by parallelizing instructions. -.PP -The following options are available when as is configured for a D30V -processor. -.IP "\fB\-O\fR" 4 -.IX Item "-O" -Optimize output by parallelizing instructions. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -Warn when nops are generated. -.IP "\fB\-N\fR" 4 -.IX Item "-N" -Warn when a nop after a 32\-bit multiply instruction is generated. -.PP -The following options are available when as is configured for -an i386 processor. -.IP "\fB\-\-32 | \-\-x32 | \-\-64\fR" 4 -.IX Item "--32 | --x32 | --64" -Select the word size, either 32 bits or 64 bits. \fB\-\-32\fR -implies Intel i386 architecture, while \fB\-\-x32\fR and \fB\-\-64\fR -imply \s-1AMD\s0 x86\-64 architecture with 32\-bit or 64\-bit word-size -respectively. -.Sp -These options are only available with the \s-1ELF\s0 object file format, and -require that the necessary \s-1BFD\s0 support has been included (on a 32\-bit -platform you have to add \-\-enable\-64\-bit\-bfd to configure enable 64\-bit -usage and use x86\-64 as target platform). -.IP "\fB\-n\fR" 4 -.IX Item "-n" -By default, x86 \s-1GAS\s0 replaces multiple nop instructions used for -alignment within code sections with multi-byte nop instructions such -as leal 0(%esi,1),%esi. This switch disables the optimization. -.IP "\fB\-\-divide\fR" 4 -.IX Item "--divide" -On SVR4\-derived platforms, the character \fB/\fR is treated as a comment -character, which means that it cannot be used in expressions. The -\&\fB\-\-divide\fR option turns \fB/\fR into a normal character. This does -not disable \fB/\fR at the beginning of a line starting a comment, or -affect using \fB#\fR for starting a comment. -.IP "\fB\-march=\fR\fI\s-1CPU\s0\fR\fB[+\fR\fI\s-1EXTENSION\s0\fR\fB...]\fR" 4 -.IX Item "-march=CPU[+EXTENSION...]" -This option specifies the target processor. The assembler will -issue an error message if an attempt is made to assemble an instruction -which will not execute on the target processor. The following -processor names are recognized: -\&\f(CW\*(C`i8086\*(C'\fR, -\&\f(CW\*(C`i186\*(C'\fR, -\&\f(CW\*(C`i286\*(C'\fR, -\&\f(CW\*(C`i386\*(C'\fR, -\&\f(CW\*(C`i486\*(C'\fR, -\&\f(CW\*(C`i586\*(C'\fR, -\&\f(CW\*(C`i686\*(C'\fR, -\&\f(CW\*(C`pentium\*(C'\fR, -\&\f(CW\*(C`pentiumpro\*(C'\fR, -\&\f(CW\*(C`pentiumii\*(C'\fR, -\&\f(CW\*(C`pentiumiii\*(C'\fR, -\&\f(CW\*(C`pentium4\*(C'\fR, -\&\f(CW\*(C`prescott\*(C'\fR, -\&\f(CW\*(C`nocona\*(C'\fR, -\&\f(CW\*(C`core\*(C'\fR, -\&\f(CW\*(C`core2\*(C'\fR, -\&\f(CW\*(C`corei7\*(C'\fR, -\&\f(CW\*(C`l1om\*(C'\fR, -\&\f(CW\*(C`k1om\*(C'\fR, -\&\f(CW\*(C`k6\*(C'\fR, -\&\f(CW\*(C`k6_2\*(C'\fR, -\&\f(CW\*(C`athlon\*(C'\fR, -\&\f(CW\*(C`opteron\*(C'\fR, -\&\f(CW\*(C`k8\*(C'\fR, -\&\f(CW\*(C`amdfam10\*(C'\fR, -\&\f(CW\*(C`bdver1\*(C'\fR, -\&\f(CW\*(C`bdver2\*(C'\fR, -\&\f(CW\*(C`generic32\*(C'\fR and -\&\f(CW\*(C`generic64\*(C'\fR. -.Sp -In addition to the basic instruction set, the assembler can be told to -accept various extension mnemonics. For example, -\&\f(CW\*(C`\-march=i686+sse4+vmx\*(C'\fR extends \fIi686\fR with \fIsse4\fR and -\&\fIvmx\fR. The following extensions are currently supported: -\&\f(CW8087\fR, -\&\f(CW287\fR, -\&\f(CW387\fR, -\&\f(CW\*(C`no87\*(C'\fR, -\&\f(CW\*(C`mmx\*(C'\fR, -\&\f(CW\*(C`nommx\*(C'\fR, -\&\f(CW\*(C`sse\*(C'\fR, -\&\f(CW\*(C`sse2\*(C'\fR, -\&\f(CW\*(C`sse3\*(C'\fR, -\&\f(CW\*(C`ssse3\*(C'\fR, -\&\f(CW\*(C`sse4.1\*(C'\fR, -\&\f(CW\*(C`sse4.2\*(C'\fR, -\&\f(CW\*(C`sse4\*(C'\fR, -\&\f(CW\*(C`nosse\*(C'\fR, -\&\f(CW\*(C`avx\*(C'\fR, -\&\f(CW\*(C`avx2\*(C'\fR, -\&\f(CW\*(C`noavx\*(C'\fR, -\&\f(CW\*(C`vmx\*(C'\fR, -\&\f(CW\*(C`smx\*(C'\fR, -\&\f(CW\*(C`xsave\*(C'\fR, -\&\f(CW\*(C`xsaveopt\*(C'\fR, -\&\f(CW\*(C`aes\*(C'\fR, -\&\f(CW\*(C`pclmul\*(C'\fR, -\&\f(CW\*(C`fsgsbase\*(C'\fR, -\&\f(CW\*(C`rdrnd\*(C'\fR, -\&\f(CW\*(C`f16c\*(C'\fR, -\&\f(CW\*(C`bmi2\*(C'\fR, -\&\f(CW\*(C`fma\*(C'\fR, -\&\f(CW\*(C`movbe\*(C'\fR, -\&\f(CW\*(C`ept\*(C'\fR, -\&\f(CW\*(C`lzcnt\*(C'\fR, -\&\f(CW\*(C`invpcid\*(C'\fR, -\&\f(CW\*(C`clflush\*(C'\fR, -\&\f(CW\*(C`lwp\*(C'\fR, -\&\f(CW\*(C`fma4\*(C'\fR, -\&\f(CW\*(C`xop\*(C'\fR, -\&\f(CW\*(C`syscall\*(C'\fR, -\&\f(CW\*(C`rdtscp\*(C'\fR, -\&\f(CW\*(C`3dnow\*(C'\fR, -\&\f(CW\*(C`3dnowa\*(C'\fR, -\&\f(CW\*(C`sse4a\*(C'\fR, -\&\f(CW\*(C`sse5\*(C'\fR, -\&\f(CW\*(C`svme\*(C'\fR, -\&\f(CW\*(C`abm\*(C'\fR and -\&\f(CW\*(C`padlock\*(C'\fR. -Note that rather than extending a basic instruction set, the extension -mnemonics starting with \f(CW\*(C`no\*(C'\fR revoke the respective functionality. -.Sp -When the \f(CW\*(C`.arch\*(C'\fR directive is used with \fB\-march\fR, the -\&\f(CW\*(C`.arch\*(C'\fR directive will take precedent. -.IP "\fB\-mtune=\fR\fI\s-1CPU\s0\fR" 4 -.IX Item "-mtune=CPU" -This option specifies a processor to optimize for. When used in -conjunction with the \fB\-march\fR option, only instructions -of the processor specified by the \fB\-march\fR option will be -generated. -.Sp -Valid \fI\s-1CPU\s0\fR values are identical to the processor list of -\&\fB\-march=\fR\fI\s-1CPU\s0\fR. -.IP "\fB\-msse2avx\fR" 4 -.IX Item "-msse2avx" -This option specifies that the assembler should encode \s-1SSE\s0 instructions -with \s-1VEX\s0 prefix. -.IP "\fB\-msse\-check=\fR\fInone\fR" 4 -.IX Item "-msse-check=none" -.PD 0 -.IP "\fB\-msse\-check=\fR\fIwarning\fR" 4 -.IX Item "-msse-check=warning" -.IP "\fB\-msse\-check=\fR\fIerror\fR" 4 -.IX Item "-msse-check=error" -.PD -These options control if the assembler should check \s-1SSE\s0 intructions. -\&\fB\-msse\-check=\fR\fInone\fR will make the assembler not to check \s-1SSE\s0 -instructions, which is the default. \fB\-msse\-check=\fR\fIwarning\fR -will make the assembler issue a warning for any \s-1SSE\s0 intruction. -\&\fB\-msse\-check=\fR\fIerror\fR will make the assembler issue an error -for any \s-1SSE\s0 intruction. -.IP "\fB\-mavxscalar=\fR\fI128\fR" 4 -.IX Item "-mavxscalar=128" -.PD 0 -.IP "\fB\-mavxscalar=\fR\fI256\fR" 4 -.IX Item "-mavxscalar=256" -.PD -These options control how the assembler should encode scalar \s-1AVX\s0 -instructions. \fB\-mavxscalar=\fR\fI128\fR will encode scalar -\&\s-1AVX\s0 instructions with 128bit vector length, which is the default. -\&\fB\-mavxscalar=\fR\fI256\fR will encode scalar \s-1AVX\s0 instructions -with 256bit vector length. -.IP "\fB\-mmnemonic=\fR\fIatt\fR" 4 -.IX Item "-mmnemonic=att" -.PD 0 -.IP "\fB\-mmnemonic=\fR\fIintel\fR" 4 -.IX Item "-mmnemonic=intel" -.PD -This option specifies instruction mnemonic for matching instructions. -The \f(CW\*(C`.att_mnemonic\*(C'\fR and \f(CW\*(C`.intel_mnemonic\*(C'\fR directives will -take precedent. -.IP "\fB\-msyntax=\fR\fIatt\fR" 4 -.IX Item "-msyntax=att" -.PD 0 -.IP "\fB\-msyntax=\fR\fIintel\fR" 4 -.IX Item "-msyntax=intel" -.PD -This option specifies instruction syntax when processing instructions. -The \f(CW\*(C`.att_syntax\*(C'\fR and \f(CW\*(C`.intel_syntax\*(C'\fR directives will -take precedent. -.IP "\fB\-mnaked\-reg\fR" 4 -.IX Item "-mnaked-reg" -This opetion specifies that registers don't require a \fB%\fR prefix. -The \f(CW\*(C`.att_syntax\*(C'\fR and \f(CW\*(C`.intel_syntax\*(C'\fR directives will take precedent. -.PP -The following options are available when as is configured for the -Intel 80960 processor. -.IP "\fB\-ACA | \-ACA_A | \-ACB | \-ACC | \-AKA | \-AKB | \-AKC | \-AMC\fR" 4 -.IX Item "-ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC" -Specify which variant of the 960 architecture is the target. -.IP "\fB\-b\fR" 4 -.IX Item "-b" -Add code to collect statistics about branches taken. -.IP "\fB\-no\-relax\fR" 4 -.IX Item "-no-relax" -Do not alter compare-and-branch instructions for long displacements; -error if necessary. -.PP -The following options are available when as is configured for the -Ubicom \s-1IP2K\s0 series. -.IP "\fB\-mip2022ext\fR" 4 -.IX Item "-mip2022ext" -Specifies that the extended \s-1IP2022\s0 instructions are allowed. -.IP "\fB\-mip2022\fR" 4 -.IX Item "-mip2022" -Restores the default behaviour, which restricts the permitted instructions to -just the basic \s-1IP2022\s0 ones. -.PP -The following options are available when as is configured for the -Renesas M32C and M16C processors. -.IP "\fB\-m32c\fR" 4 -.IX Item "-m32c" -Assemble M32C instructions. -.IP "\fB\-m16c\fR" 4 -.IX Item "-m16c" -Assemble M16C instructions (the default). -.IP "\fB\-relax\fR" 4 -.IX Item "-relax" -Enable support for link-time relaxations. -.IP "\fB\-h\-tick\-hex\fR" 4 -.IX Item "-h-tick-hex" -Support H'00 style hex constants in addition to 0x00 style. -.PP -The following options are available when as is configured for the -Renesas M32R (formerly Mitsubishi M32R) series. -.IP "\fB\-\-m32rx\fR" 4 -.IX Item "--m32rx" -Specify which processor in the M32R family is the target. The default -is normally the M32R, but this option changes it to the M32RX. -.IP "\fB\-\-warn\-explicit\-parallel\-conflicts or \-\-Wp\fR" 4 -.IX Item "--warn-explicit-parallel-conflicts or --Wp" -Produce warning messages when questionable parallel constructs are -encountered. -.IP "\fB\-\-no\-warn\-explicit\-parallel\-conflicts or \-\-Wnp\fR" 4 -.IX Item "--no-warn-explicit-parallel-conflicts or --Wnp" -Do not produce warning messages when questionable parallel constructs are -encountered. -.PP -The following options are available when as is configured for the -Motorola 68000 series. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -Shorten references to undefined symbols, to one word instead of two. -.IP "\fB\-m68000 | \-m68008 | \-m68010 | \-m68020 | \-m68030\fR" 4 -.IX Item "-m68000 | -m68008 | -m68010 | -m68020 | -m68030" -.PD 0 -.IP "\fB| \-m68040 | \-m68060 | \-m68302 | \-m68331 | \-m68332\fR" 4 -.IX Item "| -m68040 | -m68060 | -m68302 | -m68331 | -m68332" -.IP "\fB| \-m68333 | \-m68340 | \-mcpu32 | \-m5200\fR" 4 -.IX Item "| -m68333 | -m68340 | -mcpu32 | -m5200" -.PD -Specify what processor in the 68000 family is the target. The default -is normally the 68020, but this can be changed at configuration time. -.IP "\fB\-m68881 | \-m68882 | \-mno\-68881 | \-mno\-68882\fR" 4 -.IX Item "-m68881 | -m68882 | -mno-68881 | -mno-68882" -The target machine does (or does not) have a floating-point coprocessor. -The default is to assume a coprocessor for 68020, 68030, and cpu32. Although -the basic 68000 is not compatible with the 68881, a combination of the -two can be specified, since it's possible to do emulation of the -coprocessor instructions with the main processor. -.IP "\fB\-m68851 | \-mno\-68851\fR" 4 -.IX Item "-m68851 | -mno-68851" -The target machine does (or does not) have a memory-management -unit coprocessor. The default is to assume an \s-1MMU\s0 for 68020 and up. -.PP -For details about the \s-1PDP\-11\s0 machine dependent features options, -see \fBPDP\-11\-Options\fR. -.IP "\fB\-mpic | \-mno\-pic\fR" 4 -.IX Item "-mpic | -mno-pic" -Generate position-independent (or position-dependent) code. The -default is \fB\-mpic\fR. -.IP "\fB\-mall\fR" 4 -.IX Item "-mall" -.PD 0 -.IP "\fB\-mall\-extensions\fR" 4 -.IX Item "-mall-extensions" -.PD -Enable all instruction set extensions. This is the default. -.IP "\fB\-mno\-extensions\fR" 4 -.IX Item "-mno-extensions" -Disable all instruction set extensions. -.IP "\fB\-m\fR\fIextension\fR \fB| \-mno\-\fR\fIextension\fR" 4 -.IX Item "-mextension | -mno-extension" -Enable (or disable) a particular instruction set extension. -.IP "\fB\-m\fR\fIcpu\fR" 4 -.IX Item "-mcpu" -Enable the instruction set extensions supported by a particular \s-1CPU\s0, and -disable all other extensions. -.IP "\fB\-m\fR\fImachine\fR" 4 -.IX Item "-mmachine" -Enable the instruction set extensions supported by a particular machine -model, and disable all other extensions. -.PP -The following options are available when as is configured for -a picoJava processor. -.IP "\fB\-mb\fR" 4 -.IX Item "-mb" -Generate \*(L"big endian\*(R" format output. -.IP "\fB\-ml\fR" 4 -.IX Item "-ml" -Generate \*(L"little endian\*(R" format output. -.PP -The following options are available when as is configured for the -Motorola 68HC11 or 68HC12 series. -.IP "\fB\-m68hc11 | \-m68hc12 | \-m68hcs12\fR" 4 -.IX Item "-m68hc11 | -m68hc12 | -m68hcs12" -Specify what processor is the target. The default is -defined by the configuration option when building the assembler. -.IP "\fB\-mshort\fR" 4 -.IX Item "-mshort" -Specify to use the 16\-bit integer \s-1ABI\s0. -.IP "\fB\-mlong\fR" 4 -.IX Item "-mlong" -Specify to use the 32\-bit integer \s-1ABI\s0. -.IP "\fB\-mshort\-double\fR" 4 -.IX Item "-mshort-double" -Specify to use the 32\-bit double \s-1ABI\s0. -.IP "\fB\-mlong\-double\fR" 4 -.IX Item "-mlong-double" -Specify to use the 64\-bit double \s-1ABI\s0. -.IP "\fB\-\-force\-long\-branches\fR" 4 -.IX Item "--force-long-branches" -Relative branches are turned into absolute ones. This concerns -conditional branches, unconditional branches and branches to a -sub routine. -.IP "\fB\-S | \-\-short\-branches\fR" 4 -.IX Item "-S | --short-branches" -Do not turn relative branches into absolute ones -when the offset is out of range. -.IP "\fB\-\-strict\-direct\-mode\fR" 4 -.IX Item "--strict-direct-mode" -Do not turn the direct addressing mode into extended addressing mode -when the instruction does not support direct addressing mode. -.IP "\fB\-\-print\-insn\-syntax\fR" 4 -.IX Item "--print-insn-syntax" -Print the syntax of instruction in case of error. -.IP "\fB\-\-print\-opcodes\fR" 4 -.IX Item "--print-opcodes" -print the list of instructions with syntax and then exit. -.IP "\fB\-\-generate\-example\fR" 4 -.IX Item "--generate-example" -print an example of instruction for each possible instruction and then exit. -This option is only useful for testing \fBas\fR. -.PP -The following options are available when \fBas\fR is configured -for the \s-1SPARC\s0 architecture: -.IP "\fB\-Av6 | \-Av7 | \-Av8 | \-Asparclet | \-Asparclite\fR" 4 -.IX Item "-Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite" -.PD 0 -.IP "\fB\-Av8plus | \-Av8plusa | \-Av9 | \-Av9a\fR" 4 -.IX Item "-Av8plus | -Av8plusa | -Av9 | -Av9a" -.PD -Explicitly select a variant of the \s-1SPARC\s0 architecture. -.Sp -\&\fB\-Av8plus\fR and \fB\-Av8plusa\fR select a 32 bit environment. -\&\fB\-Av9\fR and \fB\-Av9a\fR select a 64 bit environment. -.Sp -\&\fB\-Av8plusa\fR and \fB\-Av9a\fR enable the \s-1SPARC\s0 V9 instruction set with -UltraSPARC extensions. -.IP "\fB\-xarch=v8plus | \-xarch=v8plusa\fR" 4 -.IX Item "-xarch=v8plus | -xarch=v8plusa" -For compatibility with the Solaris v9 assembler. These options are -equivalent to \-Av8plus and \-Av8plusa, respectively. -.IP "\fB\-bump\fR" 4 -.IX Item "-bump" -Warn when the assembler switches to another architecture. -.PP -The following options are available when as is configured for the 'c54x -architecture. -.IP "\fB\-mfar\-mode\fR" 4 -.IX Item "-mfar-mode" -Enable extended addressing mode. All addresses and relocations will assume -extended addressing (usually 23 bits). -.IP "\fB\-mcpu=\fR\fI\s-1CPU_VERSION\s0\fR" 4 -.IX Item "-mcpu=CPU_VERSION" -Sets the \s-1CPU\s0 version being compiled for. -.IP "\fB\-merrors\-to\-file\fR \fI\s-1FILENAME\s0\fR" 4 -.IX Item "-merrors-to-file FILENAME" -Redirect error output to a file, for broken systems which don't support such -behaviour in the shell. -.PP -The following options are available when as is configured for -a \s-1MIPS\s0 processor. -.IP "\fB\-G\fR \fInum\fR" 4 -.IX Item "-G num" -This option sets the largest size of an object that can be referenced -implicitly with the \f(CW\*(C`gp\*(C'\fR register. It is only accepted for targets that -use \s-1ECOFF\s0 format, such as a DECstation running Ultrix. The default value is 8. -.IP "\fB\-EB\fR" 4 -.IX Item "-EB" -Generate \*(L"big endian\*(R" format output. -.IP "\fB\-EL\fR" 4 -.IX Item "-EL" -Generate \*(L"little endian\*(R" format output. -.IP "\fB\-mips1\fR" 4 -.IX Item "-mips1" -.PD 0 -.IP "\fB\-mips2\fR" 4 -.IX Item "-mips2" -.IP "\fB\-mips3\fR" 4 -.IX Item "-mips3" -.IP "\fB\-mips4\fR" 4 -.IX Item "-mips4" -.IP "\fB\-mips5\fR" 4 -.IX Item "-mips5" -.IP "\fB\-mips32\fR" 4 -.IX Item "-mips32" -.IP "\fB\-mips32r2\fR" 4 -.IX Item "-mips32r2" -.IP "\fB\-mips64\fR" 4 -.IX Item "-mips64" -.IP "\fB\-mips64r2\fR" 4 -.IX Item "-mips64r2" -.PD -Generate code for a particular \s-1MIPS\s0 Instruction Set Architecture level. -\&\fB\-mips1\fR is an alias for \fB\-march=r3000\fR, \fB\-mips2\fR is an -alias for \fB\-march=r6000\fR, \fB\-mips3\fR is an alias for -\&\fB\-march=r4000\fR and \fB\-mips4\fR is an alias for \fB\-march=r8000\fR. -\&\fB\-mips5\fR, \fB\-mips32\fR, \fB\-mips32r2\fR, \fB\-mips64\fR, and -\&\fB\-mips64r2\fR -correspond to generic -\&\fB\s-1MIPS\s0 V\fR, \fB\s-1MIPS32\s0\fR, \fB\s-1MIPS32\s0 Release 2\fR, \fB\s-1MIPS64\s0\fR, -and \fB\s-1MIPS64\s0 Release 2\fR -\&\s-1ISA\s0 processors, respectively. -.IP "\fB\-march=\fR\fI\s-1CPU\s0\fR" 4 -.IX Item "-march=CPU" -Generate code for a particular \s-1MIPS\s0 cpu. -.IP "\fB\-mtune=\fR\fIcpu\fR" 4 -.IX Item "-mtune=cpu" -Schedule and tune for a particular \s-1MIPS\s0 cpu. -.IP "\fB\-mfix7000\fR" 4 -.IX Item "-mfix7000" -.PD 0 -.IP "\fB\-mno\-fix7000\fR" 4 -.IX Item "-mno-fix7000" -.PD -Cause nops to be inserted if the read of the destination register -of an mfhi or mflo instruction occurs in the following two instructions. -.IP "\fB\-mdebug\fR" 4 -.IX Item "-mdebug" -.PD 0 -.IP "\fB\-no\-mdebug\fR" 4 -.IX Item "-no-mdebug" -.PD -Cause stabs-style debugging output to go into an ECOFF-style .mdebug -section instead of the standard \s-1ELF\s0 .stabs sections. -.IP "\fB\-mpdr\fR" 4 -.IX Item "-mpdr" -.PD 0 -.IP "\fB\-mno\-pdr\fR" 4 -.IX Item "-mno-pdr" -.PD -Control generation of \f(CW\*(C`.pdr\*(C'\fR sections. -.IP "\fB\-mgp32\fR" 4 -.IX Item "-mgp32" -.PD 0 -.IP "\fB\-mfp32\fR" 4 -.IX Item "-mfp32" -.PD -The register sizes are normally inferred from the \s-1ISA\s0 and \s-1ABI\s0, but these -flags force a certain group of registers to be treated as 32 bits wide at -all times. \fB\-mgp32\fR controls the size of general-purpose registers -and \fB\-mfp32\fR controls the size of floating-point registers. -.IP "\fB\-mips16\fR" 4 -.IX Item "-mips16" -.PD 0 -.IP "\fB\-no\-mips16\fR" 4 -.IX Item "-no-mips16" -.PD -Generate code for the \s-1MIPS\s0 16 processor. This is equivalent to putting -\&\f(CW\*(C`.set mips16\*(C'\fR at the start of the assembly file. \fB\-no\-mips16\fR -turns off this option. -.IP "\fB\-mmicromips\fR" 4 -.IX Item "-mmicromips" -.PD 0 -.IP "\fB\-mno\-micromips\fR" 4 -.IX Item "-mno-micromips" -.PD -Generate code for the microMIPS processor. This is equivalent to putting -\&\f(CW\*(C`.set micromips\*(C'\fR at the start of the assembly file. \fB\-mno\-micromips\fR -turns off this option. This is equivalent to putting \f(CW\*(C`.set nomicromips\*(C'\fR -at the start of the assembly file. -.IP "\fB\-msmartmips\fR" 4 -.IX Item "-msmartmips" -.PD 0 -.IP "\fB\-mno\-smartmips\fR" 4 -.IX Item "-mno-smartmips" -.PD -Enables the SmartMIPS extension to the \s-1MIPS32\s0 instruction set. This is -equivalent to putting \f(CW\*(C`.set smartmips\*(C'\fR at the start of the assembly file. -\&\fB\-mno\-smartmips\fR turns off this option. -.IP "\fB\-mips3d\fR" 4 -.IX Item "-mips3d" -.PD 0 -.IP "\fB\-no\-mips3d\fR" 4 -.IX Item "-no-mips3d" -.PD -Generate code for the \s-1MIPS\-3D\s0 Application Specific Extension. -This tells the assembler to accept \s-1MIPS\-3D\s0 instructions. -\&\fB\-no\-mips3d\fR turns off this option. -.IP "\fB\-mdmx\fR" 4 -.IX Item "-mdmx" -.PD 0 -.IP "\fB\-no\-mdmx\fR" 4 -.IX Item "-no-mdmx" -.PD -Generate code for the \s-1MDMX\s0 Application Specific Extension. -This tells the assembler to accept \s-1MDMX\s0 instructions. -\&\fB\-no\-mdmx\fR turns off this option. -.IP "\fB\-mdsp\fR" 4 -.IX Item "-mdsp" -.PD 0 -.IP "\fB\-mno\-dsp\fR" 4 -.IX Item "-mno-dsp" -.PD -Generate code for the \s-1DSP\s0 Release 1 Application Specific Extension. -This tells the assembler to accept \s-1DSP\s0 Release 1 instructions. -\&\fB\-mno\-dsp\fR turns off this option. -.IP "\fB\-mdspr2\fR" 4 -.IX Item "-mdspr2" -.PD 0 -.IP "\fB\-mno\-dspr2\fR" 4 -.IX Item "-mno-dspr2" -.PD -Generate code for the \s-1DSP\s0 Release 2 Application Specific Extension. -This option implies \-mdsp. -This tells the assembler to accept \s-1DSP\s0 Release 2 instructions. -\&\fB\-mno\-dspr2\fR turns off this option. -.IP "\fB\-mmt\fR" 4 -.IX Item "-mmt" -.PD 0 -.IP "\fB\-mno\-mt\fR" 4 -.IX Item "-mno-mt" -.PD -Generate code for the \s-1MT\s0 Application Specific Extension. -This tells the assembler to accept \s-1MT\s0 instructions. -\&\fB\-mno\-mt\fR turns off this option. -.IP "\fB\-mmcu\fR" 4 -.IX Item "-mmcu" -.PD 0 -.IP "\fB\-mno\-mcu\fR" 4 -.IX Item "-mno-mcu" -.PD -Generate code for the \s-1MCU\s0 Application Specific Extension. -This tells the assembler to accept \s-1MCU\s0 instructions. -\&\fB\-mno\-mcu\fR turns off this option. -.IP "\fB\-\-construct\-floats\fR" 4 -.IX Item "--construct-floats" -.PD 0 -.IP "\fB\-\-no\-construct\-floats\fR" 4 -.IX Item "--no-construct-floats" -.PD -The \fB\-\-no\-construct\-floats\fR option disables the construction of -double width floating point constants by loading the two halves of the -value into the two single width floating point registers that make up -the double width register. By default \fB\-\-construct\-floats\fR is -selected, allowing construction of these floating point constants. -.IP "\fB\-\-emulation=\fR\fIname\fR" 4 -.IX Item "--emulation=name" -This option causes \fBas\fR to emulate \fBas\fR configured -for some other target, in all respects, including output format (choosing -between \s-1ELF\s0 and \s-1ECOFF\s0 only), handling of pseudo-opcodes which may generate -debugging information or store symbol table information, and default -endianness. The available configuration names are: \fBmipsecoff\fR, -\&\fBmipself\fR, \fBmipslecoff\fR, \fBmipsbecoff\fR, \fBmipslelf\fR, -\&\fBmipsbelf\fR. The first two do not alter the default endianness from that -of the primary target for which the assembler was configured; the others change -the default to little\- or big-endian as indicated by the \fBb\fR or \fBl\fR -in the name. Using \fB\-EB\fR or \fB\-EL\fR will override the endianness -selection in any case. -.Sp -This option is currently supported only when the primary target -\&\fBas\fR is configured for is a \s-1MIPS\s0 \s-1ELF\s0 or \s-1ECOFF\s0 target. -Furthermore, the primary target or others specified with -\&\fB\-\-enable\-targets=...\fR at configuration time must include support for -the other format, if both are to be available. For example, the Irix 5 -configuration includes support for both. -.Sp -Eventually, this option will support more configurations, with more -fine-grained control over the assembler's behavior, and will be supported for -more processors. -.IP "\fB\-nocpp\fR" 4 -.IX Item "-nocpp" -\&\fBas\fR ignores this option. It is accepted for compatibility with -the native tools. -.IP "\fB\-\-trap\fR" 4 -.IX Item "--trap" -.PD 0 -.IP "\fB\-\-no\-trap\fR" 4 -.IX Item "--no-trap" -.IP "\fB\-\-break\fR" 4 -.IX Item "--break" -.IP "\fB\-\-no\-break\fR" 4 -.IX Item "--no-break" -.PD -Control how to deal with multiplication overflow and division by zero. -\&\fB\-\-trap\fR or \fB\-\-no\-break\fR (which are synonyms) take a trap exception -(and only work for Instruction Set Architecture level 2 and higher); -\&\fB\-\-break\fR or \fB\-\-no\-trap\fR (also synonyms, and the default) take a -break exception. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -When this option is used, \fBas\fR will issue a warning every -time it generates a nop instruction from a macro. -.PP -The following options are available when as is configured for -an MCore processor. -.IP "\fB\-jsri2bsr\fR" 4 -.IX Item "-jsri2bsr" -.PD 0 -.IP "\fB\-nojsri2bsr\fR" 4 -.IX Item "-nojsri2bsr" -.PD -Enable or disable the \s-1JSRI\s0 to \s-1BSR\s0 transformation. By default this is enabled. -The command line option \fB\-nojsri2bsr\fR can be used to disable it. -.IP "\fB\-sifilter\fR" 4 -.IX Item "-sifilter" -.PD 0 -.IP "\fB\-nosifilter\fR" 4 -.IX Item "-nosifilter" -.PD -Enable or disable the silicon filter behaviour. By default this is disabled. -The default can be overridden by the \fB\-sifilter\fR command line option. -.IP "\fB\-relax\fR" 4 -.IX Item "-relax" -Alter jump instructions for long displacements. -.IP "\fB\-mcpu=[210|340]\fR" 4 -.IX Item "-mcpu=[210|340]" -Select the cpu type on the target hardware. This controls which instructions -can be assembled. -.IP "\fB\-EB\fR" 4 -.IX Item "-EB" -Assemble for a big endian target. -.IP "\fB\-EL\fR" 4 -.IX Item "-EL" -Assemble for a little endian target. -.PP -See the info pages for documentation of the MMIX-specific options. -.PP -The following options are available when as is configured for a -PowerPC processor. -.IP "\fB\-a32\fR" 4 -.IX Item "-a32" -Generate \s-1ELF32\s0 or \s-1XCOFF32\s0. -.IP "\fB\-a64\fR" 4 -.IX Item "-a64" -Generate \s-1ELF64\s0 or \s-1XCOFF64\s0. -.IP "\fB\-K \s-1PIC\s0\fR" 4 -.IX Item "-K PIC" -Set \s-1EF_PPC_RELOCATABLE_LIB\s0 in \s-1ELF\s0 flags. -.IP "\fB\-mpwrx | \-mpwr2\fR" 4 -.IX Item "-mpwrx | -mpwr2" -Generate code for \s-1POWER/2\s0 (\s-1RIOS2\s0). -.IP "\fB\-mpwr\fR" 4 -.IX Item "-mpwr" -Generate code for \s-1POWER\s0 (\s-1RIOS1\s0) -.IP "\fB\-m601\fR" 4 -.IX Item "-m601" -Generate code for PowerPC 601. -.IP "\fB\-mppc, \-mppc32, \-m603, \-m604\fR" 4 -.IX Item "-mppc, -mppc32, -m603, -m604" -Generate code for PowerPC 603/604. -.IP "\fB\-m403, \-m405\fR" 4 -.IX Item "-m403, -m405" -Generate code for PowerPC 403/405. -.IP "\fB\-m440\fR" 4 -.IX Item "-m440" -Generate code for PowerPC 440. BookE and some 405 instructions. -.IP "\fB\-m464\fR" 4 -.IX Item "-m464" -Generate code for PowerPC 464. -.IP "\fB\-m476\fR" 4 -.IX Item "-m476" -Generate code for PowerPC 476. -.IP "\fB\-m7400, \-m7410, \-m7450, \-m7455\fR" 4 -.IX Item "-m7400, -m7410, -m7450, -m7455" -Generate code for PowerPC 7400/7410/7450/7455. -.IP "\fB\-m750cl\fR" 4 -.IX Item "-m750cl" -Generate code for PowerPC 750CL. -.IP "\fB\-mppc64, \-m620\fR" 4 -.IX Item "-mppc64, -m620" -Generate code for PowerPC 620/625/630. -.IP "\fB\-me500, \-me500x2\fR" 4 -.IX Item "-me500, -me500x2" -Generate code for Motorola e500 core complex. -.IP "\fB\-me500mc\fR" 4 -.IX Item "-me500mc" -Generate code for Freescale e500mc core complex. -.IP "\fB\-me500mc64\fR" 4 -.IX Item "-me500mc64" -Generate code for Freescale e500mc64 core complex. -.IP "\fB\-mspe\fR" 4 -.IX Item "-mspe" -Generate code for Motorola \s-1SPE\s0 instructions. -.IP "\fB\-mtitan\fR" 4 -.IX Item "-mtitan" -Generate code for AppliedMicro Titan core complex. -.IP "\fB\-mppc64bridge\fR" 4 -.IX Item "-mppc64bridge" -Generate code for PowerPC 64, including bridge insns. -.IP "\fB\-mbooke\fR" 4 -.IX Item "-mbooke" -Generate code for 32\-bit BookE. -.IP "\fB\-ma2\fR" 4 -.IX Item "-ma2" -Generate code for A2 architecture. -.IP "\fB\-me300\fR" 4 -.IX Item "-me300" -Generate code for PowerPC e300 family. -.IP "\fB\-maltivec\fR" 4 -.IX Item "-maltivec" -Generate code for processors with AltiVec instructions. -.IP "\fB\-mvsx\fR" 4 -.IX Item "-mvsx" -Generate code for processors with Vector-Scalar (\s-1VSX\s0) instructions. -.IP "\fB\-mpower4, \-mpwr4\fR" 4 -.IX Item "-mpower4, -mpwr4" -Generate code for Power4 architecture. -.IP "\fB\-mpower5, \-mpwr5, \-mpwr5x\fR" 4 -.IX Item "-mpower5, -mpwr5, -mpwr5x" -Generate code for Power5 architecture. -.IP "\fB\-mpower6, \-mpwr6\fR" 4 -.IX Item "-mpower6, -mpwr6" -Generate code for Power6 architecture. -.IP "\fB\-mpower7, \-mpwr7\fR" 4 -.IX Item "-mpower7, -mpwr7" -Generate code for Power7 architecture. -.IP "\fB\-mcell\fR" 4 -.IX Item "-mcell" -Generate code for Cell Broadband Engine architecture. -.IP "\fB\-mcom\fR" 4 -.IX Item "-mcom" -Generate code Power/PowerPC common instructions. -.IP "\fB\-many\fR" 4 -.IX Item "-many" -Generate code for any architecture (\s-1PWR/PWRX/PPC\s0). -.IP "\fB\-mregnames\fR" 4 -.IX Item "-mregnames" -Allow symbolic names for registers. -.IP "\fB\-mno\-regnames\fR" 4 -.IX Item "-mno-regnames" -Do not allow symbolic names for registers. -.IP "\fB\-mrelocatable\fR" 4 -.IX Item "-mrelocatable" -Support for \s-1GCC\s0's \-mrelocatable option. -.IP "\fB\-mrelocatable\-lib\fR" 4 -.IX Item "-mrelocatable-lib" -Support for \s-1GCC\s0's \-mrelocatable\-lib option. -.IP "\fB\-memb\fR" 4 -.IX Item "-memb" -Set \s-1PPC_EMB\s0 bit in \s-1ELF\s0 flags. -.IP "\fB\-mlittle, \-mlittle\-endian, \-le\fR" 4 -.IX Item "-mlittle, -mlittle-endian, -le" -Generate code for a little endian machine. -.IP "\fB\-mbig, \-mbig\-endian, \-be\fR" 4 -.IX Item "-mbig, -mbig-endian, -be" -Generate code for a big endian machine. -.IP "\fB\-msolaris\fR" 4 -.IX Item "-msolaris" -Generate code for Solaris. -.IP "\fB\-mno\-solaris\fR" 4 -.IX Item "-mno-solaris" -Do not generate code for Solaris. -.IP "\fB\-nops=\fR\fIcount\fR" 4 -.IX Item "-nops=count" -If an alignment directive inserts more than \fIcount\fR nops, put a -branch at the beginning to skip execution of the nops. -.PP -See the info pages for documentation of the RX-specific options. -.PP -The following options are available when as is configured for the s390 -processor family. -.IP "\fB\-m31\fR" 4 -.IX Item "-m31" -.PD 0 -.IP "\fB\-m64\fR" 4 -.IX Item "-m64" -.PD -Select the word size, either 31/32 bits or 64 bits. -.IP "\fB\-mesa\fR" 4 -.IX Item "-mesa" -.PD 0 -.IP "\fB\-mzarch\fR" 4 -.IX Item "-mzarch" -.PD -Select the architecture mode, either the Enterprise System -Architecture (esa) or the z/Architecture mode (zarch). -.IP "\fB\-march=\fR\fIprocessor\fR" 4 -.IX Item "-march=processor" -Specify which s390 processor variant is the target, \fBg6\fR, \fBg6\fR, -\&\fBz900\fR, \fBz990\fR, \fBz9\-109\fR, \fBz9\-ec\fR, or \fBz10\fR. -.IP "\fB\-mregnames\fR" 4 -.IX Item "-mregnames" -.PD 0 -.IP "\fB\-mno\-regnames\fR" 4 -.IX Item "-mno-regnames" -.PD -Allow or disallow symbolic names for registers. -.IP "\fB\-mwarn\-areg\-zero\fR" 4 -.IX Item "-mwarn-areg-zero" -Warn whenever the operand for a base or index register has been specified -but evaluates to zero. -.PP -The following options are available when as is configured for a -\&\s-1TMS320C6000\s0 processor. -.IP "\fB\-march=\fR\fIarch\fR" 4 -.IX Item "-march=arch" -Enable (only) instructions from architecture \fIarch\fR. By default, -all instructions are permitted. -.Sp -The following values of \fIarch\fR are accepted: \f(CW\*(C`c62x\*(C'\fR, -\&\f(CW\*(C`c64x\*(C'\fR, \f(CW\*(C`c64x+\*(C'\fR, \f(CW\*(C`c67x\*(C'\fR, \f(CW\*(C`c67x+\*(C'\fR, \f(CW\*(C`c674x\*(C'\fR. -.IP "\fB\-mdsbt\fR" 4 -.IX Item "-mdsbt" -.PD 0 -.IP "\fB\-mno\-dsbt\fR" 4 -.IX Item "-mno-dsbt" -.PD -The \fB\-mdsbt\fR option causes the assembler to generate the -\&\f(CW\*(C`Tag_ABI_DSBT\*(C'\fR attribute with a value of 1, indicating that the -code is using \s-1DSBT\s0 addressing. The \fB\-mno\-dsbt\fR option, the -default, causes the tag to have a value of 0, indicating that the code -does not use \s-1DSBT\s0 addressing. The linker will emit a warning if -objects of different type (\s-1DSBT\s0 and non-DSBT) are linked together. -.IP "\fB\-mpid=no\fR" 4 -.IX Item "-mpid=no" -.PD 0 -.IP "\fB\-mpid=near\fR" 4 -.IX Item "-mpid=near" -.IP "\fB\-mpid=far\fR" 4 -.IX Item "-mpid=far" -.PD -The \fB\-mpid=\fR option causes the assembler to generate the -\&\f(CW\*(C`Tag_ABI_PID\*(C'\fR attribute with a value indicating the form of data -addressing used by the code. \fB\-mpid=no\fR, the default, -indicates position-dependent data addressing, \fB\-mpid=near\fR -indicates position-independent addressing with \s-1GOT\s0 accesses using near -\&\s-1DP\s0 addressing, and \fB\-mpid=far\fR indicates position-independent -addressing with \s-1GOT\s0 accesses using far \s-1DP\s0 addressing. The linker will -emit a warning if objects built with different settings of this option -are linked together. -.IP "\fB\-mpic\fR" 4 -.IX Item "-mpic" -.PD 0 -.IP "\fB\-mno\-pic\fR" 4 -.IX Item "-mno-pic" -.PD -The \fB\-mpic\fR option causes the assembler to generate the -\&\f(CW\*(C`Tag_ABI_PIC\*(C'\fR attribute with a value of 1, indicating that the -code is using position-independent code addressing, The -\&\f(CW\*(C`\-mno\-pic\*(C'\fR option, the default, causes the tag to have a value of -0, indicating position-dependent code addressing. The linker will -emit a warning if objects of different type (position-dependent and -position-independent) are linked together. -.IP "\fB\-mbig\-endian\fR" 4 -.IX Item "-mbig-endian" -.PD 0 -.IP "\fB\-mlittle\-endian\fR" 4 -.IX Item "-mlittle-endian" -.PD -Generate code for the specified endianness. The default is -little-endian. -.PP -The following options are available when as is configured for a TILE-Gx -processor. -.IP "\fB\-m32 | \-m64\fR" 4 -.IX Item "-m32 | -m64" -Select the word size, either 32 bits or 64 bits. -.PP -The following options are available when as is configured for an -Xtensa processor. -.IP "\fB\-\-text\-section\-literals | \-\-no\-text\-section\-literals\fR" 4 -.IX Item "--text-section-literals | --no-text-section-literals" -Control the treatment of literal pools. The default is -\&\fB\-\-no\-text\-section\-literals\fR, which places literals in -separate sections in the output file. This allows the literal pool to be -placed in a data \s-1RAM/ROM\s0. With \fB\-\-text\-section\-literals\fR, the -literals are interspersed in the text section in order to keep them as -close as possible to their references. This may be necessary for large -assembly files, where the literals would otherwise be out of range of the -\&\f(CW\*(C`L32R\*(C'\fR instructions in the text section. These options only affect -literals referenced via PC-relative \f(CW\*(C`L32R\*(C'\fR instructions; literals -for absolute mode \f(CW\*(C`L32R\*(C'\fR instructions are handled separately. -.IP "\fB\-\-absolute\-literals | \-\-no\-absolute\-literals\fR" 4 -.IX Item "--absolute-literals | --no-absolute-literals" -Indicate to the assembler whether \f(CW\*(C`L32R\*(C'\fR instructions use absolute -or PC-relative addressing. If the processor includes the absolute -addressing option, the default is to use absolute \f(CW\*(C`L32R\*(C'\fR -relocations. Otherwise, only the PC-relative \f(CW\*(C`L32R\*(C'\fR relocations -can be used. -.IP "\fB\-\-target\-align | \-\-no\-target\-align\fR" 4 -.IX Item "--target-align | --no-target-align" -Enable or disable automatic alignment to reduce branch penalties at some -expense in code size. This optimization is enabled by default. Note -that the assembler will always align instructions like \f(CW\*(C`LOOP\*(C'\fR that -have fixed alignment requirements. -.IP "\fB\-\-longcalls | \-\-no\-longcalls\fR" 4 -.IX Item "--longcalls | --no-longcalls" -Enable or disable transformation of call instructions to allow calls -across a greater range of addresses. This option should be used when call -targets can potentially be out of range. It may degrade both code size -and performance, but the linker can generally optimize away the -unnecessary overhead when a call ends up within range. The default is -\&\fB\-\-no\-longcalls\fR. -.IP "\fB\-\-transform | \-\-no\-transform\fR" 4 -.IX Item "--transform | --no-transform" -Enable or disable all assembler transformations of Xtensa instructions, -including both relaxation and optimization. The default is -\&\fB\-\-transform\fR; \fB\-\-no\-transform\fR should only be used in the -rare cases when the instructions must be exactly as specified in the -assembly source. Using \fB\-\-no\-transform\fR causes out of range -instruction operands to be errors. -.IP "\fB\-\-rename\-section\fR \fIoldname\fR\fB=\fR\fInewname\fR" 4 -.IX Item "--rename-section oldname=newname" -Rename the \fIoldname\fR section to \fInewname\fR. This option can be used -multiple times to rename multiple sections. -.PP -The following options are available when as is configured for -a Z80 family processor. -.IP "\fB\-z80\fR" 4 -.IX Item "-z80" -Assemble for Z80 processor. -.IP "\fB\-r800\fR" 4 -.IX Item "-r800" -Assemble for R800 processor. -.IP "\fB\-ignore\-undocumented\-instructions\fR" 4 -.IX Item "-ignore-undocumented-instructions" -.PD 0 -.IP "\fB\-Wnud\fR" 4 -.IX Item "-Wnud" -.PD -Assemble undocumented Z80 instructions that also work on R800 without warning. -.IP "\fB\-ignore\-unportable\-instructions\fR" 4 -.IX Item "-ignore-unportable-instructions" -.PD 0 -.IP "\fB\-Wnup\fR" 4 -.IX Item "-Wnup" -.PD -Assemble all undocumented Z80 instructions without warning. -.IP "\fB\-warn\-undocumented\-instructions\fR" 4 -.IX Item "-warn-undocumented-instructions" -.PD 0 -.IP "\fB\-Wud\fR" 4 -.IX Item "-Wud" -.PD -Issue a warning for undocumented Z80 instructions that also work on R800. -.IP "\fB\-warn\-unportable\-instructions\fR" 4 -.IX Item "-warn-unportable-instructions" -.PD 0 -.IP "\fB\-Wup\fR" 4 -.IX Item "-Wup" -.PD -Issue a warning for undocumented Z80 instructions that do not work on R800. -.IP "\fB\-forbid\-undocumented\-instructions\fR" 4 -.IX Item "-forbid-undocumented-instructions" -.PD 0 -.IP "\fB\-Fud\fR" 4 -.IX Item "-Fud" -.PD -Treat all undocumented instructions as errors. -.IP "\fB\-forbid\-unportable\-instructions\fR" 4 -.IX Item "-forbid-unportable-instructions" -.PD 0 -.IP "\fB\-Fup\fR" 4 -.IX Item "-Fup" -.PD -Treat undocumented Z80 instructions that do not work on R800 as errors. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIgcc\fR\|(1), \fIld\fR\|(1), and the Info entries for \fIbinutils\fR and \fIld\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/contrib/binutils-2.22/gas/doc/as.texinfo b/contrib/binutils-2.22/gas/doc/as.texinfo deleted file mode 100644 index 8ed62a4db6..0000000000 --- a/contrib/binutils-2.22/gas/doc/as.texinfo +++ /dev/null @@ -1,7494 +0,0 @@ -\input texinfo @c -*-Texinfo-*- -@c Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -@c 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -@c Free Software Foundation, Inc. -@c UPDATE!! On future updates-- -@c (1) check for new machine-dep cmdline options in -@c md_parse_option definitions in config/tc-*.c -@c (2) for platform-specific directives, examine md_pseudo_op -@c in config/tc-*.c -@c (3) for object-format specific directives, examine obj_pseudo_op -@c in config/obj-*.c -@c (4) portable directives in potable[] in read.c -@c %**start of header -@setfilename as.info -@c ---config--- -@macro gcctabopt{body} -@code{\body\} -@end macro -@c defaults, config file may override: -@set have-stabs -@c --- -@c man begin NAME -@c --- -@include asconfig.texi -@include bfdver.texi -@c --- -@c man end -@c --- -@c common OR combinations of conditions -@ifset COFF -@set COFF-ELF -@end ifset -@ifset ELF -@set COFF-ELF -@end ifset -@ifset AOUT -@set aout-bout -@end ifset -@ifset ARM/Thumb -@set ARM -@end ifset -@ifset Blackfin -@set Blackfin -@end ifset -@ifset BOUT -@set aout-bout -@end ifset -@ifset H8/300 -@set H8 -@end ifset -@ifset SH -@set H8 -@end ifset -@ifset HPPA -@set abnormal-separator -@end ifset -@c ------------ -@ifset GENERIC -@settitle Using @value{AS} -@end ifset -@ifclear GENERIC -@settitle Using @value{AS} (@value{TARGET}) -@end ifclear -@setchapternewpage odd -@c %**end of header - -@c @smallbook -@c @set SMALL -@c WARE! Some of the machine-dependent sections contain tables of machine -@c instructions. Except in multi-column format, these tables look silly. -@c Unfortunately, Texinfo doesn't have a general-purpose multi-col format, so -@c the multi-col format is faked within @example sections. -@c -@c Again unfortunately, the natural size that fits on a page, for these tables, -@c is different depending on whether or not smallbook is turned on. -@c This matters, because of order: text flow switches columns at each page -@c break. -@c -@c The format faked in this source works reasonably well for smallbook, -@c not well for the default large-page format. This manual expects that if you -@c turn on @smallbook, you will also uncomment the "@set SMALL" to enable the -@c tables in question. You can turn on one without the other at your -@c discretion, of course. -@ifinfo -@set SMALL -@c the insn tables look just as silly in info files regardless of smallbook, -@c might as well show 'em anyways. -@end ifinfo - -@ifnottex -@dircategory Software development -@direntry -* As: (as). The GNU assembler. -* Gas: (as). The GNU assembler. -@end direntry -@end ifnottex - -@finalout -@syncodeindex ky cp - -@copying -This file documents the GNU Assembler "@value{AS}". - -@c man begin COPYRIGHT -Copyright @copyright{} 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -Inc. - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled ``GNU Free Documentation License''. - -@c man end -@end copying - -@titlepage -@title Using @value{AS} -@subtitle The @sc{gnu} Assembler -@ifclear GENERIC -@subtitle for the @value{TARGET} family -@end ifclear -@ifset VERSION_PACKAGE -@sp 1 -@subtitle @value{VERSION_PACKAGE} -@end ifset -@sp 1 -@subtitle Version @value{VERSION} -@sp 1 -@sp 13 -The Free Software Foundation Inc.@: thanks The Nice Computer -Company of Australia for loaning Dean Elsner to write the -first (Vax) version of @command{as} for Project @sc{gnu}. -The proprietors, management and staff of TNCCA thank FSF for -distracting the boss while they got some work -done. -@sp 3 -@author Dean Elsner, Jay Fenlason & friends -@page -@tex -{\parskip=0pt -\hfill {\it Using {\tt @value{AS}}}\par -\hfill Edited by Cygnus Support\par -} -%"boxit" macro for figures: -%Modified from Knuth's ``boxit'' macro from TeXbook (answer to exercise 21.3) -\gdef\boxit#1#2{\vbox{\hrule\hbox{\vrule\kern3pt - \vbox{\parindent=0pt\parskip=0pt\hsize=#1\kern3pt\strut\hfil -#2\hfil\strut\kern3pt}\kern3pt\vrule}\hrule}}%box with visible outline -\gdef\ibox#1#2{\hbox to #1{#2\hfil}\kern8pt}% invisible box -@end tex - -@vskip 0pt plus 1filll -Copyright @copyright{} 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -Inc. - - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, with no Front-Cover Texts, and with no - Back-Cover Texts. A copy of the license is included in the - section entitled ``GNU Free Documentation License''. - -@end titlepage -@contents - -@ifnottex -@node Top -@top Using @value{AS} - -This file is a user guide to the @sc{gnu} assembler @command{@value{AS}} -@ifset VERSION_PACKAGE -@value{VERSION_PACKAGE} -@end ifset -version @value{VERSION}. -@ifclear GENERIC -This version of the file describes @command{@value{AS}} configured to generate -code for @value{TARGET} architectures. -@end ifclear - -This document is distributed under the terms of the GNU Free -Documentation License. A copy of the license is included in the -section entitled ``GNU Free Documentation License''. - -@menu -* Overview:: Overview -* Invoking:: Command-Line Options -* Syntax:: Syntax -* Sections:: Sections and Relocation -* Symbols:: Symbols -* Expressions:: Expressions -* Pseudo Ops:: Assembler Directives -@ifset ELF -* Object Attributes:: Object Attributes -@end ifset -* Machine Dependencies:: Machine Dependent Features -* Reporting Bugs:: Reporting Bugs -* Acknowledgements:: Who Did What -* GNU Free Documentation License:: GNU Free Documentation License -* AS Index:: AS Index -@end menu -@end ifnottex - -@node Overview -@chapter Overview -@iftex -This manual is a user guide to the @sc{gnu} assembler @command{@value{AS}}. -@ifclear GENERIC -This version of the manual describes @command{@value{AS}} configured to generate -code for @value{TARGET} architectures. -@end ifclear -@end iftex - -@cindex invocation summary -@cindex option summary -@cindex summary of options -Here is a brief summary of how to invoke @command{@value{AS}}. For details, -see @ref{Invoking,,Command-Line Options}. - -@c man title AS the portable GNU assembler. - -@ignore -@c man begin SEEALSO -gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}. -@c man end -@end ignore - -@c We don't use deffn and friends for the following because they seem -@c to be limited to one line for the header. -@smallexample -@c man begin SYNOPSIS -@value{AS} [@b{-a}[@b{cdghlns}][=@var{file}]] [@b{--alternate}] [@b{-D}] - [@b{--compress-debug-sections}] [@b{--nocompress-debug-sections}] - [@b{--debug-prefix-map} @var{old}=@var{new}] - [@b{--defsym} @var{sym}=@var{val}] [@b{-f}] [@b{-g}] [@b{--gstabs}] - [@b{--gstabs+}] [@b{--gdwarf-2}] [@b{--help}] [@b{-I} @var{dir}] [@b{-J}] - [@b{-K}] [@b{-L}] [@b{--listing-lhs-width}=@var{NUM}] - [@b{--listing-lhs-width2}=@var{NUM}] [@b{--listing-rhs-width}=@var{NUM}] - [@b{--listing-cont-lines}=@var{NUM}] [@b{--keep-locals}] [@b{-o} - @var{objfile}] [@b{-R}] [@b{--reduce-memory-overheads}] [@b{--statistics}] - [@b{-v}] [@b{-version}] [@b{--version}] [@b{-W}] [@b{--warn}] - [@b{--fatal-warnings}] [@b{-w}] [@b{-x}] [@b{-Z}] [@b{@@@var{FILE}}] - [@b{--size-check=[error|warning]}] - [@b{--target-help}] [@var{target-options}] - [@b{--}|@var{files} @dots{}] -@c -@c Target dependent options are listed below. Keep the list sorted. -@c Add an empty line for separation. -@ifset ALPHA - -@emph{Target Alpha options:} - [@b{-m@var{cpu}}] - [@b{-mdebug} | @b{-no-mdebug}] - [@b{-replace} | @b{-noreplace}] - [@b{-relax}] [@b{-g}] [@b{-G@var{size}}] - [@b{-F}] [@b{-32addr}] -@end ifset -@ifset ARC - -@emph{Target ARC options:} - [@b{-marc[5|6|7|8]}] - [@b{-EB}|@b{-EL}] -@end ifset -@ifset ARM - -@emph{Target ARM options:} -@c Don't document the deprecated options - [@b{-mcpu}=@var{processor}[+@var{extension}@dots{}]] - [@b{-march}=@var{architecture}[+@var{extension}@dots{}]] - [@b{-mfpu}=@var{floating-point-format}] - [@b{-mfloat-abi}=@var{abi}] - [@b{-meabi}=@var{ver}] - [@b{-mthumb}] - [@b{-EB}|@b{-EL}] - [@b{-mapcs-32}|@b{-mapcs-26}|@b{-mapcs-float}| - @b{-mapcs-reentrant}] - [@b{-mthumb-interwork}] [@b{-k}] -@end ifset -@ifset Blackfin - -@emph{Target Blackfin options:} - [@b{-mcpu}=@var{processor}[-@var{sirevision}]] - [@b{-mfdpic}] - [@b{-mno-fdpic}] - [@b{-mnopic}] -@end ifset -@ifset CRIS - -@emph{Target CRIS options:} - [@b{--underscore} | @b{--no-underscore}] - [@b{--pic}] [@b{-N}] - [@b{--emulation=criself} | @b{--emulation=crisaout}] - [@b{--march=v0_v10} | @b{--march=v10} | @b{--march=v32} | @b{--march=common_v10_v32}] -@c Deprecated -- deliberately not documented. -@c [@b{-h}] [@b{-H}] -@end ifset -@ifset D10V - -@emph{Target D10V options:} - [@b{-O}] -@end ifset -@ifset D30V - -@emph{Target D30V options:} - [@b{-O}|@b{-n}|@b{-N}] -@end ifset -@ifset H8 - -@emph{Target H8/300 options:} - [-h-tick-hex] -@end ifset -@ifset HPPA -@c HPPA has no machine-dependent assembler options (yet). -@end ifset -@ifset I80386 - -@emph{Target i386 options:} - [@b{--32}|@b{--n32}|@b{--64}] [@b{-n}] - [@b{-march}=@var{CPU}[+@var{EXTENSION}@dots{}]] [@b{-mtune}=@var{CPU}] -@end ifset -@ifset I960 - -@emph{Target i960 options:} -@c see md_parse_option in tc-i960.c - [@b{-ACA}|@b{-ACA_A}|@b{-ACB}|@b{-ACC}|@b{-AKA}|@b{-AKB}| - @b{-AKC}|@b{-AMC}] - [@b{-b}] [@b{-no-relax}] -@end ifset -@ifset IA64 - -@emph{Target IA-64 options:} - [@b{-mconstant-gp}|@b{-mauto-pic}] - [@b{-milp32}|@b{-milp64}|@b{-mlp64}|@b{-mp64}] - [@b{-mle}|@b{mbe}] - [@b{-mtune=itanium1}|@b{-mtune=itanium2}] - [@b{-munwind-check=warning}|@b{-munwind-check=error}] - [@b{-mhint.b=ok}|@b{-mhint.b=warning}|@b{-mhint.b=error}] - [@b{-x}|@b{-xexplicit}] [@b{-xauto}] [@b{-xdebug}] -@end ifset -@ifset IP2K - -@emph{Target IP2K options:} - [@b{-mip2022}|@b{-mip2022ext}] -@end ifset -@ifset M32C - -@emph{Target M32C options:} - [@b{-m32c}|@b{-m16c}] [-relax] [-h-tick-hex] -@end ifset -@ifset M32R - -@emph{Target M32R options:} - [@b{--m32rx}|@b{--[no-]warn-explicit-parallel-conflicts}| - @b{--W[n]p}] -@end ifset -@ifset M680X0 - -@emph{Target M680X0 options:} - [@b{-l}] [@b{-m68000}|@b{-m68010}|@b{-m68020}|@dots{}] -@end ifset -@ifset M68HC11 - -@emph{Target M68HC11 options:} - [@b{-m68hc11}|@b{-m68hc12}|@b{-m68hcs12}] - [@b{-mshort}|@b{-mlong}] - [@b{-mshort-double}|@b{-mlong-double}] - [@b{--force-long-branches}] [@b{--short-branches}] - [@b{--strict-direct-mode}] [@b{--print-insn-syntax}] - [@b{--print-opcodes}] [@b{--generate-example}] -@end ifset -@ifset MCORE - -@emph{Target MCORE options:} - [@b{-jsri2bsr}] [@b{-sifilter}] [@b{-relax}] - [@b{-mcpu=[210|340]}] -@end ifset -@ifset MICROBLAZE -@emph{Target MICROBLAZE options:} -@c MicroBlaze has no machine-dependent assembler options. -@end ifset -@ifset MIPS - -@emph{Target MIPS options:} - [@b{-nocpp}] [@b{-EL}] [@b{-EB}] [@b{-O}[@var{optimization level}]] - [@b{-g}[@var{debug level}]] [@b{-G} @var{num}] [@b{-KPIC}] [@b{-call_shared}] - [@b{-non_shared}] [@b{-xgot} [@b{-mvxworks-pic}] - [@b{-mabi}=@var{ABI}] [@b{-32}] [@b{-n32}] [@b{-64}] [@b{-mfp32}] [@b{-mgp32}] - [@b{-march}=@var{CPU}] [@b{-mtune}=@var{CPU}] [@b{-mips1}] [@b{-mips2}] - [@b{-mips3}] [@b{-mips4}] [@b{-mips5}] [@b{-mips32}] [@b{-mips32r2}] - [@b{-mips64}] [@b{-mips64r2}] - [@b{-construct-floats}] [@b{-no-construct-floats}] - [@b{-trap}] [@b{-no-break}] [@b{-break}] [@b{-no-trap}] - [@b{-mips16}] [@b{-no-mips16}] - [@b{-mmicromips}] [@b{-mno-micromips}] - [@b{-msmartmips}] [@b{-mno-smartmips}] - [@b{-mips3d}] [@b{-no-mips3d}] - [@b{-mdmx}] [@b{-no-mdmx}] - [@b{-mdsp}] [@b{-mno-dsp}] - [@b{-mdspr2}] [@b{-mno-dspr2}] - [@b{-mmt}] [@b{-mno-mt}] - [@b{-mmcu}] [@b{-mno-mcu}] - [@b{-mfix7000}] [@b{-mno-fix7000}] - [@b{-mfix-vr4120}] [@b{-mno-fix-vr4120}] - [@b{-mfix-vr4130}] [@b{-mno-fix-vr4130}] - [@b{-mdebug}] [@b{-no-mdebug}] - [@b{-mpdr}] [@b{-mno-pdr}] -@end ifset -@ifset MMIX - -@emph{Target MMIX options:} - [@b{--fixed-special-register-names}] [@b{--globalize-symbols}] - [@b{--gnu-syntax}] [@b{--relax}] [@b{--no-predefined-symbols}] - [@b{--no-expand}] [@b{--no-merge-gregs}] [@b{-x}] - [@b{--linker-allocated-gregs}] -@end ifset -@ifset PDP11 - -@emph{Target PDP11 options:} - [@b{-mpic}|@b{-mno-pic}] [@b{-mall}] [@b{-mno-extensions}] - [@b{-m}@var{extension}|@b{-mno-}@var{extension}] - [@b{-m}@var{cpu}] [@b{-m}@var{machine}] -@end ifset -@ifset PJ - -@emph{Target picoJava options:} - [@b{-mb}|@b{-me}] -@end ifset -@ifset PPC - -@emph{Target PowerPC options:} - [@b{-a32}|@b{-a64}] - [@b{-mpwrx}|@b{-mpwr2}|@b{-mpwr}|@b{-m601}|@b{-mppc}|@b{-mppc32}|@b{-m603}|@b{-m604}|@b{-m403}|@b{-m405}| - @b{-m440}|@b{-m464}|@b{-m476}|@b{-m7400}|@b{-m7410}|@b{-m7450}|@b{-m7455}|@b{-m750cl}|@b{-mppc64}| - @b{-m620}|@b{-me500}|@b{-e500x2}|@b{-me500mc}|@b{-me500mc64}|@b{-mppc64bridge}|@b{-mbooke}| - @b{-mpower4}|@b{-mpr4}|@b{-mpower5}|@b{-mpwr5}|@b{-mpwr5x}|@b{-mpower6}|@b{-mpwr6}| - @b{-mpower7}|@b{-mpw7}|@b{-ma2}|@b{-mcell}|@b{-mspe}|@b{-mtitan}|@b{-me300}|@b{-mcom}] - [@b{-many}] [@b{-maltivec}|@b{-mvsx}] - [@b{-mregnames}|@b{-mno-regnames}] - [@b{-mrelocatable}|@b{-mrelocatable-lib}|@b{-K PIC}] [@b{-memb}] - [@b{-mlittle}|@b{-mlittle-endian}|@b{-le}|@b{-mbig}|@b{-mbig-endian}|@b{-be}] - [@b{-msolaris}|@b{-mno-solaris}] - [@b{-nops=@var{count}}] -@end ifset -@ifset RX - -@emph{Target RX options:} - [@b{-mlittle-endian}|@b{-mbig-endian}] - [@b{-m32bit-ints}|@b{-m16bit-ints}] - [@b{-m32bit-doubles}|@b{-m64bit-doubles}] -@end ifset -@ifset S390 - -@emph{Target s390 options:} - [@b{-m31}|@b{-m64}] [@b{-mesa}|@b{-mzarch}] [@b{-march}=@var{CPU}] - [@b{-mregnames}|@b{-mno-regnames}] - [@b{-mwarn-areg-zero}] -@end ifset -@ifset SCORE - -@emph{Target SCORE options:} - [@b{-EB}][@b{-EL}][@b{-FIXDD}][@b{-NWARN}] - [@b{-SCORE5}][@b{-SCORE5U}][@b{-SCORE7}][@b{-SCORE3}] - [@b{-march=score7}][@b{-march=score3}] - [@b{-USE_R1}][@b{-KPIC}][@b{-O0}][@b{-G} @var{num}][@b{-V}] -@end ifset -@ifset SPARC - -@emph{Target SPARC options:} -@c The order here is important. See c-sparc.texi. - [@b{-Av6}|@b{-Av7}|@b{-Av8}|@b{-Asparclet}|@b{-Asparclite} - @b{-Av8plus}|@b{-Av8plusa}|@b{-Av9}|@b{-Av9a}] - [@b{-xarch=v8plus}|@b{-xarch=v8plusa}] [@b{-bump}] - [@b{-32}|@b{-64}] -@end ifset -@ifset TIC54X - -@emph{Target TIC54X options:} - [@b{-mcpu=54[123589]}|@b{-mcpu=54[56]lp}] [@b{-mfar-mode}|@b{-mf}] - [@b{-merrors-to-file} @var{}|@b{-me} @var{}] -@end ifset - -@ifset TIC6X - -@emph{Target TIC6X options:} - [@b{-march=@var{arch}}] [@b{-mbig-endian}|@b{-mlittle-endian}] - [@b{-mdsbt}|@b{-mno-dsbt}] [@b{-mpid=no}|@b{-mpid=near}|@b{-mpid=far}] - [@b{-mpic}|@b{-mno-pic}] -@end ifset -@ifset TILEGX - -@emph{Target TILE-Gx options:} - [@b{-m32}|@b{-m64}] -@end ifset -@ifset TILEPRO -@c TILEPro has no machine-dependent assembler options -@end ifset - -@ifset XTENSA - -@emph{Target Xtensa options:} - [@b{--[no-]text-section-literals}] [@b{--[no-]absolute-literals}] - [@b{--[no-]target-align}] [@b{--[no-]longcalls}] - [@b{--[no-]transform}] - [@b{--rename-section} @var{oldname}=@var{newname}] -@end ifset - -@ifset Z80 - -@emph{Target Z80 options:} - [@b{-z80}] [@b{-r800}] - [@b{ -ignore-undocumented-instructions}] [@b{-Wnud}] - [@b{ -ignore-unportable-instructions}] [@b{-Wnup}] - [@b{ -warn-undocumented-instructions}] [@b{-Wud}] - [@b{ -warn-unportable-instructions}] [@b{-Wup}] - [@b{ -forbid-undocumented-instructions}] [@b{-Fud}] - [@b{ -forbid-unportable-instructions}] [@b{-Fup}] -@end ifset - -@ifset Z8000 -@c Z8000 has no machine-dependent assembler options -@end ifset - -@c man end -@end smallexample - -@c man begin OPTIONS - -@table @gcctabopt -@include at-file.texi - -@item -a[cdghlmns] -Turn on listings, in any of a variety of ways: - -@table @gcctabopt -@item -ac -omit false conditionals - -@item -ad -omit debugging directives - -@item -ag -include general information, like @value{AS} version and options passed - -@item -ah -include high-level source - -@item -al -include assembly - -@item -am -include macro expansions - -@item -an -omit forms processing - -@item -as -include symbols - -@item =file -set the name of the listing file -@end table - -You may combine these options; for example, use @samp{-aln} for assembly -listing without forms processing. The @samp{=file} option, if used, must be -the last one. By itself, @samp{-a} defaults to @samp{-ahls}. - -@item --alternate -Begin in alternate macro mode. -@ifclear man -@xref{Altmacro,,@code{.altmacro}}. -@end ifclear - -@item --compress-debug-sections -Compress DWARF debug sections using zlib. The debug sections are renamed -to begin with @samp{.zdebug}, and the resulting object file may not be -compatible with older linkers and object file utilities. - -@item --nocompress-debug-sections -Do not compress DWARF debug sections. This is the default. - -@item -D -Ignored. This option is accepted for script compatibility with calls to -other assemblers. - -@item --debug-prefix-map @var{old}=@var{new} -When assembling files in directory @file{@var{old}}, record debugging -information describing them as in @file{@var{new}} instead. - -@item --defsym @var{sym}=@var{value} -Define the symbol @var{sym} to be @var{value} before assembling the input file. -@var{value} must be an integer constant. As in C, a leading @samp{0x} -indicates a hexadecimal value, and a leading @samp{0} indicates an octal -value. The value of the symbol can be overridden inside a source file via the -use of a @code{.set} pseudo-op. - -@item -f -``fast''---skip whitespace and comment preprocessing (assume source is -compiler output). - -@item -g -@itemx --gen-debug -Generate debugging information for each assembler source line using whichever -debug format is preferred by the target. This currently means either STABS, -ECOFF or DWARF2. - -@item --gstabs -Generate stabs debugging information for each assembler line. This -may help debugging assembler code, if the debugger can handle it. - -@item --gstabs+ -Generate stabs debugging information for each assembler line, with GNU -extensions that probably only gdb can handle, and that could make other -debuggers crash or refuse to read your program. This -may help debugging assembler code. Currently the only GNU extension is -the location of the current working directory at assembling time. - -@item --gdwarf-2 -Generate DWARF2 debugging information for each assembler line. This -may help debugging assembler code, if the debugger can handle it. Note---this -option is only supported by some targets, not all of them. - -@item --size-check=error -@itemx --size-check=warning -Issue an error or warning for invalid ELF .size directive. - -@item --help -Print a summary of the command line options and exit. - -@item --target-help -Print a summary of all target specific options and exit. - -@item -I @var{dir} -Add directory @var{dir} to the search list for @code{.include} directives. - -@item -J -Don't warn about signed overflow. - -@item -K -@ifclear DIFF-TBL-KLUGE -This option is accepted but has no effect on the @value{TARGET} family. -@end ifclear -@ifset DIFF-TBL-KLUGE -Issue warnings when difference tables altered for long displacements. -@end ifset - -@item -L -@itemx --keep-locals -Keep (in the symbol table) local symbols. These symbols start with -system-specific local label prefixes, typically @samp{.L} for ELF systems -or @samp{L} for traditional a.out systems. -@ifclear man -@xref{Symbol Names}. -@end ifclear - -@item --listing-lhs-width=@var{number} -Set the maximum width, in words, of the output data column for an assembler -listing to @var{number}. - -@item --listing-lhs-width2=@var{number} -Set the maximum width, in words, of the output data column for continuation -lines in an assembler listing to @var{number}. - -@item --listing-rhs-width=@var{number} -Set the maximum width of an input source line, as displayed in a listing, to -@var{number} bytes. - -@item --listing-cont-lines=@var{number} -Set the maximum number of lines printed in a listing for a single line of input -to @var{number} + 1. - -@item -o @var{objfile} -Name the object-file output from @command{@value{AS}} @var{objfile}. - -@item -R -Fold the data section into the text section. - -@kindex --hash-size=@var{number} -Set the default size of GAS's hash tables to a prime number close to -@var{number}. Increasing this value can reduce the length of time it takes the -assembler to perform its tasks, at the expense of increasing the assembler's -memory requirements. Similarly reducing this value can reduce the memory -requirements at the expense of speed. - -@item --reduce-memory-overheads -This option reduces GAS's memory requirements, at the expense of making the -assembly processes slower. Currently this switch is a synonym for -@samp{--hash-size=4051}, but in the future it may have other effects as well. - -@item --statistics -Print the maximum space (in bytes) and total time (in seconds) used by -assembly. - -@item --strip-local-absolute -Remove local absolute symbols from the outgoing symbol table. - -@item -v -@itemx -version -Print the @command{as} version. - -@item --version -Print the @command{as} version and exit. - -@item -W -@itemx --no-warn -Suppress warning messages. - -@item --fatal-warnings -Treat warnings as errors. - -@item --warn -Don't suppress warning messages or treat them as errors. - -@item -w -Ignored. - -@item -x -Ignored. - -@item -Z -Generate an object file even after errors. - -@item -- | @var{files} @dots{} -Standard input, or source files to assemble. - -@end table -@c man end - -@ifset ALPHA - -@ifclear man -@xref{Alpha Options}, for the options available when @value{AS} is configured -for an Alpha processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for an Alpha -processor. -@c man end -@c man begin INCLUDE -@include c-alpha.texi -@c ended inside the included file -@end ifset - -@end ifset - -@c man begin OPTIONS -@ifset ARC -The following options are available when @value{AS} is configured for -an ARC processor. - -@table @gcctabopt -@item -marc[5|6|7|8] -This option selects the core processor variant. -@item -EB | -EL -Select either big-endian (-EB) or little-endian (-EL) output. -@end table -@end ifset - -@ifset ARM -The following options are available when @value{AS} is configured for the ARM -processor family. - -@table @gcctabopt -@item -mcpu=@var{processor}[+@var{extension}@dots{}] -Specify which ARM processor variant is the target. -@item -march=@var{architecture}[+@var{extension}@dots{}] -Specify which ARM architecture variant is used by the target. -@item -mfpu=@var{floating-point-format} -Select which Floating Point architecture is the target. -@item -mfloat-abi=@var{abi} -Select which floating point ABI is in use. -@item -mthumb -Enable Thumb only instruction decoding. -@item -mapcs-32 | -mapcs-26 | -mapcs-float | -mapcs-reentrant -Select which procedure calling convention is in use. -@item -EB | -EL -Select either big-endian (-EB) or little-endian (-EL) output. -@item -mthumb-interwork -Specify that the code has been generated with interworking between Thumb and -ARM code in mind. -@item -k -Specify that PIC code has been generated. -@end table -@end ifset -@c man end - -@ifset Blackfin - -@ifclear man -@xref{Blackfin Options}, for the options available when @value{AS} is -configured for the Blackfin processor family. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for -the Blackfin processor family. -@c man end -@c man begin INCLUDE -@include c-bfin.texi -@c ended inside the included file -@end ifset - -@end ifset - -@c man begin OPTIONS -@ifset CRIS -See the info pages for documentation of the CRIS-specific options. -@end ifset - -@ifset D10V -The following options are available when @value{AS} is configured for -a D10V processor. -@table @gcctabopt -@cindex D10V optimization -@cindex optimization, D10V -@item -O -Optimize output by parallelizing instructions. -@end table -@end ifset - -@ifset D30V -The following options are available when @value{AS} is configured for a D30V -processor. -@table @gcctabopt -@cindex D30V optimization -@cindex optimization, D30V -@item -O -Optimize output by parallelizing instructions. - -@cindex D30V nops -@item -n -Warn when nops are generated. - -@cindex D30V nops after 32-bit multiply -@item -N -Warn when a nop after a 32-bit multiply instruction is generated. -@end table -@end ifset -@c man end - -@ifset I80386 - -@ifclear man -@xref{i386-Options}, for the options available when @value{AS} is -configured for an i386 processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for -an i386 processor. -@c man end -@c man begin INCLUDE -@include c-i386.texi -@c ended inside the included file -@end ifset - -@end ifset - -@c man begin OPTIONS -@ifset I960 -The following options are available when @value{AS} is configured for the -Intel 80960 processor. - -@table @gcctabopt -@item -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC -Specify which variant of the 960 architecture is the target. - -@item -b -Add code to collect statistics about branches taken. - -@item -no-relax -Do not alter compare-and-branch instructions for long displacements; -error if necessary. - -@end table -@end ifset - -@ifset IP2K -The following options are available when @value{AS} is configured for the -Ubicom IP2K series. - -@table @gcctabopt - -@item -mip2022ext -Specifies that the extended IP2022 instructions are allowed. - -@item -mip2022 -Restores the default behaviour, which restricts the permitted instructions to -just the basic IP2022 ones. - -@end table -@end ifset - -@ifset M32C -The following options are available when @value{AS} is configured for the -Renesas M32C and M16C processors. - -@table @gcctabopt - -@item -m32c -Assemble M32C instructions. - -@item -m16c -Assemble M16C instructions (the default). - -@item -relax -Enable support for link-time relaxations. - -@item -h-tick-hex -Support H'00 style hex constants in addition to 0x00 style. - -@end table -@end ifset - -@ifset M32R -The following options are available when @value{AS} is configured for the -Renesas M32R (formerly Mitsubishi M32R) series. - -@table @gcctabopt - -@item --m32rx -Specify which processor in the M32R family is the target. The default -is normally the M32R, but this option changes it to the M32RX. - -@item --warn-explicit-parallel-conflicts or --Wp -Produce warning messages when questionable parallel constructs are -encountered. - -@item --no-warn-explicit-parallel-conflicts or --Wnp -Do not produce warning messages when questionable parallel constructs are -encountered. - -@end table -@end ifset - -@ifset M680X0 -The following options are available when @value{AS} is configured for the -Motorola 68000 series. - -@table @gcctabopt - -@item -l -Shorten references to undefined symbols, to one word instead of two. - -@item -m68000 | -m68008 | -m68010 | -m68020 | -m68030 -@itemx | -m68040 | -m68060 | -m68302 | -m68331 | -m68332 -@itemx | -m68333 | -m68340 | -mcpu32 | -m5200 -Specify what processor in the 68000 family is the target. The default -is normally the 68020, but this can be changed at configuration time. - -@item -m68881 | -m68882 | -mno-68881 | -mno-68882 -The target machine does (or does not) have a floating-point coprocessor. -The default is to assume a coprocessor for 68020, 68030, and cpu32. Although -the basic 68000 is not compatible with the 68881, a combination of the -two can be specified, since it's possible to do emulation of the -coprocessor instructions with the main processor. - -@item -m68851 | -mno-68851 -The target machine does (or does not) have a memory-management -unit coprocessor. The default is to assume an MMU for 68020 and up. - -@end table -@end ifset - -@ifset PDP11 - -For details about the PDP-11 machine dependent features options, -see @ref{PDP-11-Options}. - -@table @gcctabopt -@item -mpic | -mno-pic -Generate position-independent (or position-dependent) code. The -default is @option{-mpic}. - -@item -mall -@itemx -mall-extensions -Enable all instruction set extensions. This is the default. - -@item -mno-extensions -Disable all instruction set extensions. - -@item -m@var{extension} | -mno-@var{extension} -Enable (or disable) a particular instruction set extension. - -@item -m@var{cpu} -Enable the instruction set extensions supported by a particular CPU, and -disable all other extensions. - -@item -m@var{machine} -Enable the instruction set extensions supported by a particular machine -model, and disable all other extensions. -@end table - -@end ifset - -@ifset PJ -The following options are available when @value{AS} is configured for -a picoJava processor. - -@table @gcctabopt - -@cindex PJ endianness -@cindex endianness, PJ -@cindex big endian output, PJ -@item -mb -Generate ``big endian'' format output. - -@cindex little endian output, PJ -@item -ml -Generate ``little endian'' format output. - -@end table -@end ifset - -@ifset M68HC11 -The following options are available when @value{AS} is configured for the -Motorola 68HC11 or 68HC12 series. - -@table @gcctabopt - -@item -m68hc11 | -m68hc12 | -m68hcs12 -Specify what processor is the target. The default is -defined by the configuration option when building the assembler. - -@item -mshort -Specify to use the 16-bit integer ABI. - -@item -mlong -Specify to use the 32-bit integer ABI. - -@item -mshort-double -Specify to use the 32-bit double ABI. - -@item -mlong-double -Specify to use the 64-bit double ABI. - -@item --force-long-branches -Relative branches are turned into absolute ones. This concerns -conditional branches, unconditional branches and branches to a -sub routine. - -@item -S | --short-branches -Do not turn relative branches into absolute ones -when the offset is out of range. - -@item --strict-direct-mode -Do not turn the direct addressing mode into extended addressing mode -when the instruction does not support direct addressing mode. - -@item --print-insn-syntax -Print the syntax of instruction in case of error. - -@item --print-opcodes -print the list of instructions with syntax and then exit. - -@item --generate-example -print an example of instruction for each possible instruction and then exit. -This option is only useful for testing @command{@value{AS}}. - -@end table -@end ifset - -@ifset SPARC -The following options are available when @command{@value{AS}} is configured -for the SPARC architecture: - -@table @gcctabopt -@item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite -@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a -Explicitly select a variant of the SPARC architecture. - -@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment. -@samp{-Av9} and @samp{-Av9a} select a 64 bit environment. - -@samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with -UltraSPARC extensions. - -@item -xarch=v8plus | -xarch=v8plusa -For compatibility with the Solaris v9 assembler. These options are -equivalent to -Av8plus and -Av8plusa, respectively. - -@item -bump -Warn when the assembler switches to another architecture. -@end table -@end ifset - -@ifset TIC54X -The following options are available when @value{AS} is configured for the 'c54x -architecture. - -@table @gcctabopt -@item -mfar-mode -Enable extended addressing mode. All addresses and relocations will assume -extended addressing (usually 23 bits). -@item -mcpu=@var{CPU_VERSION} -Sets the CPU version being compiled for. -@item -merrors-to-file @var{FILENAME} -Redirect error output to a file, for broken systems which don't support such -behaviour in the shell. -@end table -@end ifset - -@ifset MIPS -The following options are available when @value{AS} is configured for -a @sc{mips} processor. - -@table @gcctabopt -@item -G @var{num} -This option sets the largest size of an object that can be referenced -implicitly with the @code{gp} register. It is only accepted for targets that -use ECOFF format, such as a DECstation running Ultrix. The default value is 8. - -@cindex MIPS endianness -@cindex endianness, MIPS -@cindex big endian output, MIPS -@item -EB -Generate ``big endian'' format output. - -@cindex little endian output, MIPS -@item -EL -Generate ``little endian'' format output. - -@cindex MIPS ISA -@item -mips1 -@itemx -mips2 -@itemx -mips3 -@itemx -mips4 -@itemx -mips5 -@itemx -mips32 -@itemx -mips32r2 -@itemx -mips64 -@itemx -mips64r2 -Generate code for a particular @sc{mips} Instruction Set Architecture level. -@samp{-mips1} is an alias for @samp{-march=r3000}, @samp{-mips2} is an -alias for @samp{-march=r6000}, @samp{-mips3} is an alias for -@samp{-march=r4000} and @samp{-mips4} is an alias for @samp{-march=r8000}. -@samp{-mips5}, @samp{-mips32}, @samp{-mips32r2}, @samp{-mips64}, and -@samp{-mips64r2} -correspond to generic -@samp{MIPS V}, @samp{MIPS32}, @samp{MIPS32 Release 2}, @samp{MIPS64}, -and @samp{MIPS64 Release 2} -ISA processors, respectively. - -@item -march=@var{CPU} -Generate code for a particular @sc{mips} cpu. - -@item -mtune=@var{cpu} -Schedule and tune for a particular @sc{mips} cpu. - -@item -mfix7000 -@itemx -mno-fix7000 -Cause nops to be inserted if the read of the destination register -of an mfhi or mflo instruction occurs in the following two instructions. - -@item -mdebug -@itemx -no-mdebug -Cause stabs-style debugging output to go into an ECOFF-style .mdebug -section instead of the standard ELF .stabs sections. - -@item -mpdr -@itemx -mno-pdr -Control generation of @code{.pdr} sections. - -@item -mgp32 -@itemx -mfp32 -The register sizes are normally inferred from the ISA and ABI, but these -flags force a certain group of registers to be treated as 32 bits wide at -all times. @samp{-mgp32} controls the size of general-purpose registers -and @samp{-mfp32} controls the size of floating-point registers. - -@item -mips16 -@itemx -no-mips16 -Generate code for the MIPS 16 processor. This is equivalent to putting -@code{.set mips16} at the start of the assembly file. @samp{-no-mips16} -turns off this option. - -@item -mmicromips -@itemx -mno-micromips -Generate code for the microMIPS processor. This is equivalent to putting -@code{.set micromips} at the start of the assembly file. @samp{-mno-micromips} -turns off this option. This is equivalent to putting @code{.set nomicromips} -at the start of the assembly file. - -@item -msmartmips -@itemx -mno-smartmips -Enables the SmartMIPS extension to the MIPS32 instruction set. This is -equivalent to putting @code{.set smartmips} at the start of the assembly file. -@samp{-mno-smartmips} turns off this option. - -@item -mips3d -@itemx -no-mips3d -Generate code for the MIPS-3D Application Specific Extension. -This tells the assembler to accept MIPS-3D instructions. -@samp{-no-mips3d} turns off this option. - -@item -mdmx -@itemx -no-mdmx -Generate code for the MDMX Application Specific Extension. -This tells the assembler to accept MDMX instructions. -@samp{-no-mdmx} turns off this option. - -@item -mdsp -@itemx -mno-dsp -Generate code for the DSP Release 1 Application Specific Extension. -This tells the assembler to accept DSP Release 1 instructions. -@samp{-mno-dsp} turns off this option. - -@item -mdspr2 -@itemx -mno-dspr2 -Generate code for the DSP Release 2 Application Specific Extension. -This option implies -mdsp. -This tells the assembler to accept DSP Release 2 instructions. -@samp{-mno-dspr2} turns off this option. - -@item -mmt -@itemx -mno-mt -Generate code for the MT Application Specific Extension. -This tells the assembler to accept MT instructions. -@samp{-mno-mt} turns off this option. - -@item -mmcu -@itemx -mno-mcu -Generate code for the MCU Application Specific Extension. -This tells the assembler to accept MCU instructions. -@samp{-mno-mcu} turns off this option. - -@item --construct-floats -@itemx --no-construct-floats -The @samp{--no-construct-floats} option disables the construction of -double width floating point constants by loading the two halves of the -value into the two single width floating point registers that make up -the double width register. By default @samp{--construct-floats} is -selected, allowing construction of these floating point constants. - -@cindex emulation -@item --emulation=@var{name} -This option causes @command{@value{AS}} to emulate @command{@value{AS}} configured -for some other target, in all respects, including output format (choosing -between ELF and ECOFF only), handling of pseudo-opcodes which may generate -debugging information or store symbol table information, and default -endianness. The available configuration names are: @samp{mipsecoff}, -@samp{mipself}, @samp{mipslecoff}, @samp{mipsbecoff}, @samp{mipslelf}, -@samp{mipsbelf}. The first two do not alter the default endianness from that -of the primary target for which the assembler was configured; the others change -the default to little- or big-endian as indicated by the @samp{b} or @samp{l} -in the name. Using @samp{-EB} or @samp{-EL} will override the endianness -selection in any case. - -This option is currently supported only when the primary target -@command{@value{AS}} is configured for is a @sc{mips} ELF or ECOFF target. -Furthermore, the primary target or others specified with -@samp{--enable-targets=@dots{}} at configuration time must include support for -the other format, if both are to be available. For example, the Irix 5 -configuration includes support for both. - -Eventually, this option will support more configurations, with more -fine-grained control over the assembler's behavior, and will be supported for -more processors. - -@item -nocpp -@command{@value{AS}} ignores this option. It is accepted for compatibility with -the native tools. - -@item --trap -@itemx --no-trap -@itemx --break -@itemx --no-break -Control how to deal with multiplication overflow and division by zero. -@samp{--trap} or @samp{--no-break} (which are synonyms) take a trap exception -(and only work for Instruction Set Architecture level 2 and higher); -@samp{--break} or @samp{--no-trap} (also synonyms, and the default) take a -break exception. - -@item -n -When this option is used, @command{@value{AS}} will issue a warning every -time it generates a nop instruction from a macro. -@end table -@end ifset - -@ifset MCORE -The following options are available when @value{AS} is configured for -an MCore processor. - -@table @gcctabopt -@item -jsri2bsr -@itemx -nojsri2bsr -Enable or disable the JSRI to BSR transformation. By default this is enabled. -The command line option @samp{-nojsri2bsr} can be used to disable it. - -@item -sifilter -@itemx -nosifilter -Enable or disable the silicon filter behaviour. By default this is disabled. -The default can be overridden by the @samp{-sifilter} command line option. - -@item -relax -Alter jump instructions for long displacements. - -@item -mcpu=[210|340] -Select the cpu type on the target hardware. This controls which instructions -can be assembled. - -@item -EB -Assemble for a big endian target. - -@item -EL -Assemble for a little endian target. - -@end table -@end ifset - -@ifset MMIX -See the info pages for documentation of the MMIX-specific options. -@end ifset - -@c man end -@ifset PPC - -@ifclear man -@xref{PowerPC-Opts}, for the options available when @value{AS} is configured -for a PowerPC processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for a -PowerPC processor. -@c man end -@c man begin INCLUDE -@include c-ppc.texi -@c ended inside the included file -@end ifset - -@end ifset - -@c man begin OPTIONS -@ifset RX -See the info pages for documentation of the RX-specific options. -@end ifset - -@ifset S390 -The following options are available when @value{AS} is configured for the s390 -processor family. - -@table @gcctabopt -@item -m31 -@itemx -m64 -Select the word size, either 31/32 bits or 64 bits. -@item -mesa -@item -mzarch -Select the architecture mode, either the Enterprise System -Architecture (esa) or the z/Architecture mode (zarch). -@item -march=@var{processor} -Specify which s390 processor variant is the target, @samp{g6}, @samp{g6}, -@samp{z900}, @samp{z990}, @samp{z9-109}, @samp{z9-ec}, or @samp{z10}. -@item -mregnames -@itemx -mno-regnames -Allow or disallow symbolic names for registers. -@item -mwarn-areg-zero -Warn whenever the operand for a base or index register has been specified -but evaluates to zero. -@end table -@end ifset -@c man end - -@ifset TIC6X - -@ifclear man -@xref{TIC6X Options}, for the options available when @value{AS} is configured -for a TMS320C6000 processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for a -TMS320C6000 processor. -@c man end -@c man begin INCLUDE -@include c-tic6x.texi -@c ended inside the included file -@end ifset - -@end ifset - -@ifset TILEGX - -@ifclear man -@xref{TILE-Gx Options}, for the options available when @value{AS} is configured -for a TILE-Gx processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for a TILE-Gx -processor. -@c man end -@c man begin INCLUDE -@include c-tilegx.texi -@c ended inside the included file -@end ifset - -@end ifset - -@ifset XTENSA - -@ifclear man -@xref{Xtensa Options}, for the options available when @value{AS} is configured -for an Xtensa processor. -@end ifclear - -@ifset man -@c man begin OPTIONS -The following options are available when @value{AS} is configured for an -Xtensa processor. -@c man end -@c man begin INCLUDE -@include c-xtensa.texi -@c ended inside the included file -@end ifset - -@end ifset - -@c man begin OPTIONS - -@ifset Z80 -The following options are available when @value{AS} is configured for -a Z80 family processor. -@table @gcctabopt -@item -z80 -Assemble for Z80 processor. -@item -r800 -Assemble for R800 processor. -@item -ignore-undocumented-instructions -@itemx -Wnud -Assemble undocumented Z80 instructions that also work on R800 without warning. -@item -ignore-unportable-instructions -@itemx -Wnup -Assemble all undocumented Z80 instructions without warning. -@item -warn-undocumented-instructions -@itemx -Wud -Issue a warning for undocumented Z80 instructions that also work on R800. -@item -warn-unportable-instructions -@itemx -Wup -Issue a warning for undocumented Z80 instructions that do not work on R800. -@item -forbid-undocumented-instructions -@itemx -Fud -Treat all undocumented instructions as errors. -@item -forbid-unportable-instructions -@itemx -Fup -Treat undocumented Z80 instructions that do not work on R800 as errors. -@end table -@end ifset - -@c man end - -@menu -* Manual:: Structure of this Manual -* GNU Assembler:: The GNU Assembler -* Object Formats:: Object File Formats -* Command Line:: Command Line -* Input Files:: Input Files -* Object:: Output (Object) File -* Errors:: Error and Warning Messages -@end menu - -@node Manual -@section Structure of this Manual - -@cindex manual, structure and purpose -This manual is intended to describe what you need to know to use -@sc{gnu} @command{@value{AS}}. We cover the syntax expected in source files, including -notation for symbols, constants, and expressions; the directives that -@command{@value{AS}} understands; and of course how to invoke @command{@value{AS}}. - -@ifclear GENERIC -We also cover special features in the @value{TARGET} -configuration of @command{@value{AS}}, including assembler directives. -@end ifclear -@ifset GENERIC -This manual also describes some of the machine-dependent features of -various flavors of the assembler. -@end ifset - -@cindex machine instructions (not covered) -On the other hand, this manual is @emph{not} intended as an introduction -to programming in assembly language---let alone programming in general! -In a similar vein, we make no attempt to introduce the machine -architecture; we do @emph{not} describe the instruction set, standard -mnemonics, registers or addressing modes that are standard to a -particular architecture. -@ifset GENERIC -You may want to consult the manufacturer's -machine architecture manual for this information. -@end ifset -@ifclear GENERIC -@ifset H8/300 -For information on the H8/300 machine instruction set, see @cite{H8/300 -Series Programming Manual}. For the H8/300H, see @cite{H8/300H Series -Programming Manual} (Renesas). -@end ifset -@ifset SH -For information on the Renesas (formerly Hitachi) / SuperH SH machine instruction set, -see @cite{SH-Microcomputer User's Manual} (Renesas) or -@cite{SH-4 32-bit CPU Core Architecture} (SuperH) and -@cite{SuperH (SH) 64-Bit RISC Series} (SuperH). -@end ifset -@ifset Z8000 -For information on the Z8000 machine instruction set, see @cite{Z8000 CPU Technical Manual} -@end ifset -@end ifclear - -@c I think this is premature---doc@cygnus.com, 17jan1991 -@ignore -Throughout this manual, we assume that you are running @dfn{GNU}, -the portable operating system from the @dfn{Free Software -Foundation, Inc.}. This restricts our attention to certain kinds of -computer (in particular, the kinds of computers that @sc{gnu} can run on); -once this assumption is granted examples and definitions need less -qualification. - -@command{@value{AS}} is part of a team of programs that turn a high-level -human-readable series of instructions into a low-level -computer-readable series of instructions. Different versions of -@command{@value{AS}} are used for different kinds of computer. -@end ignore - -@c There used to be a section "Terminology" here, which defined -@c "contents", "byte", "word", and "long". Defining "word" to any -@c particular size is confusing when the .word directive may generate 16 -@c bits on one machine and 32 bits on another; in general, for the user -@c version of this manual, none of these terms seem essential to define. -@c They were used very little even in the former draft of the manual; -@c this draft makes an effort to avoid them (except in names of -@c directives). - -@node GNU Assembler -@section The GNU Assembler - -@c man begin DESCRIPTION - -@sc{gnu} @command{as} is really a family of assemblers. -@ifclear GENERIC -This manual describes @command{@value{AS}}, a member of that family which is -configured for the @value{TARGET} architectures. -@end ifclear -If you use (or have used) the @sc{gnu} assembler on one architecture, you -should find a fairly similar environment when you use it on another -architecture. Each version has much in common with the others, -including object file formats, most assembler directives (often called -@dfn{pseudo-ops}) and assembler syntax.@refill - -@cindex purpose of @sc{gnu} assembler -@command{@value{AS}} is primarily intended to assemble the output of the -@sc{gnu} C compiler @code{@value{GCC}} for use by the linker -@code{@value{LD}}. Nevertheless, we've tried to make @command{@value{AS}} -assemble correctly everything that other assemblers for the same -machine would assemble. -@ifset VAX -Any exceptions are documented explicitly (@pxref{Machine Dependencies}). -@end ifset -@ifset M680X0 -@c This remark should appear in generic version of manual; assumption -@c here is that generic version sets M680x0. -This doesn't mean @command{@value{AS}} always uses the same syntax as another -assembler for the same architecture; for example, we know of several -incompatible versions of 680x0 assembly language syntax. -@end ifset - -@c man end - -Unlike older assemblers, @command{@value{AS}} is designed to assemble a source -program in one pass of the source file. This has a subtle impact on the -@kbd{.org} directive (@pxref{Org,,@code{.org}}). - -@node Object Formats -@section Object File Formats - -@cindex object file format -The @sc{gnu} assembler can be configured to produce several alternative -object file formats. For the most part, this does not affect how you -write assembly language programs; but directives for debugging symbols -are typically different in different file formats. @xref{Symbol -Attributes,,Symbol Attributes}. -@ifclear GENERIC -@ifclear MULTI-OBJ -For the @value{TARGET} target, @command{@value{AS}} is configured to produce -@value{OBJ-NAME} format object files. -@end ifclear -@c The following should exhaust all configs that set MULTI-OBJ, ideally -@ifset I960 -On the @value{TARGET}, @command{@value{AS}} can be configured to produce either -@code{b.out} or COFF format object files. -@end ifset -@ifset HPPA -On the @value{TARGET}, @command{@value{AS}} can be configured to produce either -SOM or ELF format object files. -@end ifset -@end ifclear - -@node Command Line -@section Command Line - -@cindex command line conventions - -After the program name @command{@value{AS}}, the command line may contain -options and file names. Options may appear in any order, and may be -before, after, or between file names. The order of file names is -significant. - -@cindex standard input, as input file -@kindex -- -@file{--} (two hyphens) by itself names the standard input file -explicitly, as one of the files for @command{@value{AS}} to assemble. - -@cindex options, command line -Except for @samp{--} any command line argument that begins with a -hyphen (@samp{-}) is an option. Each option changes the behavior of -@command{@value{AS}}. No option changes the way another option works. An -option is a @samp{-} followed by one or more letters; the case of -the letter is important. All options are optional. - -Some options expect exactly one file name to follow them. The file -name may either immediately follow the option's letter (compatible -with older assemblers) or it may be the next command argument (@sc{gnu} -standard). These two command lines are equivalent: - -@smallexample -@value{AS} -o my-object-file.o mumble.s -@value{AS} -omy-object-file.o mumble.s -@end smallexample - -@node Input Files -@section Input Files - -@cindex input -@cindex source program -@cindex files, input -We use the phrase @dfn{source program}, abbreviated @dfn{source}, to -describe the program input to one run of @command{@value{AS}}. The program may -be in one or more files; how the source is partitioned into files -doesn't change the meaning of the source. - -@c I added "con" prefix to "catenation" just to prove I can overcome my -@c APL training... doc@cygnus.com -The source program is a concatenation of the text in all the files, in the -order specified. - -@c man begin DESCRIPTION -Each time you run @command{@value{AS}} it assembles exactly one source -program. The source program is made up of one or more files. -(The standard input is also a file.) - -You give @command{@value{AS}} a command line that has zero or more input file -names. The input files are read (from left file name to right). A -command line argument (in any position) that has no special meaning -is taken to be an input file name. - -If you give @command{@value{AS}} no file names it attempts to read one input file -from the @command{@value{AS}} standard input, which is normally your terminal. You -may have to type @key{ctl-D} to tell @command{@value{AS}} there is no more program -to assemble. - -Use @samp{--} if you need to explicitly name the standard input file -in your command line. - -If the source is empty, @command{@value{AS}} produces a small, empty object -file. - -@c man end - -@subheading Filenames and Line-numbers - -@cindex input file linenumbers -@cindex line numbers, in input files -There are two ways of locating a line in the input file (or files) and -either may be used in reporting error messages. One way refers to a line -number in a physical file; the other refers to a line number in a -``logical'' file. @xref{Errors, ,Error and Warning Messages}. - -@dfn{Physical files} are those files named in the command line given -to @command{@value{AS}}. - -@dfn{Logical files} are simply names declared explicitly by assembler -directives; they bear no relation to physical files. Logical file names help -error messages reflect the original source file, when @command{@value{AS}} source -is itself synthesized from other files. @command{@value{AS}} understands the -@samp{#} directives emitted by the @code{@value{GCC}} preprocessor. See also -@ref{File,,@code{.file}}. - -@node Object -@section Output (Object) File - -@cindex object file -@cindex output file -@kindex a.out -@kindex .o -Every time you run @command{@value{AS}} it produces an output file, which is -your assembly language program translated into numbers. This file -is the object file. Its default name is -@ifclear BOUT -@code{a.out}. -@end ifclear -@ifset BOUT -@ifset GENERIC -@code{a.out}, or -@end ifset -@code{b.out} when @command{@value{AS}} is configured for the Intel 80960. -@end ifset -You can give it another name by using the @option{-o} option. Conventionally, -object file names end with @file{.o}. The default name is used for historical -reasons: older assemblers were capable of assembling self-contained programs -directly into a runnable program. (For some formats, this isn't currently -possible, but it can be done for the @code{a.out} format.) - -@cindex linker -@kindex ld -The object file is meant for input to the linker @code{@value{LD}}. It contains -assembled program code, information to help @code{@value{LD}} integrate -the assembled program into a runnable file, and (optionally) symbolic -information for the debugger. - -@c link above to some info file(s) like the description of a.out. -@c don't forget to describe @sc{gnu} info as well as Unix lossage. - -@node Errors -@section Error and Warning Messages - -@c man begin DESCRIPTION - -@cindex error messages -@cindex warning messages -@cindex messages from assembler -@command{@value{AS}} may write warnings and error messages to the standard error -file (usually your terminal). This should not happen when a compiler -runs @command{@value{AS}} automatically. Warnings report an assumption made so -that @command{@value{AS}} could keep assembling a flawed program; errors report a -grave problem that stops the assembly. - -@c man end - -@cindex format of warning messages -Warning messages have the format - -@smallexample -file_name:@b{NNN}:Warning Message Text -@end smallexample - -@noindent -@cindex line numbers, in warnings/errors -(where @b{NNN} is a line number). If a logical file name has been given -(@pxref{File,,@code{.file}}) it is used for the filename, otherwise the name of -the current input file is used. If a logical line number was given -@ifset GENERIC -(@pxref{Line,,@code{.line}}) -@end ifset -then it is used to calculate the number printed, -otherwise the actual line in the current source file is printed. The -message text is intended to be self explanatory (in the grand Unix -tradition). - -@cindex format of error messages -Error messages have the format -@smallexample -file_name:@b{NNN}:FATAL:Error Message Text -@end smallexample -The file name and line number are derived as for warning -messages. The actual message text may be rather less explanatory -because many of them aren't supposed to happen. - -@node Invoking -@chapter Command-Line Options - -@cindex options, all versions of assembler -This chapter describes command-line options available in @emph{all} -versions of the @sc{gnu} assembler; see @ref{Machine Dependencies}, -for options specific -@ifclear GENERIC -to the @value{TARGET} target. -@end ifclear -@ifset GENERIC -to particular machine architectures. -@end ifset - -@c man begin DESCRIPTION - -If you are invoking @command{@value{AS}} via the @sc{gnu} C compiler, -you can use the @samp{-Wa} option to pass arguments through to the assembler. -The assembler arguments must be separated from each other (and the @samp{-Wa}) -by commas. For example: - -@smallexample -gcc -c -g -O -Wa,-alh,-L file.c -@end smallexample - -@noindent -This passes two options to the assembler: @samp{-alh} (emit a listing to -standard output with high-level and assembly source) and @samp{-L} (retain -local symbols in the symbol table). - -Usually you do not need to use this @samp{-Wa} mechanism, since many compiler -command-line options are automatically passed to the assembler by the compiler. -(You can call the @sc{gnu} compiler driver with the @samp{-v} option to see -precisely what options it passes to each compilation pass, including the -assembler.) - -@c man end - -@menu -* a:: -a[cdghlns] enable listings -* alternate:: --alternate enable alternate macro syntax -* D:: -D for compatibility -* f:: -f to work faster -* I:: -I for .include search path -@ifclear DIFF-TBL-KLUGE -* K:: -K for compatibility -@end ifclear -@ifset DIFF-TBL-KLUGE -* K:: -K for difference tables -@end ifset - -* L:: -L to retain local symbols -* listing:: --listing-XXX to configure listing output -* M:: -M or --mri to assemble in MRI compatibility mode -* MD:: --MD for dependency tracking -* o:: -o to name the object file -* R:: -R to join data and text sections -* statistics:: --statistics to see statistics about assembly -* traditional-format:: --traditional-format for compatible output -* v:: -v to announce version -* W:: -W, --no-warn, --warn, --fatal-warnings to control warnings -* Z:: -Z to make object file even after errors -@end menu - -@node a -@section Enable Listings: @option{-a[cdghlns]} - -@kindex -a -@kindex -ac -@kindex -ad -@kindex -ag -@kindex -ah -@kindex -al -@kindex -an -@kindex -as -@cindex listings, enabling -@cindex assembly listings, enabling - -These options enable listing output from the assembler. By itself, -@samp{-a} requests high-level, assembly, and symbols listing. -You can use other letters to select specific options for the list: -@samp{-ah} requests a high-level language listing, -@samp{-al} requests an output-program assembly listing, and -@samp{-as} requests a symbol table listing. -High-level listings require that a compiler debugging option like -@samp{-g} be used, and that assembly listings (@samp{-al}) be requested -also. - -Use the @samp{-ag} option to print a first section with general assembly -information, like @value{AS} version, switches passed, or time stamp. - -Use the @samp{-ac} option to omit false conditionals from a listing. Any lines -which are not assembled because of a false @code{.if} (or @code{.ifdef}, or any -other conditional), or a true @code{.if} followed by an @code{.else}, will be -omitted from the listing. - -Use the @samp{-ad} option to omit debugging directives from the -listing. - -Once you have specified one of these options, you can further control -listing output and its appearance using the directives @code{.list}, -@code{.nolist}, @code{.psize}, @code{.eject}, @code{.title}, and -@code{.sbttl}. -The @samp{-an} option turns off all forms processing. -If you do not request listing output with one of the @samp{-a} options, the -listing-control directives have no effect. - -The letters after @samp{-a} may be combined into one option, -@emph{e.g.}, @samp{-aln}. - -Note if the assembler source is coming from the standard input (e.g., -because it -is being created by @code{@value{GCC}} and the @samp{-pipe} command line switch -is being used) then the listing will not contain any comments or preprocessor -directives. This is because the listing code buffers input source lines from -stdin only after they have been preprocessed by the assembler. This reduces -memory usage and makes the code more efficient. - -@node alternate -@section @option{--alternate} - -@kindex --alternate -Begin in alternate macro mode, see @ref{Altmacro,,@code{.altmacro}}. - -@node D -@section @option{-D} - -@kindex -D -This option has no effect whatsoever, but it is accepted to make it more -likely that scripts written for other assemblers also work with -@command{@value{AS}}. - -@node f -@section Work Faster: @option{-f} - -@kindex -f -@cindex trusted compiler -@cindex faster processing (@option{-f}) -@samp{-f} should only be used when assembling programs written by a -(trusted) compiler. @samp{-f} stops the assembler from doing whitespace -and comment preprocessing on -the input file(s) before assembling them. @xref{Preprocessing, -,Preprocessing}. - -@quotation -@emph{Warning:} if you use @samp{-f} when the files actually need to be -preprocessed (if they contain comments, for example), @command{@value{AS}} does -not work correctly. -@end quotation - -@node I -@section @code{.include} Search Path: @option{-I} @var{path} - -@kindex -I @var{path} -@cindex paths for @code{.include} -@cindex search path for @code{.include} -@cindex @code{include} directive search path -Use this option to add a @var{path} to the list of directories -@command{@value{AS}} searches for files specified in @code{.include} -directives (@pxref{Include,,@code{.include}}). You may use @option{-I} as -many times as necessary to include a variety of paths. The current -working directory is always searched first; after that, @command{@value{AS}} -searches any @samp{-I} directories in the same order as they were -specified (left to right) on the command line. - -@node K -@section Difference Tables: @option{-K} - -@kindex -K -@ifclear DIFF-TBL-KLUGE -On the @value{TARGET} family, this option is allowed, but has no effect. It is -permitted for compatibility with the @sc{gnu} assembler on other platforms, -where it can be used to warn when the assembler alters the machine code -generated for @samp{.word} directives in difference tables. The @value{TARGET} -family does not have the addressing limitations that sometimes lead to this -alteration on other platforms. -@end ifclear - -@ifset DIFF-TBL-KLUGE -@cindex difference tables, warning -@cindex warning for altered difference tables -@command{@value{AS}} sometimes alters the code emitted for directives of the -form @samp{.word @var{sym1}-@var{sym2}}. @xref{Word,,@code{.word}}. -You can use the @samp{-K} option if you want a warning issued when this -is done. -@end ifset - -@node L -@section Include Local Symbols: @option{-L} - -@kindex -L -@cindex local symbols, retaining in output -Symbols beginning with system-specific local label prefixes, typically -@samp{.L} for ELF systems or @samp{L} for traditional a.out systems, are -called @dfn{local symbols}. @xref{Symbol Names}. Normally you do not see -such symbols when debugging, because they are intended for the use of -programs (like compilers) that compose assembler programs, not for your -notice. Normally both @command{@value{AS}} and @code{@value{LD}} discard -such symbols, so you do not normally debug with them. - -This option tells @command{@value{AS}} to retain those local symbols -in the object file. Usually if you do this you also tell the linker -@code{@value{LD}} to preserve those symbols. - -@node listing -@section Configuring listing output: @option{--listing} - -The listing feature of the assembler can be enabled via the command line switch -@samp{-a} (@pxref{a}). This feature combines the input source file(s) with a -hex dump of the corresponding locations in the output object file, and displays -them as a listing file. The format of this listing can be controlled by -directives inside the assembler source (i.e., @code{.list} (@pxref{List}), -@code{.title} (@pxref{Title}), @code{.sbttl} (@pxref{Sbttl}), -@code{.psize} (@pxref{Psize}), and -@code{.eject} (@pxref{Eject}) and also by the following switches: - -@table @gcctabopt -@item --listing-lhs-width=@samp{number} -@kindex --listing-lhs-width -@cindex Width of first line disassembly output -Sets the maximum width, in words, of the first line of the hex byte dump. This -dump appears on the left hand side of the listing output. - -@item --listing-lhs-width2=@samp{number} -@kindex --listing-lhs-width2 -@cindex Width of continuation lines of disassembly output -Sets the maximum width, in words, of any further lines of the hex byte dump for -a given input source line. If this value is not specified, it defaults to being -the same as the value specified for @samp{--listing-lhs-width}. If neither -switch is used the default is to one. - -@item --listing-rhs-width=@samp{number} -@kindex --listing-rhs-width -@cindex Width of source line output -Sets the maximum width, in characters, of the source line that is displayed -alongside the hex dump. The default value for this parameter is 100. The -source line is displayed on the right hand side of the listing output. - -@item --listing-cont-lines=@samp{number} -@kindex --listing-cont-lines -@cindex Maximum number of continuation lines -Sets the maximum number of continuation lines of hex dump that will be -displayed for a given single line of source input. The default value is 4. -@end table - -@node M -@section Assemble in MRI Compatibility Mode: @option{-M} - -@kindex -M -@cindex MRI compatibility mode -The @option{-M} or @option{--mri} option selects MRI compatibility mode. This -changes the syntax and pseudo-op handling of @command{@value{AS}} to make it -compatible with the @code{ASM68K} or the @code{ASM960} (depending upon the -configured target) assembler from Microtec Research. The exact nature of the -MRI syntax will not be documented here; see the MRI manuals for more -information. Note in particular that the handling of macros and macro -arguments is somewhat different. The purpose of this option is to permit -assembling existing MRI assembler code using @command{@value{AS}}. - -The MRI compatibility is not complete. Certain operations of the MRI assembler -depend upon its object file format, and can not be supported using other object -file formats. Supporting these would require enhancing each object file format -individually. These are: - -@itemize @bullet -@item global symbols in common section - -The m68k MRI assembler supports common sections which are merged by the linker. -Other object file formats do not support this. @command{@value{AS}} handles -common sections by treating them as a single common symbol. It permits local -symbols to be defined within a common section, but it can not support global -symbols, since it has no way to describe them. - -@item complex relocations - -The MRI assemblers support relocations against a negated section address, and -relocations which combine the start addresses of two or more sections. These -are not support by other object file formats. - -@item @code{END} pseudo-op specifying start address - -The MRI @code{END} pseudo-op permits the specification of a start address. -This is not supported by other object file formats. The start address may -instead be specified using the @option{-e} option to the linker, or in a linker -script. - -@item @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops - -The MRI @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops assign a module -name to the output file. This is not supported by other object file formats. - -@item @code{ORG} pseudo-op - -The m68k MRI @code{ORG} pseudo-op begins an absolute section at a given -address. This differs from the usual @command{@value{AS}} @code{.org} pseudo-op, -which changes the location within the current section. Absolute sections are -not supported by other object file formats. The address of a section may be -assigned within a linker script. -@end itemize - -There are some other features of the MRI assembler which are not supported by -@command{@value{AS}}, typically either because they are difficult or because they -seem of little consequence. Some of these may be supported in future releases. - -@itemize @bullet - -@item EBCDIC strings - -EBCDIC strings are not supported. - -@item packed binary coded decimal - -Packed binary coded decimal is not supported. This means that the @code{DC.P} -and @code{DCB.P} pseudo-ops are not supported. - -@item @code{FEQU} pseudo-op - -The m68k @code{FEQU} pseudo-op is not supported. - -@item @code{NOOBJ} pseudo-op - -The m68k @code{NOOBJ} pseudo-op is not supported. - -@item @code{OPT} branch control options - -The m68k @code{OPT} branch control options---@code{B}, @code{BRS}, @code{BRB}, -@code{BRL}, and @code{BRW}---are ignored. @command{@value{AS}} automatically -relaxes all branches, whether forward or backward, to an appropriate size, so -these options serve no purpose. - -@item @code{OPT} list control options - -The following m68k @code{OPT} list control options are ignored: @code{C}, -@code{CEX}, @code{CL}, @code{CRE}, @code{E}, @code{G}, @code{I}, @code{M}, -@code{MEX}, @code{MC}, @code{MD}, @code{X}. - -@item other @code{OPT} options - -The following m68k @code{OPT} options are ignored: @code{NEST}, @code{O}, -@code{OLD}, @code{OP}, @code{P}, @code{PCO}, @code{PCR}, @code{PCS}, @code{R}. - -@item @code{OPT} @code{D} option is default - -The m68k @code{OPT} @code{D} option is the default, unlike the MRI assembler. -@code{OPT NOD} may be used to turn it off. - -@item @code{XREF} pseudo-op. - -The m68k @code{XREF} pseudo-op is ignored. - -@item @code{.debug} pseudo-op - -The i960 @code{.debug} pseudo-op is not supported. - -@item @code{.extended} pseudo-op - -The i960 @code{.extended} pseudo-op is not supported. - -@item @code{.list} pseudo-op. - -The various options of the i960 @code{.list} pseudo-op are not supported. - -@item @code{.optimize} pseudo-op - -The i960 @code{.optimize} pseudo-op is not supported. - -@item @code{.output} pseudo-op - -The i960 @code{.output} pseudo-op is not supported. - -@item @code{.setreal} pseudo-op - -The i960 @code{.setreal} pseudo-op is not supported. - -@end itemize - -@node MD -@section Dependency Tracking: @option{--MD} - -@kindex --MD -@cindex dependency tracking -@cindex make rules - -@command{@value{AS}} can generate a dependency file for the file it creates. This -file consists of a single rule suitable for @code{make} describing the -dependencies of the main source file. - -The rule is written to the file named in its argument. - -This feature is used in the automatic updating of makefiles. - -@node o -@section Name the Object File: @option{-o} - -@kindex -o -@cindex naming object file -@cindex object file name -There is always one object file output when you run @command{@value{AS}}. By -default it has the name -@ifset GENERIC -@ifset I960 -@file{a.out} (or @file{b.out}, for Intel 960 targets only). -@end ifset -@ifclear I960 -@file{a.out}. -@end ifclear -@end ifset -@ifclear GENERIC -@ifset I960 -@file{b.out}. -@end ifset -@ifclear I960 -@file{a.out}. -@end ifclear -@end ifclear -You use this option (which takes exactly one filename) to give the -object file a different name. - -Whatever the object file is called, @command{@value{AS}} overwrites any -existing file of the same name. - -@node R -@section Join Data and Text Sections: @option{-R} - -@kindex -R -@cindex data and text sections, joining -@cindex text and data sections, joining -@cindex joining text and data sections -@cindex merging text and data sections -@option{-R} tells @command{@value{AS}} to write the object file as if all -data-section data lives in the text section. This is only done at -the very last moment: your binary data are the same, but data -section parts are relocated differently. The data section part of -your object file is zero bytes long because all its bytes are -appended to the text section. (@xref{Sections,,Sections and Relocation}.) - -When you specify @option{-R} it would be possible to generate shorter -address displacements (because we do not have to cross between text and -data section). We refrain from doing this simply for compatibility with -older versions of @command{@value{AS}}. In future, @option{-R} may work this way. - -@ifset COFF-ELF -When @command{@value{AS}} is configured for COFF or ELF output, -this option is only useful if you use sections named @samp{.text} and -@samp{.data}. -@end ifset - -@ifset HPPA -@option{-R} is not supported for any of the HPPA targets. Using -@option{-R} generates a warning from @command{@value{AS}}. -@end ifset - -@node statistics -@section Display Assembly Statistics: @option{--statistics} - -@kindex --statistics -@cindex statistics, about assembly -@cindex time, total for assembly -@cindex space used, maximum for assembly -Use @samp{--statistics} to display two statistics about the resources used by -@command{@value{AS}}: the maximum amount of space allocated during the assembly -(in bytes), and the total execution time taken for the assembly (in @sc{cpu} -seconds). - -@node traditional-format -@section Compatible Output: @option{--traditional-format} - -@kindex --traditional-format -For some targets, the output of @command{@value{AS}} is different in some ways -from the output of some existing assembler. This switch requests -@command{@value{AS}} to use the traditional format instead. - -For example, it disables the exception frame optimizations which -@command{@value{AS}} normally does by default on @code{@value{GCC}} output. - -@node v -@section Announce Version: @option{-v} - -@kindex -v -@kindex -version -@cindex assembler version -@cindex version of assembler -You can find out what version of as is running by including the -option @samp{-v} (which you can also spell as @samp{-version}) on the -command line. - -@node W -@section Control Warnings: @option{-W}, @option{--warn}, @option{--no-warn}, @option{--fatal-warnings} - -@command{@value{AS}} should never give a warning or error message when -assembling compiler output. But programs written by people often -cause @command{@value{AS}} to give a warning that a particular assumption was -made. All such warnings are directed to the standard error file. - -@kindex -W -@kindex --no-warn -@cindex suppressing warnings -@cindex warnings, suppressing -If you use the @option{-W} and @option{--no-warn} options, no warnings are issued. -This only affects the warning messages: it does not change any particular of -how @command{@value{AS}} assembles your file. Errors, which stop the assembly, -are still reported. - -@kindex --fatal-warnings -@cindex errors, caused by warnings -@cindex warnings, causing error -If you use the @option{--fatal-warnings} option, @command{@value{AS}} considers -files that generate warnings to be in error. - -@kindex --warn -@cindex warnings, switching on -You can switch these options off again by specifying @option{--warn}, which -causes warnings to be output as usual. - -@node Z -@section Generate Object File in Spite of Errors: @option{-Z} -@cindex object file, after errors -@cindex errors, continuing after -After an error message, @command{@value{AS}} normally produces no output. If for -some reason you are interested in object file output even after -@command{@value{AS}} gives an error message on your program, use the @samp{-Z} -option. If there are any errors, @command{@value{AS}} continues anyways, and -writes an object file after a final warning message of the form @samp{@var{n} -errors, @var{m} warnings, generating bad object file.} - -@node Syntax -@chapter Syntax - -@cindex machine-independent syntax -@cindex syntax, machine-independent -This chapter describes the machine-independent syntax allowed in a -source file. @command{@value{AS}} syntax is similar to what many other -assemblers use; it is inspired by the BSD 4.2 -@ifclear VAX -assembler. -@end ifclear -@ifset VAX -assembler, except that @command{@value{AS}} does not assemble Vax bit-fields. -@end ifset - -@menu -* Preprocessing:: Preprocessing -* Whitespace:: Whitespace -* Comments:: Comments -* Symbol Intro:: Symbols -* Statements:: Statements -* Constants:: Constants -@end menu - -@node Preprocessing -@section Preprocessing - -@cindex preprocessing -The @command{@value{AS}} internal preprocessor: -@itemize @bullet -@cindex whitespace, removed by preprocessor -@item -adjusts and removes extra whitespace. It leaves one space or tab before -the keywords on a line, and turns any other whitespace on the line into -a single space. - -@cindex comments, removed by preprocessor -@item -removes all comments, replacing them with a single space, or an -appropriate number of newlines. - -@cindex constants, converted by preprocessor -@item -converts character constants into the appropriate numeric values. -@end itemize - -It does not do macro processing, include file handling, or -anything else you may get from your C compiler's preprocessor. You can -do include file processing with the @code{.include} directive -(@pxref{Include,,@code{.include}}). You can use the @sc{gnu} C compiler driver -to get other ``CPP'' style preprocessing by giving the input file a -@samp{.S} suffix. @xref{Overall Options, ,Options Controlling the Kind of -Output, gcc.info, Using GNU CC}. - -Excess whitespace, comments, and character constants -cannot be used in the portions of the input text that are not -preprocessed. - -@cindex turning preprocessing on and off -@cindex preprocessing, turning on and off -@kindex #NO_APP -@kindex #APP -If the first line of an input file is @code{#NO_APP} or if you use the -@samp{-f} option, whitespace and comments are not removed from the input file. -Within an input file, you can ask for whitespace and comment removal in -specific portions of the by putting a line that says @code{#APP} before the -text that may contain whitespace or comments, and putting a line that says -@code{#NO_APP} after this text. This feature is mainly intend to support -@code{asm} statements in compilers whose output is otherwise free of comments -and whitespace. - -@node Whitespace -@section Whitespace - -@cindex whitespace -@dfn{Whitespace} is one or more blanks or tabs, in any order. -Whitespace is used to separate symbols, and to make programs neater for -people to read. Unless within character constants -(@pxref{Characters,,Character Constants}), any whitespace means the same -as exactly one space. - -@node Comments -@section Comments - -@cindex comments -There are two ways of rendering comments to @command{@value{AS}}. In both -cases the comment is equivalent to one space. - -Anything from @samp{/*} through the next @samp{*/} is a comment. -This means you may not nest these comments. - -@smallexample -/* - The only way to include a newline ('\n') in a comment - is to use this sort of comment. -*/ - -/* This sort of comment does not nest. */ -@end smallexample - -@cindex line comment character -Anything from a @dfn{line comment} character up to the next newline is -considered a comment and is ignored. The line comment character is target -specific, and some targets multiple comment characters. Some targets also have -line comment characters that only work if they are the first character on a -line. Some targets use a sequence of two characters to introduce a line -comment. Some targets can also change their line comment characters depending -upon command line options that have been used. For more details see the -@emph{Syntax} section in the documentation for individual targets. - -If the line comment character is the hash sign (@samp{#}) then it still has the -special ability to enable and disable preprocessing (@pxref{Preprocessing}) and -to specify logical line numbers: - -@kindex # -@cindex lines starting with @code{#} -@cindex logical line numbers -To be compatible with past assemblers, lines that begin with @samp{#} have a -special interpretation. Following the @samp{#} should be an absolute -expression (@pxref{Expressions}): the logical line number of the @emph{next} -line. Then a string (@pxref{Strings, ,Strings}) is allowed: if present it is a -new logical file name. The rest of the line, if any, should be whitespace. - -If the first non-whitespace characters on the line are not numeric, -the line is ignored. (Just like a comment.) - -@smallexample - # This is an ordinary comment. -# 42-6 "new_file_name" # New logical file name - # This is logical line # 36. -@end smallexample -This feature is deprecated, and may disappear from future versions -of @command{@value{AS}}. - -@node Symbol Intro -@section Symbols - -@cindex characters used in symbols -@ifclear SPECIAL-SYMS -A @dfn{symbol} is one or more characters chosen from the set of all -letters (both upper and lower case), digits and the three characters -@samp{_.$}. -@end ifclear -@ifset SPECIAL-SYMS -@ifclear GENERIC -@ifset H8 -A @dfn{symbol} is one or more characters chosen from the set of all -letters (both upper and lower case), digits and the three characters -@samp{._$}. (Save that, on the H8/300 only, you may not use @samp{$} in -symbol names.) -@end ifset -@end ifclear -@end ifset -@ifset GENERIC -On most machines, you can also use @code{$} in symbol names; exceptions -are noted in @ref{Machine Dependencies}. -@end ifset -No symbol may begin with a digit. Case is significant. -There is no length limit: all characters are significant. Symbols are -delimited by characters not in that set, or by the beginning of a file -(since the source program must end with a newline, the end of a file is -not a possible symbol delimiter). @xref{Symbols}. -@cindex length of symbols - -@node Statements -@section Statements - -@cindex statements, structure of -@cindex line separator character -@cindex statement separator character - -A @dfn{statement} ends at a newline character (@samp{\n}) or a -@dfn{line separator character}. The line separator character is target -specific and described in the @emph{Syntax} section of each -target's documentation. Not all targets support a line separator character. -The newline or line separator character is considered to be part of the -preceding statement. Newlines and separators within character constants are an -exception: they do not end statements. - -@cindex newline, required at file end -@cindex EOF, newline must precede -It is an error to end any statement with end-of-file: the last -character of any input file should be a newline.@refill - -An empty statement is allowed, and may include whitespace. It is ignored. - -@cindex instructions and directives -@cindex directives and instructions -@c "key symbol" is not used elsewhere in the document; seems pedantic to -@c @defn{} it in that case, as was done previously... doc@cygnus.com, -@c 13feb91. -A statement begins with zero or more labels, optionally followed by a -key symbol which determines what kind of statement it is. The key -symbol determines the syntax of the rest of the statement. If the -symbol begins with a dot @samp{.} then the statement is an assembler -directive: typically valid for any computer. If the symbol begins with -a letter the statement is an assembly language @dfn{instruction}: it -assembles into a machine language instruction. -@ifset GENERIC -Different versions of @command{@value{AS}} for different computers -recognize different instructions. In fact, the same symbol may -represent a different instruction in a different computer's assembly -language.@refill -@end ifset - -@cindex @code{:} (label) -@cindex label (@code{:}) -A label is a symbol immediately followed by a colon (@code{:}). -Whitespace before a label or after a colon is permitted, but you may not -have whitespace between a label's symbol and its colon. @xref{Labels}. - -@ifset HPPA -For HPPA targets, labels need not be immediately followed by a colon, but -the definition of a label must begin in column zero. This also implies that -only one label may be defined on each line. -@end ifset - -@smallexample -label: .directive followed by something -another_label: # This is an empty statement. - instruction operand_1, operand_2, @dots{} -@end smallexample - -@node Constants -@section Constants - -@cindex constants -A constant is a number, written so that its value is known by -inspection, without knowing any context. Like this: -@smallexample -@group -.byte 74, 0112, 092, 0x4A, 0X4a, 'J, '\J # All the same value. -.ascii "Ring the bell\7" # A string constant. -.octa 0x123456789abcdef0123456789ABCDEF0 # A bignum. -.float 0f-314159265358979323846264338327\ -95028841971.693993751E-40 # - pi, a flonum. -@end group -@end smallexample - -@menu -* Characters:: Character Constants -* Numbers:: Number Constants -@end menu - -@node Characters -@subsection Character Constants - -@cindex character constants -@cindex constants, character -There are two kinds of character constants. A @dfn{character} stands -for one character in one byte and its value may be used in -numeric expressions. String constants (properly called string -@emph{literals}) are potentially many bytes and their values may not be -used in arithmetic expressions. - -@menu -* Strings:: Strings -* Chars:: Characters -@end menu - -@node Strings -@subsubsection Strings - -@cindex string constants -@cindex constants, string -A @dfn{string} is written between double-quotes. It may contain -double-quotes or null characters. The way to get special characters -into a string is to @dfn{escape} these characters: precede them with -a backslash @samp{\} character. For example @samp{\\} represents -one backslash: the first @code{\} is an escape which tells -@command{@value{AS}} to interpret the second character literally as a backslash -(which prevents @command{@value{AS}} from recognizing the second @code{\} as an -escape character). The complete list of escapes follows. - -@cindex escape codes, character -@cindex character escape codes -@table @kbd -@c @item \a -@c Mnemonic for ACKnowledge; for ASCII this is octal code 007. -@c -@cindex @code{\b} (backspace character) -@cindex backspace (@code{\b}) -@item \b -Mnemonic for backspace; for ASCII this is octal code 010. - -@c @item \e -@c Mnemonic for EOText; for ASCII this is octal code 004. -@c -@cindex @code{\f} (formfeed character) -@cindex formfeed (@code{\f}) -@item \f -Mnemonic for FormFeed; for ASCII this is octal code 014. - -@cindex @code{\n} (newline character) -@cindex newline (@code{\n}) -@item \n -Mnemonic for newline; for ASCII this is octal code 012. - -@c @item \p -@c Mnemonic for prefix; for ASCII this is octal code 033, usually known as @code{escape}. -@c -@cindex @code{\r} (carriage return character) -@cindex carriage return (@code{\r}) -@item \r -Mnemonic for carriage-Return; for ASCII this is octal code 015. - -@c @item \s -@c Mnemonic for space; for ASCII this is octal code 040. Included for compliance with -@c other assemblers. -@c -@cindex @code{\t} (tab) -@cindex tab (@code{\t}) -@item \t -Mnemonic for horizontal Tab; for ASCII this is octal code 011. - -@c @item \v -@c Mnemonic for Vertical tab; for ASCII this is octal code 013. -@c @item \x @var{digit} @var{digit} @var{digit} -@c A hexadecimal character code. The numeric code is 3 hexadecimal digits. -@c -@cindex @code{\@var{ddd}} (octal character code) -@cindex octal character code (@code{\@var{ddd}}) -@item \ @var{digit} @var{digit} @var{digit} -An octal character code. The numeric code is 3 octal digits. -For compatibility with other Unix systems, 8 and 9 are accepted as digits: -for example, @code{\008} has the value 010, and @code{\009} the value 011. - -@cindex @code{\@var{xd...}} (hex character code) -@cindex hex character code (@code{\@var{xd...}}) -@item \@code{x} @var{hex-digits...} -A hex character code. All trailing hex digits are combined. Either upper or -lower case @code{x} works. - -@cindex @code{\\} (@samp{\} character) -@cindex backslash (@code{\\}) -@item \\ -Represents one @samp{\} character. - -@c @item \' -@c Represents one @samp{'} (accent acute) character. -@c This is needed in single character literals -@c (@xref{Characters,,Character Constants}.) to represent -@c a @samp{'}. -@c -@cindex @code{\"} (doublequote character) -@cindex doublequote (@code{\"}) -@item \" -Represents one @samp{"} character. Needed in strings to represent -this character, because an unescaped @samp{"} would end the string. - -@item \ @var{anything-else} -Any other character when escaped by @kbd{\} gives a warning, but -assembles as if the @samp{\} was not present. The idea is that if -you used an escape sequence you clearly didn't want the literal -interpretation of the following character. However @command{@value{AS}} has no -other interpretation, so @command{@value{AS}} knows it is giving you the wrong -code and warns you of the fact. -@end table - -Which characters are escapable, and what those escapes represent, -varies widely among assemblers. The current set is what we think -the BSD 4.2 assembler recognizes, and is a subset of what most C -compilers recognize. If you are in doubt, do not use an escape -sequence. - -@node Chars -@subsubsection Characters - -@cindex single character constant -@cindex character, single -@cindex constant, single character -A single character may be written as a single quote immediately -followed by that character. The same escapes apply to characters as -to strings. So if you want to write the character backslash, you -must write @kbd{'\\} where the first @code{\} escapes the second -@code{\}. As you can see, the quote is an acute accent, not a -grave accent. A newline -@ifclear GENERIC -@ifclear abnormal-separator -(or semicolon @samp{;}) -@end ifclear -@ifset abnormal-separator -@ifset H8 -(or dollar sign @samp{$}, for the H8/300; or semicolon @samp{;} for the -Renesas SH) -@end ifset -@end ifset -@end ifclear -immediately following an acute accent is taken as a literal character -and does not count as the end of a statement. The value of a character -constant in a numeric expression is the machine's byte-wide code for -that character. @command{@value{AS}} assumes your character code is ASCII: -@kbd{'A} means 65, @kbd{'B} means 66, and so on. @refill - -@node Numbers -@subsection Number Constants - -@cindex constants, number -@cindex number constants -@command{@value{AS}} distinguishes three kinds of numbers according to how they -are stored in the target machine. @emph{Integers} are numbers that -would fit into an @code{int} in the C language. @emph{Bignums} are -integers, but they are stored in more than 32 bits. @emph{Flonums} -are floating point numbers, described below. - -@menu -* Integers:: Integers -* Bignums:: Bignums -* Flonums:: Flonums -@ifclear GENERIC -@ifset I960 -* Bit Fields:: Bit Fields -@end ifset -@end ifclear -@end menu - -@node Integers -@subsubsection Integers -@cindex integers -@cindex constants, integer - -@cindex binary integers -@cindex integers, binary -A binary integer is @samp{0b} or @samp{0B} followed by zero or more of -the binary digits @samp{01}. - -@cindex octal integers -@cindex integers, octal -An octal integer is @samp{0} followed by zero or more of the octal -digits (@samp{01234567}). - -@cindex decimal integers -@cindex integers, decimal -A decimal integer starts with a non-zero digit followed by zero or -more digits (@samp{0123456789}). - -@cindex hexadecimal integers -@cindex integers, hexadecimal -A hexadecimal integer is @samp{0x} or @samp{0X} followed by one or -more hexadecimal digits chosen from @samp{0123456789abcdefABCDEF}. - -Integers have the usual values. To denote a negative integer, use -the prefix operator @samp{-} discussed under expressions -(@pxref{Prefix Ops,,Prefix Operators}). - -@node Bignums -@subsubsection Bignums - -@cindex bignums -@cindex constants, bignum -A @dfn{bignum} has the same syntax and semantics as an integer -except that the number (or its negative) takes more than 32 bits to -represent in binary. The distinction is made because in some places -integers are permitted while bignums are not. - -@node Flonums -@subsubsection Flonums -@cindex flonums -@cindex floating point numbers -@cindex constants, floating point - -@cindex precision, floating point -A @dfn{flonum} represents a floating point number. The translation is -indirect: a decimal floating point number from the text is converted by -@command{@value{AS}} to a generic binary floating point number of more than -sufficient precision. This generic floating point number is converted -to a particular computer's floating point format (or formats) by a -portion of @command{@value{AS}} specialized to that computer. - -A flonum is written by writing (in order) -@itemize @bullet -@item -The digit @samp{0}. -@ifset HPPA -(@samp{0} is optional on the HPPA.) -@end ifset - -@item -A letter, to tell @command{@value{AS}} the rest of the number is a flonum. -@ifset GENERIC -@kbd{e} is recommended. Case is not important. -@ignore -@c FIXME: verify if flonum syntax really this vague for most cases -(Any otherwise illegal letter works here, but that might be changed. Vax BSD -4.2 assembler seems to allow any of @samp{defghDEFGH}.) -@end ignore - -On the H8/300, Renesas / SuperH SH, -and AMD 29K architectures, the letter must be -one of the letters @samp{DFPRSX} (in upper or lower case). - -On the ARC, the letter must be one of the letters @samp{DFRS} -(in upper or lower case). - -On the Intel 960 architecture, the letter must be -one of the letters @samp{DFT} (in upper or lower case). - -On the HPPA architecture, the letter must be @samp{E} (upper case only). -@end ifset -@ifclear GENERIC -@ifset ARC -One of the letters @samp{DFRS} (in upper or lower case). -@end ifset -@ifset H8 -One of the letters @samp{DFPRSX} (in upper or lower case). -@end ifset -@ifset HPPA -The letter @samp{E} (upper case only). -@end ifset -@ifset I960 -One of the letters @samp{DFT} (in upper or lower case). -@end ifset -@end ifclear - -@item -An optional sign: either @samp{+} or @samp{-}. - -@item -An optional @dfn{integer part}: zero or more decimal digits. - -@item -An optional @dfn{fractional part}: @samp{.} followed by zero -or more decimal digits. - -@item -An optional exponent, consisting of: - -@itemize @bullet -@item -An @samp{E} or @samp{e}. -@c I can't find a config where "EXP_CHARS" is other than 'eE', but in -@c principle this can perfectly well be different on different targets. -@item -Optional sign: either @samp{+} or @samp{-}. -@item -One or more decimal digits. -@end itemize - -@end itemize - -At least one of the integer part or the fractional part must be -present. The floating point number has the usual base-10 value. - -@command{@value{AS}} does all processing using integers. Flonums are computed -independently of any floating point hardware in the computer running -@command{@value{AS}}. - -@ifclear GENERIC -@ifset I960 -@c Bit fields are written as a general facility but are also controlled -@c by a conditional-compilation flag---which is as of now (21mar91) -@c turned on only by the i960 config of GAS. -@node Bit Fields -@subsubsection Bit Fields - -@cindex bit fields -@cindex constants, bit field -You can also define numeric constants as @dfn{bit fields}. -Specify two numbers separated by a colon--- -@example -@var{mask}:@var{value} -@end example -@noindent -@command{@value{AS}} applies a bitwise @sc{and} between @var{mask} and -@var{value}. - -The resulting number is then packed -@ifset GENERIC -@c this conditional paren in case bit fields turned on elsewhere than 960 -(in host-dependent byte order) -@end ifset -into a field whose width depends on which assembler directive has the -bit-field as its argument. Overflow (a result from the bitwise and -requiring more binary digits to represent) is not an error; instead, -more constants are generated, of the specified width, beginning with the -least significant digits.@refill - -The directives @code{.byte}, @code{.hword}, @code{.int}, @code{.long}, -@code{.short}, and @code{.word} accept bit-field arguments. -@end ifset -@end ifclear - -@node Sections -@chapter Sections and Relocation -@cindex sections -@cindex relocation - -@menu -* Secs Background:: Background -* Ld Sections:: Linker Sections -* As Sections:: Assembler Internal Sections -* Sub-Sections:: Sub-Sections -* bss:: bss Section -@end menu - -@node Secs Background -@section Background - -Roughly, a section is a range of addresses, with no gaps; all data -``in'' those addresses is treated the same for some particular purpose. -For example there may be a ``read only'' section. - -@cindex linker, and assembler -@cindex assembler, and linker -The linker @code{@value{LD}} reads many object files (partial programs) and -combines their contents to form a runnable program. When @command{@value{AS}} -emits an object file, the partial program is assumed to start at address 0. -@code{@value{LD}} assigns the final addresses for the partial program, so that -different partial programs do not overlap. This is actually an -oversimplification, but it suffices to explain how @command{@value{AS}} uses -sections. - -@code{@value{LD}} moves blocks of bytes of your program to their run-time -addresses. These blocks slide to their run-time addresses as rigid -units; their length does not change and neither does the order of bytes -within them. Such a rigid unit is called a @emph{section}. Assigning -run-time addresses to sections is called @dfn{relocation}. It includes -the task of adjusting mentions of object-file addresses so they refer to -the proper run-time addresses. -@ifset H8 -For the H8/300, and for the Renesas / SuperH SH, -@command{@value{AS}} pads sections if needed to -ensure they end on a word (sixteen bit) boundary. -@end ifset - -@cindex standard assembler sections -An object file written by @command{@value{AS}} has at least three sections, any -of which may be empty. These are named @dfn{text}, @dfn{data} and -@dfn{bss} sections. - -@ifset COFF-ELF -@ifset GENERIC -When it generates COFF or ELF output, -@end ifset -@command{@value{AS}} can also generate whatever other named sections you specify -using the @samp{.section} directive (@pxref{Section,,@code{.section}}). -If you do not use any directives that place output in the @samp{.text} -or @samp{.data} sections, these sections still exist, but are empty. -@end ifset - -@ifset HPPA -@ifset GENERIC -When @command{@value{AS}} generates SOM or ELF output for the HPPA, -@end ifset -@command{@value{AS}} can also generate whatever other named sections you -specify using the @samp{.space} and @samp{.subspace} directives. See -@cite{HP9000 Series 800 Assembly Language Reference Manual} -(HP 92432-90001) for details on the @samp{.space} and @samp{.subspace} -assembler directives. - -@ifset SOM -Additionally, @command{@value{AS}} uses different names for the standard -text, data, and bss sections when generating SOM output. Program text -is placed into the @samp{$CODE$} section, data into @samp{$DATA$}, and -BSS into @samp{$BSS$}. -@end ifset -@end ifset - -Within the object file, the text section starts at address @code{0}, the -data section follows, and the bss section follows the data section. - -@ifset HPPA -When generating either SOM or ELF output files on the HPPA, the text -section starts at address @code{0}, the data section at address -@code{0x4000000}, and the bss section follows the data section. -@end ifset - -To let @code{@value{LD}} know which data changes when the sections are -relocated, and how to change that data, @command{@value{AS}} also writes to the -object file details of the relocation needed. To perform relocation -@code{@value{LD}} must know, each time an address in the object -file is mentioned: -@itemize @bullet -@item -Where in the object file is the beginning of this reference to -an address? -@item -How long (in bytes) is this reference? -@item -Which section does the address refer to? What is the numeric value of -@display -(@var{address}) @minus{} (@var{start-address of section})? -@end display -@item -Is the reference to an address ``Program-Counter relative''? -@end itemize - -@cindex addresses, format of -@cindex section-relative addressing -In fact, every address @command{@value{AS}} ever uses is expressed as -@display -(@var{section}) + (@var{offset into section}) -@end display -@noindent -Further, most expressions @command{@value{AS}} computes have this section-relative -nature. -@ifset SOM -(For some object formats, such as SOM for the HPPA, some expressions are -symbol-relative instead.) -@end ifset - -In this manual we use the notation @{@var{secname} @var{N}@} to mean ``offset -@var{N} into section @var{secname}.'' - -Apart from text, data and bss sections you need to know about the -@dfn{absolute} section. When @code{@value{LD}} mixes partial programs, -addresses in the absolute section remain unchanged. For example, address -@code{@{absolute 0@}} is ``relocated'' to run-time address 0 by -@code{@value{LD}}. Although the linker never arranges two partial programs' -data sections with overlapping addresses after linking, @emph{by definition} -their absolute sections must overlap. Address @code{@{absolute@ 239@}} in one -part of a program is always the same address when the program is running as -address @code{@{absolute@ 239@}} in any other part of the program. - -The idea of sections is extended to the @dfn{undefined} section. Any -address whose section is unknown at assembly time is by definition -rendered @{undefined @var{U}@}---where @var{U} is filled in later. -Since numbers are always defined, the only way to generate an undefined -address is to mention an undefined symbol. A reference to a named -common block would be such a symbol: its value is unknown at assembly -time so it has section @emph{undefined}. - -By analogy the word @emph{section} is used to describe groups of sections in -the linked program. @code{@value{LD}} puts all partial programs' text -sections in contiguous addresses in the linked program. It is -customary to refer to the @emph{text section} of a program, meaning all -the addresses of all partial programs' text sections. Likewise for -data and bss sections. - -Some sections are manipulated by @code{@value{LD}}; others are invented for -use of @command{@value{AS}} and have no meaning except during assembly. - -@node Ld Sections -@section Linker Sections -@code{@value{LD}} deals with just four kinds of sections, summarized below. - -@table @strong - -@ifset COFF-ELF -@cindex named sections -@cindex sections, named -@item named sections -@end ifset -@ifset aout-bout -@cindex text section -@cindex data section -@itemx text section -@itemx data section -@end ifset -These sections hold your program. @command{@value{AS}} and @code{@value{LD}} treat them as -separate but equal sections. Anything you can say of one section is -true of another. -@c @ifset aout-bout -When the program is running, however, it is -customary for the text section to be unalterable. The -text section is often shared among processes: it contains -instructions, constants and the like. The data section of a running -program is usually alterable: for example, C variables would be stored -in the data section. -@c @end ifset - -@cindex bss section -@item bss section -This section contains zeroed bytes when your program begins running. It -is used to hold uninitialized variables or common storage. The length of -each partial program's bss section is important, but because it starts -out containing zeroed bytes there is no need to store explicit zero -bytes in the object file. The bss section was invented to eliminate -those explicit zeros from object files. - -@cindex absolute section -@item absolute section -Address 0 of this section is always ``relocated'' to runtime address 0. -This is useful if you want to refer to an address that @code{@value{LD}} must -not change when relocating. In this sense we speak of absolute -addresses being ``unrelocatable'': they do not change during relocation. - -@cindex undefined section -@item undefined section -This ``section'' is a catch-all for address references to objects not in -the preceding sections. -@c FIXME: ref to some other doc on obj-file formats could go here. -@end table - -@cindex relocation example -An idealized example of three relocatable sections follows. -@ifset COFF-ELF -The example uses the traditional section names @samp{.text} and @samp{.data}. -@end ifset -Memory addresses are on the horizontal axis. - -@c TEXI2ROFF-KILL -@ifnottex -@c END TEXI2ROFF-KILL -@smallexample - +-----+----+--+ -partial program # 1: |ttttt|dddd|00| - +-----+----+--+ - - text data bss - seg. seg. seg. - - +---+---+---+ -partial program # 2: |TTT|DDD|000| - +---+---+---+ - - +--+---+-----+--+----+---+-----+~~ -linked program: | |TTT|ttttt| |dddd|DDD|00000| - +--+---+-----+--+----+---+-----+~~ - - addresses: 0 @dots{} -@end smallexample -@c TEXI2ROFF-KILL -@end ifnottex -@need 5000 -@tex -\bigskip -\line{\it Partial program \#1: \hfil} -\line{\ibox{2.5cm}{\tt text}\ibox{2cm}{\tt data}\ibox{1cm}{\tt bss}\hfil} -\line{\boxit{2.5cm}{\tt ttttt}\boxit{2cm}{\tt dddd}\boxit{1cm}{\tt 00}\hfil} - -\line{\it Partial program \#2: \hfil} -\line{\ibox{1cm}{\tt text}\ibox{1.5cm}{\tt data}\ibox{1cm}{\tt bss}\hfil} -\line{\boxit{1cm}{\tt TTT}\boxit{1.5cm}{\tt DDDD}\boxit{1cm}{\tt 000}\hfil} - -\line{\it linked program: \hfil} -\line{\ibox{.5cm}{}\ibox{1cm}{\tt text}\ibox{2.5cm}{}\ibox{.75cm}{}\ibox{2cm}{\tt data}\ibox{1.5cm}{}\ibox{2cm}{\tt bss}\hfil} -\line{\boxit{.5cm}{}\boxit{1cm}{\tt TTT}\boxit{2.5cm}{\tt -ttttt}\boxit{.75cm}{}\boxit{2cm}{\tt dddd}\boxit{1.5cm}{\tt -DDDD}\boxit{2cm}{\tt 00000}\ \dots\hfil} - -\line{\it addresses: \hfil} -\line{0\dots\hfil} - -@end tex -@c END TEXI2ROFF-KILL - -@node As Sections -@section Assembler Internal Sections - -@cindex internal assembler sections -@cindex sections in messages, internal -These sections are meant only for the internal use of @command{@value{AS}}. They -have no meaning at run-time. You do not really need to know about these -sections for most purposes; but they can be mentioned in @command{@value{AS}} -warning messages, so it might be helpful to have an idea of their -meanings to @command{@value{AS}}. These sections are used to permit the -value of every expression in your assembly language program to be a -section-relative address. - -@table @b -@cindex assembler internal logic error -@item ASSEMBLER-INTERNAL-LOGIC-ERROR! -An internal assembler logic error has been found. This means there is a -bug in the assembler. - -@cindex expr (internal section) -@item expr section -The assembler stores complex expression internally as combinations of -symbols. When it needs to represent an expression as a symbol, it puts -it in the expr section. -@c FIXME item debug -@c FIXME item transfer[t] vector preload -@c FIXME item transfer[t] vector postload -@c FIXME item register -@end table - -@node Sub-Sections -@section Sub-Sections - -@cindex numbered subsections -@cindex grouping data -@ifset aout-bout -Assembled bytes -@ifset COFF-ELF -conventionally -@end ifset -fall into two sections: text and data. -@end ifset -You may have separate groups of -@ifset GENERIC -data in named sections -@end ifset -@ifclear GENERIC -@ifclear aout-bout -data in named sections -@end ifclear -@ifset aout-bout -text or data -@end ifset -@end ifclear -that you want to end up near to each other in the object file, even though they -are not contiguous in the assembler source. @command{@value{AS}} allows you to -use @dfn{subsections} for this purpose. Within each section, there can be -numbered subsections with values from 0 to 8192. Objects assembled into the -same subsection go into the object file together with other objects in the same -subsection. For example, a compiler might want to store constants in the text -section, but might not want to have them interspersed with the program being -assembled. In this case, the compiler could issue a @samp{.text 0} before each -section of code being output, and a @samp{.text 1} before each group of -constants being output. - -Subsections are optional. If you do not use subsections, everything -goes in subsection number zero. - -@ifset GENERIC -Each subsection is zero-padded up to a multiple of four bytes. -(Subsections may be padded a different amount on different flavors -of @command{@value{AS}}.) -@end ifset -@ifclear GENERIC -@ifset H8 -On the H8/300 platform, each subsection is zero-padded to a word -boundary (two bytes). -The same is true on the Renesas SH. -@end ifset -@ifset I960 -@c FIXME section padding (alignment)? -@c Rich Pixley says padding here depends on target obj code format; that -@c doesn't seem particularly useful to say without further elaboration, -@c so for now I say nothing about it. If this is a generic BFD issue, -@c these paragraphs might need to vanish from this manual, and be -@c discussed in BFD chapter of binutils (or some such). -@end ifset -@end ifclear - -Subsections appear in your object file in numeric order, lowest numbered -to highest. (All this to be compatible with other people's assemblers.) -The object file contains no representation of subsections; @code{@value{LD}} and -other programs that manipulate object files see no trace of them. -They just see all your text subsections as a text section, and all your -data subsections as a data section. - -To specify which subsection you want subsequent statements assembled -into, use a numeric argument to specify it, in a @samp{.text -@var{expression}} or a @samp{.data @var{expression}} statement. -@ifset COFF -@ifset GENERIC -When generating COFF output, you -@end ifset -@ifclear GENERIC -You -@end ifclear -can also use an extra subsection -argument with arbitrary named sections: @samp{.section @var{name}, -@var{expression}}. -@end ifset -@ifset ELF -@ifset GENERIC -When generating ELF output, you -@end ifset -@ifclear GENERIC -You -@end ifclear -can also use the @code{.subsection} directive (@pxref{SubSection}) -to specify a subsection: @samp{.subsection @var{expression}}. -@end ifset -@var{Expression} should be an absolute expression -(@pxref{Expressions}). If you just say @samp{.text} then @samp{.text 0} -is assumed. Likewise @samp{.data} means @samp{.data 0}. Assembly -begins in @code{text 0}. For instance: -@smallexample -.text 0 # The default subsection is text 0 anyway. -.ascii "This lives in the first text subsection. *" -.text 1 -.ascii "But this lives in the second text subsection." -.data 0 -.ascii "This lives in the data section," -.ascii "in the first data subsection." -.text 0 -.ascii "This lives in the first text section," -.ascii "immediately following the asterisk (*)." -@end smallexample - -Each section has a @dfn{location counter} incremented by one for every byte -assembled into that section. Because subsections are merely a convenience -restricted to @command{@value{AS}} there is no concept of a subsection location -counter. There is no way to directly manipulate a location counter---but the -@code{.align} directive changes it, and any label definition captures its -current value. The location counter of the section where statements are being -assembled is said to be the @dfn{active} location counter. - -@node bss -@section bss Section - -@cindex bss section -@cindex common variable storage -The bss section is used for local common variable storage. -You may allocate address space in the bss section, but you may -not dictate data to load into it before your program executes. When -your program starts running, all the contents of the bss -section are zeroed bytes. - -The @code{.lcomm} pseudo-op defines a symbol in the bss section; see -@ref{Lcomm,,@code{.lcomm}}. - -The @code{.comm} pseudo-op may be used to declare a common symbol, which is -another form of uninitialized symbol; see @ref{Comm,,@code{.comm}}. - -@ifset GENERIC -When assembling for a target which supports multiple sections, such as ELF or -COFF, you may switch into the @code{.bss} section and define symbols as usual; -see @ref{Section,,@code{.section}}. You may only assemble zero values into the -section. Typically the section will only contain symbol definitions and -@code{.skip} directives (@pxref{Skip,,@code{.skip}}). -@end ifset - -@node Symbols -@chapter Symbols - -@cindex symbols -Symbols are a central concept: the programmer uses symbols to name -things, the linker uses symbols to link, and the debugger uses symbols -to debug. - -@quotation -@cindex debuggers, and symbol order -@emph{Warning:} @command{@value{AS}} does not place symbols in the object file in -the same order they were declared. This may break some debuggers. -@end quotation - -@menu -* Labels:: Labels -* Setting Symbols:: Giving Symbols Other Values -* Symbol Names:: Symbol Names -* Dot:: The Special Dot Symbol -* Symbol Attributes:: Symbol Attributes -@end menu - -@node Labels -@section Labels - -@cindex labels -A @dfn{label} is written as a symbol immediately followed by a colon -@samp{:}. The symbol then represents the current value of the -active location counter, and is, for example, a suitable instruction -operand. You are warned if you use the same symbol to represent two -different locations: the first definition overrides any other -definitions. - -@ifset HPPA -On the HPPA, the usual form for a label need not be immediately followed by a -colon, but instead must start in column zero. Only one label may be defined on -a single line. To work around this, the HPPA version of @command{@value{AS}} also -provides a special directive @code{.label} for defining labels more flexibly. -@end ifset - -@node Setting Symbols -@section Giving Symbols Other Values - -@cindex assigning values to symbols -@cindex symbol values, assigning -A symbol can be given an arbitrary value by writing a symbol, followed -by an equals sign @samp{=}, followed by an expression -(@pxref{Expressions}). This is equivalent to using the @code{.set} -directive. @xref{Set,,@code{.set}}. In the same way, using a double -equals sign @samp{=}@samp{=} here represents an equivalent of the -@code{.eqv} directive. @xref{Eqv,,@code{.eqv}}. - -@ifset Blackfin -Blackfin does not support symbol assignment with @samp{=}. -@end ifset - -@node Symbol Names -@section Symbol Names - -@cindex symbol names -@cindex names, symbol -@ifclear SPECIAL-SYMS -Symbol names begin with a letter or with one of @samp{._}. On most -machines, you can also use @code{$} in symbol names; exceptions are -noted in @ref{Machine Dependencies}. That character may be followed by any -string of digits, letters, dollar signs (unless otherwise noted for a -particular target machine), and underscores. -@end ifclear -@ifset SPECIAL-SYMS -@ifset H8 -Symbol names begin with a letter or with one of @samp{._}. On the -Renesas SH you can also use @code{$} in symbol names. That -character may be followed by any string of digits, letters, dollar signs (save -on the H8/300), and underscores. -@end ifset -@end ifset - -Case of letters is significant: @code{foo} is a different symbol name -than @code{Foo}. - -Each symbol has exactly one name. Each name in an assembly language program -refers to exactly one symbol. You may use that symbol name any number of times -in a program. - -@subheading Local Symbol Names - -@cindex local symbol names -@cindex symbol names, local -A local symbol is any symbol beginning with certain local label prefixes. -By default, the local label prefix is @samp{.L} for ELF systems or -@samp{L} for traditional a.out systems, but each target may have its own -set of local label prefixes. -@ifset HPPA -On the HPPA local symbols begin with @samp{L$}. -@end ifset - -Local symbols are defined and used within the assembler, but they are -normally not saved in object files. Thus, they are not visible when debugging. -You may use the @samp{-L} option (@pxref{L, ,Include Local Symbols: -@option{-L}}) to retain the local symbols in the object files. - -@subheading Local Labels - -@cindex local labels -@cindex temporary symbol names -@cindex symbol names, temporary -Local labels help compilers and programmers use names temporarily. -They create symbols which are guaranteed to be unique over the entire scope of -the input source code and which can be referred to by a simple notation. -To define a local label, write a label of the form @samp{@b{N}:} (where @b{N} -represents any positive integer). To refer to the most recent previous -definition of that label write @samp{@b{N}b}, using the same number as when -you defined the label. To refer to the next definition of a local label, write -@samp{@b{N}f}---the @samp{b} stands for ``backwards'' and the @samp{f} stands -for ``forwards''. - -There is no restriction on how you can use these labels, and you can reuse them -too. So that it is possible to repeatedly define the same local label (using -the same number @samp{@b{N}}), although you can only refer to the most recently -defined local label of that number (for a backwards reference) or the next -definition of a specific local label for a forward reference. It is also worth -noting that the first 10 local labels (@samp{@b{0:}}@dots{}@samp{@b{9:}}) are -implemented in a slightly more efficient manner than the others. - -Here is an example: - -@smallexample -1: branch 1f -2: branch 1b -1: branch 2f -2: branch 1b -@end smallexample - -Which is the equivalent of: - -@smallexample -label_1: branch label_3 -label_2: branch label_1 -label_3: branch label_4 -label_4: branch label_3 -@end smallexample - -Local label names are only a notational device. They are immediately -transformed into more conventional symbol names before the assembler uses them. -The symbol names are stored in the symbol table, appear in error messages, and -are optionally emitted to the object file. The names are constructed using -these parts: - -@table @code -@item @emph{local label prefix} -All local symbols begin with the system-specific local label prefix. -Normally both @command{@value{AS}} and @code{@value{LD}} forget symbols -that start with the local label prefix. These labels are -used for symbols you are never intended to see. If you use the -@samp{-L} option then @command{@value{AS}} retains these symbols in the -object file. If you also instruct @code{@value{LD}} to retain these symbols, -you may use them in debugging. - -@item @var{number} -This is the number that was used in the local label definition. So if the -label is written @samp{55:} then the number is @samp{55}. - -@item @kbd{C-B} -This unusual character is included so you do not accidentally invent a symbol -of the same name. The character has ASCII value of @samp{\002} (control-B). - -@item @emph{ordinal number} -This is a serial number to keep the labels distinct. The first definition of -@samp{0:} gets the number @samp{1}. The 15th definition of @samp{0:} gets the -number @samp{15}, and so on. Likewise the first definition of @samp{1:} gets -the number @samp{1} and its 15th definition gets @samp{15} as well. -@end table - -So for example, the first @code{1:} may be named @code{.L1@kbd{C-B}1}, and -the 44th @code{3:} may be named @code{.L3@kbd{C-B}44}. - -@subheading Dollar Local Labels -@cindex dollar local symbols - -@code{@value{AS}} also supports an even more local form of local labels called -dollar labels. These labels go out of scope (i.e., they become undefined) as -soon as a non-local label is defined. Thus they remain valid for only a small -region of the input source code. Normal local labels, by contrast, remain in -scope for the entire file, or until they are redefined by another occurrence of -the same local label. - -Dollar labels are defined in exactly the same way as ordinary local labels, -except that they have a dollar sign suffix to their numeric value, e.g., -@samp{@b{55$:}}. - -They can also be distinguished from ordinary local labels by their transformed -names which use ASCII character @samp{\001} (control-A) as the magic character -to distinguish them from ordinary labels. For example, the fifth definition of -@samp{6$} may be named @samp{.L6@kbd{C-A}5}. - -@node Dot -@section The Special Dot Symbol - -@cindex dot (symbol) -@cindex @code{.} (symbol) -@cindex current address -@cindex location counter -The special symbol @samp{.} refers to the current address that -@command{@value{AS}} is assembling into. Thus, the expression @samp{melvin: -.long .} defines @code{melvin} to contain its own address. -Assigning a value to @code{.} is treated the same as a @code{.org} -directive. -@ifclear no-space-dir -Thus, the expression @samp{.=.+4} is the same as saying -@samp{.space 4}. -@end ifclear - -@node Symbol Attributes -@section Symbol Attributes - -@cindex symbol attributes -@cindex attributes, symbol -Every symbol has, as well as its name, the attributes ``Value'' and -``Type''. Depending on output format, symbols can also have auxiliary -attributes. -@ifset INTERNALS -The detailed definitions are in @file{a.out.h}. -@end ifset - -If you use a symbol without defining it, @command{@value{AS}} assumes zero for -all these attributes, and probably won't warn you. This makes the -symbol an externally defined symbol, which is generally what you -would want. - -@menu -* Symbol Value:: Value -* Symbol Type:: Type -@ifset aout-bout -@ifset GENERIC -* a.out Symbols:: Symbol Attributes: @code{a.out} -@end ifset -@ifclear GENERIC -@ifclear BOUT -* a.out Symbols:: Symbol Attributes: @code{a.out} -@end ifclear -@ifset BOUT -* a.out Symbols:: Symbol Attributes: @code{a.out}, @code{b.out} -@end ifset -@end ifclear -@end ifset -@ifset COFF -* COFF Symbols:: Symbol Attributes for COFF -@end ifset -@ifset SOM -* SOM Symbols:: Symbol Attributes for SOM -@end ifset -@end menu - -@node Symbol Value -@subsection Value - -@cindex value of a symbol -@cindex symbol value -The value of a symbol is (usually) 32 bits. For a symbol which labels a -location in the text, data, bss or absolute sections the value is the -number of addresses from the start of that section to the label. -Naturally for text, data and bss sections the value of a symbol changes -as @code{@value{LD}} changes section base addresses during linking. Absolute -symbols' values do not change during linking: that is why they are -called absolute. - -The value of an undefined symbol is treated in a special way. If it is -0 then the symbol is not defined in this assembler source file, and -@code{@value{LD}} tries to determine its value from other files linked into the -same program. You make this kind of symbol simply by mentioning a symbol -name without defining it. A non-zero value represents a @code{.comm} -common declaration. The value is how much common storage to reserve, in -bytes (addresses). The symbol refers to the first address of the -allocated storage. - -@node Symbol Type -@subsection Type - -@cindex type of a symbol -@cindex symbol type -The type attribute of a symbol contains relocation (section) -information, any flag settings indicating that a symbol is external, and -(optionally), other information for linkers and debuggers. The exact -format depends on the object-code output format in use. - -@ifset aout-bout -@ifclear GENERIC -@ifset BOUT -@c The following avoids a "widow" subsection title. @group would be -@c better if it were available outside examples. -@need 1000 -@node a.out Symbols -@subsection Symbol Attributes: @code{a.out}, @code{b.out} - -@cindex @code{b.out} symbol attributes -@cindex symbol attributes, @code{b.out} -These symbol attributes appear only when @command{@value{AS}} is configured for -one of the Berkeley-descended object output formats---@code{a.out} or -@code{b.out}. - -@end ifset -@ifclear BOUT -@node a.out Symbols -@subsection Symbol Attributes: @code{a.out} - -@cindex @code{a.out} symbol attributes -@cindex symbol attributes, @code{a.out} - -@end ifclear -@end ifclear -@ifset GENERIC -@node a.out Symbols -@subsection Symbol Attributes: @code{a.out} - -@cindex @code{a.out} symbol attributes -@cindex symbol attributes, @code{a.out} - -@end ifset -@menu -* Symbol Desc:: Descriptor -* Symbol Other:: Other -@end menu - -@node Symbol Desc -@subsubsection Descriptor - -@cindex descriptor, of @code{a.out} symbol -This is an arbitrary 16-bit value. You may establish a symbol's -descriptor value by using a @code{.desc} statement -(@pxref{Desc,,@code{.desc}}). A descriptor value means nothing to -@command{@value{AS}}. - -@node Symbol Other -@subsubsection Other - -@cindex other attribute, of @code{a.out} symbol -This is an arbitrary 8-bit value. It means nothing to @command{@value{AS}}. -@end ifset - -@ifset COFF -@node COFF Symbols -@subsection Symbol Attributes for COFF - -@cindex COFF symbol attributes -@cindex symbol attributes, COFF - -The COFF format supports a multitude of auxiliary symbol attributes; -like the primary symbol attributes, they are set between @code{.def} and -@code{.endef} directives. - -@subsubsection Primary Attributes - -@cindex primary attributes, COFF symbols -The symbol name is set with @code{.def}; the value and type, -respectively, with @code{.val} and @code{.type}. - -@subsubsection Auxiliary Attributes - -@cindex auxiliary attributes, COFF symbols -The @command{@value{AS}} directives @code{.dim}, @code{.line}, @code{.scl}, -@code{.size}, @code{.tag}, and @code{.weak} can generate auxiliary symbol -table information for COFF. -@end ifset - -@ifset SOM -@node SOM Symbols -@subsection Symbol Attributes for SOM - -@cindex SOM symbol attributes -@cindex symbol attributes, SOM - -The SOM format for the HPPA supports a multitude of symbol attributes set with -the @code{.EXPORT} and @code{.IMPORT} directives. - -The attributes are described in @cite{HP9000 Series 800 Assembly -Language Reference Manual} (HP 92432-90001) under the @code{IMPORT} and -@code{EXPORT} assembler directive documentation. -@end ifset - -@node Expressions -@chapter Expressions - -@cindex expressions -@cindex addresses -@cindex numeric values -An @dfn{expression} specifies an address or numeric value. -Whitespace may precede and/or follow an expression. - -The result of an expression must be an absolute number, or else an offset into -a particular section. If an expression is not absolute, and there is not -enough information when @command{@value{AS}} sees the expression to know its -section, a second pass over the source program might be necessary to interpret -the expression---but the second pass is currently not implemented. -@command{@value{AS}} aborts with an error message in this situation. - -@menu -* Empty Exprs:: Empty Expressions -* Integer Exprs:: Integer Expressions -@end menu - -@node Empty Exprs -@section Empty Expressions - -@cindex empty expressions -@cindex expressions, empty -An empty expression has no value: it is just whitespace or null. -Wherever an absolute expression is required, you may omit the -expression, and @command{@value{AS}} assumes a value of (absolute) 0. This -is compatible with other assemblers. - -@node Integer Exprs -@section Integer Expressions - -@cindex integer expressions -@cindex expressions, integer -An @dfn{integer expression} is one or more @emph{arguments} delimited -by @emph{operators}. - -@menu -* Arguments:: Arguments -* Operators:: Operators -* Prefix Ops:: Prefix Operators -* Infix Ops:: Infix Operators -@end menu - -@node Arguments -@subsection Arguments - -@cindex expression arguments -@cindex arguments in expressions -@cindex operands in expressions -@cindex arithmetic operands -@dfn{Arguments} are symbols, numbers or subexpressions. In other -contexts arguments are sometimes called ``arithmetic operands''. In -this manual, to avoid confusing them with the ``instruction operands'' of -the machine language, we use the term ``argument'' to refer to parts of -expressions only, reserving the word ``operand'' to refer only to machine -instruction operands. - -Symbols are evaluated to yield @{@var{section} @var{NNN}@} where -@var{section} is one of text, data, bss, absolute, -or undefined. @var{NNN} is a signed, 2's complement 32 bit -integer. - -Numbers are usually integers. - -A number can be a flonum or bignum. In this case, you are warned -that only the low order 32 bits are used, and @command{@value{AS}} pretends -these 32 bits are an integer. You may write integer-manipulating -instructions that act on exotic constants, compatible with other -assemblers. - -@cindex subexpressions -Subexpressions are a left parenthesis @samp{(} followed by an integer -expression, followed by a right parenthesis @samp{)}; or a prefix -operator followed by an argument. - -@node Operators -@subsection Operators - -@cindex operators, in expressions -@cindex arithmetic functions -@cindex functions, in expressions -@dfn{Operators} are arithmetic functions, like @code{+} or @code{%}. Prefix -operators are followed by an argument. Infix operators appear -between their arguments. Operators may be preceded and/or followed by -whitespace. - -@node Prefix Ops -@subsection Prefix Operator - -@cindex prefix operators -@command{@value{AS}} has the following @dfn{prefix operators}. They each take -one argument, which must be absolute. - -@c the tex/end tex stuff surrounding this small table is meant to make -@c it align, on the printed page, with the similar table in the next -@c section (which is inside an enumerate). -@tex -\global\advance\leftskip by \itemindent -@end tex - -@table @code -@item - -@dfn{Negation}. Two's complement negation. -@item ~ -@dfn{Complementation}. Bitwise not. -@end table - -@tex -\global\advance\leftskip by -\itemindent -@end tex - -@node Infix Ops -@subsection Infix Operators - -@cindex infix operators -@cindex operators, permitted arguments -@dfn{Infix operators} take two arguments, one on either side. Operators -have precedence, but operations with equal precedence are performed left -to right. Apart from @code{+} or @option{-}, both arguments must be -absolute, and the result is absolute. - -@enumerate -@cindex operator precedence -@cindex precedence of operators - -@item -Highest Precedence - -@table @code -@item * -@dfn{Multiplication}. - -@item / -@dfn{Division}. Truncation is the same as the C operator @samp{/} - -@item % -@dfn{Remainder}. - -@item << -@dfn{Shift Left}. Same as the C operator @samp{<<}. - -@item >> -@dfn{Shift Right}. Same as the C operator @samp{>>}. -@end table - -@item -Intermediate precedence - -@table @code -@item | - -@dfn{Bitwise Inclusive Or}. - -@item & -@dfn{Bitwise And}. - -@item ^ -@dfn{Bitwise Exclusive Or}. - -@item ! -@dfn{Bitwise Or Not}. -@end table - -@item -Low Precedence - -@table @code -@cindex addition, permitted arguments -@cindex plus, permitted arguments -@cindex arguments for addition -@item + -@dfn{Addition}. If either argument is absolute, the result has the section of -the other argument. You may not add together arguments from different -sections. - -@cindex subtraction, permitted arguments -@cindex minus, permitted arguments -@cindex arguments for subtraction -@item - -@dfn{Subtraction}. If the right argument is absolute, the -result has the section of the left argument. -If both arguments are in the same section, the result is absolute. -You may not subtract arguments from different sections. -@c FIXME is there still something useful to say about undefined - undefined ? - -@cindex comparison expressions -@cindex expressions, comparison -@item == -@dfn{Is Equal To} -@item <> -@itemx != -@dfn{Is Not Equal To} -@item < -@dfn{Is Less Than} -@item > -@dfn{Is Greater Than} -@item >= -@dfn{Is Greater Than Or Equal To} -@item <= -@dfn{Is Less Than Or Equal To} - -The comparison operators can be used as infix operators. A true results has a -value of -1 whereas a false result has a value of 0. Note, these operators -perform signed comparisons. -@end table - -@item Lowest Precedence - -@table @code -@item && -@dfn{Logical And}. - -@item || -@dfn{Logical Or}. - -These two logical operations can be used to combine the results of sub -expressions. Note, unlike the comparison operators a true result returns a -value of 1 but a false results does still return 0. Also note that the logical -or operator has a slightly lower precedence than logical and. - -@end table -@end enumerate - -In short, it's only meaningful to add or subtract the @emph{offsets} in an -address; you can only have a defined section in one of the two arguments. - -@node Pseudo Ops -@chapter Assembler Directives - -@cindex directives, machine independent -@cindex pseudo-ops, machine independent -@cindex machine independent directives -All assembler directives have names that begin with a period (@samp{.}). -The rest of the name is letters, usually in lower case. - -This chapter discusses directives that are available regardless of the -target machine configuration for the @sc{gnu} assembler. -@ifset GENERIC -Some machine configurations provide additional directives. -@xref{Machine Dependencies}. -@end ifset -@ifclear GENERIC -@ifset machine-directives -@xref{Machine Dependencies}, for additional directives. -@end ifset -@end ifclear - -@menu -* Abort:: @code{.abort} -@ifset COFF -* ABORT (COFF):: @code{.ABORT} -@end ifset - -* Align:: @code{.align @var{abs-expr} , @var{abs-expr}} -* Altmacro:: @code{.altmacro} -* Ascii:: @code{.ascii "@var{string}"}@dots{} -* Asciz:: @code{.asciz "@var{string}"}@dots{} -* Balign:: @code{.balign @var{abs-expr} , @var{abs-expr}} -* Byte:: @code{.byte @var{expressions}} -* CFI directives:: @code{.cfi_startproc [simple]}, @code{.cfi_endproc}, etc. -* Comm:: @code{.comm @var{symbol} , @var{length} } -* Data:: @code{.data @var{subsection}} -@ifset COFF -* Def:: @code{.def @var{name}} -@end ifset -@ifset aout-bout -* Desc:: @code{.desc @var{symbol}, @var{abs-expression}} -@end ifset -@ifset COFF -* Dim:: @code{.dim} -@end ifset - -* Double:: @code{.double @var{flonums}} -* Eject:: @code{.eject} -* Else:: @code{.else} -* Elseif:: @code{.elseif} -* End:: @code{.end} -@ifset COFF -* Endef:: @code{.endef} -@end ifset - -* Endfunc:: @code{.endfunc} -* Endif:: @code{.endif} -* Equ:: @code{.equ @var{symbol}, @var{expression}} -* Equiv:: @code{.equiv @var{symbol}, @var{expression}} -* Eqv:: @code{.eqv @var{symbol}, @var{expression}} -* Err:: @code{.err} -* Error:: @code{.error @var{string}} -* Exitm:: @code{.exitm} -* Extern:: @code{.extern} -* Fail:: @code{.fail} -* File:: @code{.file} -* Fill:: @code{.fill @var{repeat} , @var{size} , @var{value}} -* Float:: @code{.float @var{flonums}} -* Func:: @code{.func} -* Global:: @code{.global @var{symbol}}, @code{.globl @var{symbol}} -@ifset ELF -* Gnu_attribute:: @code{.gnu_attribute @var{tag},@var{value}} -* Hidden:: @code{.hidden @var{names}} -@end ifset - -* hword:: @code{.hword @var{expressions}} -* Ident:: @code{.ident} -* If:: @code{.if @var{absolute expression}} -* Incbin:: @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]} -* Include:: @code{.include "@var{file}"} -* Int:: @code{.int @var{expressions}} -@ifset ELF -* Internal:: @code{.internal @var{names}} -@end ifset - -* Irp:: @code{.irp @var{symbol},@var{values}}@dots{} -* Irpc:: @code{.irpc @var{symbol},@var{values}}@dots{} -* Lcomm:: @code{.lcomm @var{symbol} , @var{length}} -* Lflags:: @code{.lflags} -@ifclear no-line-dir -* Line:: @code{.line @var{line-number}} -@end ifclear - -* Linkonce:: @code{.linkonce [@var{type}]} -* List:: @code{.list} -* Ln:: @code{.ln @var{line-number}} -* Loc:: @code{.loc @var{fileno} @var{lineno}} -* Loc_mark_labels:: @code{.loc_mark_labels @var{enable}} -@ifset ELF -* Local:: @code{.local @var{names}} -@end ifset - -* Long:: @code{.long @var{expressions}} -@ignore -* Lsym:: @code{.lsym @var{symbol}, @var{expression}} -@end ignore - -* Macro:: @code{.macro @var{name} @var{args}}@dots{} -* MRI:: @code{.mri @var{val}} -* Noaltmacro:: @code{.noaltmacro} -* Nolist:: @code{.nolist} -* Octa:: @code{.octa @var{bignums}} -* Offset:: @code{.offset @var{loc}} -* Org:: @code{.org @var{new-lc}, @var{fill}} -* P2align:: @code{.p2align @var{abs-expr}, @var{abs-expr}, @var{abs-expr}} -@ifset ELF -* PopSection:: @code{.popsection} -* Previous:: @code{.previous} -@end ifset - -* Print:: @code{.print @var{string}} -@ifset ELF -* Protected:: @code{.protected @var{names}} -@end ifset - -* Psize:: @code{.psize @var{lines}, @var{columns}} -* Purgem:: @code{.purgem @var{name}} -@ifset ELF -* PushSection:: @code{.pushsection @var{name}} -@end ifset - -* Quad:: @code{.quad @var{bignums}} -* Reloc:: @code{.reloc @var{offset}, @var{reloc_name}[, @var{expression}]} -* Rept:: @code{.rept @var{count}} -* Sbttl:: @code{.sbttl "@var{subheading}"} -@ifset COFF -* Scl:: @code{.scl @var{class}} -@end ifset -@ifset COFF-ELF -* Section:: @code{.section @var{name}[, @var{flags}]} -@end ifset - -* Set:: @code{.set @var{symbol}, @var{expression}} -* Short:: @code{.short @var{expressions}} -* Single:: @code{.single @var{flonums}} -@ifset COFF-ELF -* Size:: @code{.size [@var{name} , @var{expression}]} -@end ifset -@ifclear no-space-dir -* Skip:: @code{.skip @var{size} , @var{fill}} -@end ifclear - -* Sleb128:: @code{.sleb128 @var{expressions}} -@ifclear no-space-dir -* Space:: @code{.space @var{size} , @var{fill}} -@end ifclear -@ifset have-stabs -* Stab:: @code{.stabd, .stabn, .stabs} -@end ifset - -* String:: @code{.string "@var{str}"}, @code{.string8 "@var{str}"}, @code{.string16 "@var{str}"}, @code{.string32 "@var{str}"}, @code{.string64 "@var{str}"} -* Struct:: @code{.struct @var{expression}} -@ifset ELF -* SubSection:: @code{.subsection} -* Symver:: @code{.symver @var{name},@var{name2@@nodename}} -@end ifset - -@ifset COFF -* Tag:: @code{.tag @var{structname}} -@end ifset - -* Text:: @code{.text @var{subsection}} -* Title:: @code{.title "@var{heading}"} -@ifset COFF-ELF -* Type:: @code{.type <@var{int} | @var{name} , @var{type description}>} -@end ifset - -* Uleb128:: @code{.uleb128 @var{expressions}} -@ifset COFF -* Val:: @code{.val @var{addr}} -@end ifset - -@ifset ELF -* Version:: @code{.version "@var{string}"} -* VTableEntry:: @code{.vtable_entry @var{table}, @var{offset}} -* VTableInherit:: @code{.vtable_inherit @var{child}, @var{parent}} -@end ifset - -* Warning:: @code{.warning @var{string}} -* Weak:: @code{.weak @var{names}} -* Weakref:: @code{.weakref @var{alias}, @var{symbol}} -* Word:: @code{.word @var{expressions}} -* Deprecated:: Deprecated Directives -@end menu - -@node Abort -@section @code{.abort} - -@cindex @code{abort} directive -@cindex stopping the assembly -This directive stops the assembly immediately. It is for -compatibility with other assemblers. The original idea was that the -assembly language source would be piped into the assembler. If the sender -of the source quit, it could use this directive tells @command{@value{AS}} to -quit also. One day @code{.abort} will not be supported. - -@ifset COFF -@node ABORT (COFF) -@section @code{.ABORT} (COFF) - -@cindex @code{ABORT} directive -When producing COFF output, @command{@value{AS}} accepts this directive as a -synonym for @samp{.abort}. - -@ifset BOUT -When producing @code{b.out} output, @command{@value{AS}} accepts this directive, -but ignores it. -@end ifset -@end ifset - -@node Align -@section @code{.align @var{abs-expr}, @var{abs-expr}, @var{abs-expr}} - -@cindex padding the location counter -@cindex @code{align} directive -Pad the location counter (in the current subsection) to a particular storage -boundary. The first expression (which must be absolute) is the alignment -required, as described below. - -The second expression (also absolute) gives the fill value to be stored in the -padding bytes. It (and the comma) may be omitted. If it is omitted, the -padding bytes are normally zero. However, on some systems, if the section is -marked as containing code and the fill value is omitted, the space is filled -with no-op instructions. - -The third expression is also absolute, and is also optional. If it is present, -it is the maximum number of bytes that should be skipped by this alignment -directive. If doing the alignment would require skipping more bytes than the -specified maximum, then the alignment is not done at all. You can omit the -fill value (the second argument) entirely by simply using two commas after the -required alignment; this can be useful if you want the alignment to be filled -with no-op instructions when appropriate. - -The way the required alignment is specified varies from system to system. -For the arc, hppa, i386 using ELF, i860, iq2000, m68k, or32, -s390, sparc, tic4x, tic80 and xtensa, the first expression is the -alignment request in bytes. For example @samp{.align 8} advances -the location counter until it is a multiple of 8. If the location counter -is already a multiple of 8, no change is needed. For the tic54x, the -first expression is the alignment request in words. - -For other systems, including ppc, i386 using a.out format, arm and -strongarm, it is the -number of low-order zero bits the location counter must have after -advancement. For example @samp{.align 3} advances the location -counter until it a multiple of 8. If the location counter is already a -multiple of 8, no change is needed. - -This inconsistency is due to the different behaviors of the various -native assemblers for these systems which GAS must emulate. -GAS also provides @code{.balign} and @code{.p2align} directives, -described later, which have a consistent behavior across all -architectures (but are specific to GAS). - -@node Altmacro -@section @code{.altmacro} -Enable alternate macro mode, enabling: - -@ftable @code -@item LOCAL @var{name} [ , @dots{} ] -One additional directive, @code{LOCAL}, is available. It is used to -generate a string replacement for each of the @var{name} arguments, and -replace any instances of @var{name} in each macro expansion. The -replacement string is unique in the assembly, and different for each -separate macro expansion. @code{LOCAL} allows you to write macros that -define symbols, without fear of conflict between separate macro expansions. - -@item String delimiters -You can write strings delimited in these other ways besides -@code{"@var{string}"}: - -@table @code -@item '@var{string}' -You can delimit strings with single-quote characters. - -@item <@var{string}> -You can delimit strings with matching angle brackets. -@end table - -@item single-character string escape -To include any single character literally in a string (even if the -character would otherwise have some special meaning), you can prefix the -character with @samp{!} (an exclamation mark). For example, you can -write @samp{<4.3 !> 5.4!!>} to get the literal text @samp{4.3 > 5.4!}. - -@item Expression results as strings -You can write @samp{%@var{expr}} to evaluate the expression @var{expr} -and use the result as a string. -@end ftable - -@node Ascii -@section @code{.ascii "@var{string}"}@dots{} - -@cindex @code{ascii} directive -@cindex string literals -@code{.ascii} expects zero or more string literals (@pxref{Strings}) -separated by commas. It assembles each string (with no automatic -trailing zero byte) into consecutive addresses. - -@node Asciz -@section @code{.asciz "@var{string}"}@dots{} - -@cindex @code{asciz} directive -@cindex zero-terminated strings -@cindex null-terminated strings -@code{.asciz} is just like @code{.ascii}, but each string is followed by -a zero byte. The ``z'' in @samp{.asciz} stands for ``zero''. - -@node Balign -@section @code{.balign[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}} - -@cindex padding the location counter given number of bytes -@cindex @code{balign} directive -Pad the location counter (in the current subsection) to a particular -storage boundary. The first expression (which must be absolute) is the -alignment request in bytes. For example @samp{.balign 8} advances -the location counter until it is a multiple of 8. If the location counter -is already a multiple of 8, no change is needed. - -The second expression (also absolute) gives the fill value to be stored in the -padding bytes. It (and the comma) may be omitted. If it is omitted, the -padding bytes are normally zero. However, on some systems, if the section is -marked as containing code and the fill value is omitted, the space is filled -with no-op instructions. - -The third expression is also absolute, and is also optional. If it is present, -it is the maximum number of bytes that should be skipped by this alignment -directive. If doing the alignment would require skipping more bytes than the -specified maximum, then the alignment is not done at all. You can omit the -fill value (the second argument) entirely by simply using two commas after the -required alignment; this can be useful if you want the alignment to be filled -with no-op instructions when appropriate. - -@cindex @code{balignw} directive -@cindex @code{balignl} directive -The @code{.balignw} and @code{.balignl} directives are variants of the -@code{.balign} directive. The @code{.balignw} directive treats the fill -pattern as a two byte word value. The @code{.balignl} directives treats the -fill pattern as a four byte longword value. For example, @code{.balignw -4,0x368d} will align to a multiple of 4. If it skips two bytes, they will be -filled in with the value 0x368d (the exact placement of the bytes depends upon -the endianness of the processor). If it skips 1 or 3 bytes, the fill value is -undefined. - -@node Byte -@section @code{.byte @var{expressions}} - -@cindex @code{byte} directive -@cindex integers, one byte -@code{.byte} expects zero or more expressions, separated by commas. -Each expression is assembled into the next byte. - -@node CFI directives -@section @code{.cfi_sections @var{section_list}} -@cindex @code{cfi_sections} directive -@code{.cfi_sections} may be used to specify whether CFI directives -should emit @code{.eh_frame} section and/or @code{.debug_frame} section. -If @var{section_list} is @code{.eh_frame}, @code{.eh_frame} is emitted, -if @var{section_list} is @code{.debug_frame}, @code{.debug_frame} is emitted. -To emit both use @code{.eh_frame, .debug_frame}. The default if this -directive is not used is @code{.cfi_sections .eh_frame}. - -@section @code{.cfi_startproc [simple]} -@cindex @code{cfi_startproc} directive -@code{.cfi_startproc} is used at the beginning of each function that -should have an entry in @code{.eh_frame}. It initializes some internal -data structures. Don't forget to close the function by -@code{.cfi_endproc}. - -Unless @code{.cfi_startproc} is used along with parameter @code{simple} -it also emits some architecture dependent initial CFI instructions. - -@section @code{.cfi_endproc} -@cindex @code{cfi_endproc} directive -@code{.cfi_endproc} is used at the end of a function where it closes its -unwind entry previously opened by -@code{.cfi_startproc}, and emits it to @code{.eh_frame}. - -@section @code{.cfi_personality @var{encoding} [, @var{exp}]} -@code{.cfi_personality} defines personality routine and its encoding. -@var{encoding} must be a constant determining how the personality -should be encoded. If it is 255 (@code{DW_EH_PE_omit}), second -argument is not present, otherwise second argument should be -a constant or a symbol name. When using indirect encodings, -the symbol provided should be the location where personality -can be loaded from, not the personality routine itself. -The default after @code{.cfi_startproc} is @code{.cfi_personality 0xff}, -no personality routine. - -@section @code{.cfi_lsda @var{encoding} [, @var{exp}]} -@code{.cfi_lsda} defines LSDA and its encoding. -@var{encoding} must be a constant determining how the LSDA -should be encoded. If it is 255 (@code{DW_EH_PE_omit}), second -argument is not present, otherwise second argument should be a constant -or a symbol name. The default after @code{.cfi_startproc} is @code{.cfi_lsda 0xff}, -no LSDA. - -@section @code{.cfi_def_cfa @var{register}, @var{offset}} -@code{.cfi_def_cfa} defines a rule for computing CFA as: @i{take -address from @var{register} and add @var{offset} to it}. - -@section @code{.cfi_def_cfa_register @var{register}} -@code{.cfi_def_cfa_register} modifies a rule for computing CFA. From -now on @var{register} will be used instead of the old one. Offset -remains the same. - -@section @code{.cfi_def_cfa_offset @var{offset}} -@code{.cfi_def_cfa_offset} modifies a rule for computing CFA. Register -remains the same, but @var{offset} is new. Note that it is the -absolute offset that will be added to a defined register to compute -CFA address. - -@section @code{.cfi_adjust_cfa_offset @var{offset}} -Same as @code{.cfi_def_cfa_offset} but @var{offset} is a relative -value that is added/substracted from the previous offset. - -@section @code{.cfi_offset @var{register}, @var{offset}} -Previous value of @var{register} is saved at offset @var{offset} from -CFA. - -@section @code{.cfi_rel_offset @var{register}, @var{offset}} -Previous value of @var{register} is saved at offset @var{offset} from -the current CFA register. This is transformed to @code{.cfi_offset} -using the known displacement of the CFA register from the CFA. -This is often easier to use, because the number will match the -code it's annotating. - -@section @code{.cfi_register @var{register1}, @var{register2}} -Previous value of @var{register1} is saved in register @var{register2}. - -@section @code{.cfi_restore @var{register}} -@code{.cfi_restore} says that the rule for @var{register} is now the -same as it was at the beginning of the function, after all initial -instruction added by @code{.cfi_startproc} were executed. - -@section @code{.cfi_undefined @var{register}} -From now on the previous value of @var{register} can't be restored anymore. - -@section @code{.cfi_same_value @var{register}} -Current value of @var{register} is the same like in the previous frame, -i.e. no restoration needed. - -@section @code{.cfi_remember_state}, -First save all current rules for all registers by @code{.cfi_remember_state}, -then totally screw them up by subsequent @code{.cfi_*} directives and when -everything is hopelessly bad, use @code{.cfi_restore_state} to restore -the previous saved state. - -@section @code{.cfi_return_column @var{register}} -Change return column @var{register}, i.e. the return address is either -directly in @var{register} or can be accessed by rules for @var{register}. - -@section @code{.cfi_signal_frame} -Mark current function as signal trampoline. - -@section @code{.cfi_window_save} -SPARC register window has been saved. - -@section @code{.cfi_escape} @var{expression}[, @dots{}] -Allows the user to add arbitrary bytes to the unwind info. One -might use this to add OS-specific CFI opcodes, or generic CFI -opcodes that GAS does not yet support. - -@section @code{.cfi_val_encoded_addr @var{register}, @var{encoding}, @var{label}} -The current value of @var{register} is @var{label}. The value of @var{label} -will be encoded in the output file according to @var{encoding}; see the -description of @code{.cfi_personality} for details on this encoding. - -The usefulness of equating a register to a fixed label is probably -limited to the return address register. Here, it can be useful to -mark a code segment that has only one return address which is reached -by a direct branch and no copy of the return address exists in memory -or another register. - -@node Comm -@section @code{.comm @var{symbol} , @var{length} } - -@cindex @code{comm} directive -@cindex symbol, common -@code{.comm} declares a common symbol named @var{symbol}. When linking, a -common symbol in one object file may be merged with a defined or common symbol -of the same name in another object file. If @code{@value{LD}} does not see a -definition for the symbol--just one or more common symbols--then it will -allocate @var{length} bytes of uninitialized memory. @var{length} must be an -absolute expression. If @code{@value{LD}} sees multiple common symbols with -the same name, and they do not all have the same size, it will allocate space -using the largest size. - -@ifset COFF-ELF -When using ELF or (as a GNU extension) PE, the @code{.comm} directive takes -an optional third argument. This is the desired alignment of the symbol, -specified for ELF as a byte boundary (for example, an alignment of 16 means -that the least significant 4 bits of the address should be zero), and for PE -as a power of two (for example, an alignment of 5 means aligned to a 32-byte -boundary). The alignment must be an absolute expression, and it must be a -power of two. If @code{@value{LD}} allocates uninitialized memory for the -common symbol, it will use the alignment when placing the symbol. If no -alignment is specified, @command{@value{AS}} will set the alignment to the -largest power of two less than or equal to the size of the symbol, up to a -maximum of 16 on ELF, or the default section alignment of 4 on PE@footnote{This -is not the same as the executable image file alignment controlled by @code{@value{LD}}'s -@samp{--section-alignment} option; image file sections in PE are aligned to -multiples of 4096, which is far too large an alignment for ordinary variables. -It is rather the default alignment for (non-debug) sections within object -(@samp{*.o}) files, which are less strictly aligned.}. -@end ifset - -@ifset HPPA -The syntax for @code{.comm} differs slightly on the HPPA. The syntax is -@samp{@var{symbol} .comm, @var{length}}; @var{symbol} is optional. -@end ifset - -@node Data -@section @code{.data @var{subsection}} - -@cindex @code{data} directive -@code{.data} tells @command{@value{AS}} to assemble the following statements onto the -end of the data subsection numbered @var{subsection} (which is an -absolute expression). If @var{subsection} is omitted, it defaults -to zero. - -@ifset COFF -@node Def -@section @code{.def @var{name}} - -@cindex @code{def} directive -@cindex COFF symbols, debugging -@cindex debugging COFF symbols -Begin defining debugging information for a symbol @var{name}; the -definition extends until the @code{.endef} directive is encountered. -@ifset BOUT - -This directive is only observed when @command{@value{AS}} is configured for COFF -format output; when producing @code{b.out}, @samp{.def} is recognized, -but ignored. -@end ifset -@end ifset - -@ifset aout-bout -@node Desc -@section @code{.desc @var{symbol}, @var{abs-expression}} - -@cindex @code{desc} directive -@cindex COFF symbol descriptor -@cindex symbol descriptor, COFF -This directive sets the descriptor of the symbol (@pxref{Symbol Attributes}) -to the low 16 bits of an absolute expression. - -@ifset COFF -The @samp{.desc} directive is not available when @command{@value{AS}} is -configured for COFF output; it is only for @code{a.out} or @code{b.out} -object format. For the sake of compatibility, @command{@value{AS}} accepts -it, but produces no output, when configured for COFF. -@end ifset -@end ifset - -@ifset COFF -@node Dim -@section @code{.dim} - -@cindex @code{dim} directive -@cindex COFF auxiliary symbol information -@cindex auxiliary symbol information, COFF -This directive is generated by compilers to include auxiliary debugging -information in the symbol table. It is only permitted inside -@code{.def}/@code{.endef} pairs. -@ifset BOUT - -@samp{.dim} is only meaningful when generating COFF format output; when -@command{@value{AS}} is generating @code{b.out}, it accepts this directive but -ignores it. -@end ifset -@end ifset - -@node Double -@section @code{.double @var{flonums}} - -@cindex @code{double} directive -@cindex floating point numbers (double) -@code{.double} expects zero or more flonums, separated by commas. It -assembles floating point numbers. -@ifset GENERIC -The exact kind of floating point numbers emitted depends on how -@command{@value{AS}} is configured. @xref{Machine Dependencies}. -@end ifset -@ifclear GENERIC -@ifset IEEEFLOAT -On the @value{TARGET} family @samp{.double} emits 64-bit floating-point numbers -in @sc{ieee} format. -@end ifset -@end ifclear - -@node Eject -@section @code{.eject} - -@cindex @code{eject} directive -@cindex new page, in listings -@cindex page, in listings -@cindex listing control: new page -Force a page break at this point, when generating assembly listings. - -@node Else -@section @code{.else} - -@cindex @code{else} directive -@code{.else} is part of the @command{@value{AS}} support for conditional -assembly; see @ref{If,,@code{.if}}. It marks the beginning of a section -of code to be assembled if the condition for the preceding @code{.if} -was false. - -@node Elseif -@section @code{.elseif} - -@cindex @code{elseif} directive -@code{.elseif} is part of the @command{@value{AS}} support for conditional -assembly; see @ref{If,,@code{.if}}. It is shorthand for beginning a new -@code{.if} block that would otherwise fill the entire @code{.else} section. - -@node End -@section @code{.end} - -@cindex @code{end} directive -@code{.end} marks the end of the assembly file. @command{@value{AS}} does not -process anything in the file past the @code{.end} directive. - -@ifset COFF -@node Endef -@section @code{.endef} - -@cindex @code{endef} directive -This directive flags the end of a symbol definition begun with -@code{.def}. -@ifset BOUT - -@samp{.endef} is only meaningful when generating COFF format output; if -@command{@value{AS}} is configured to generate @code{b.out}, it accepts this -directive but ignores it. -@end ifset -@end ifset - -@node Endfunc -@section @code{.endfunc} -@cindex @code{endfunc} directive -@code{.endfunc} marks the end of a function specified with @code{.func}. - -@node Endif -@section @code{.endif} - -@cindex @code{endif} directive -@code{.endif} is part of the @command{@value{AS}} support for conditional assembly; -it marks the end of a block of code that is only assembled -conditionally. @xref{If,,@code{.if}}. - -@node Equ -@section @code{.equ @var{symbol}, @var{expression}} - -@cindex @code{equ} directive -@cindex assigning values to symbols -@cindex symbols, assigning values to -This directive sets the value of @var{symbol} to @var{expression}. -It is synonymous with @samp{.set}; see @ref{Set,,@code{.set}}. - -@ifset HPPA -The syntax for @code{equ} on the HPPA is -@samp{@var{symbol} .equ @var{expression}}. -@end ifset - -@ifset Z80 -The syntax for @code{equ} on the Z80 is -@samp{@var{symbol} equ @var{expression}}. -On the Z80 it is an eror if @var{symbol} is already defined, -but the symbol is not protected from later redefinition. -Compare @ref{Equiv}. -@end ifset - -@node Equiv -@section @code{.equiv @var{symbol}, @var{expression}} -@cindex @code{equiv} directive -The @code{.equiv} directive is like @code{.equ} and @code{.set}, except that -the assembler will signal an error if @var{symbol} is already defined. Note a -symbol which has been referenced but not actually defined is considered to be -undefined. - -Except for the contents of the error message, this is roughly equivalent to -@smallexample -.ifdef SYM -.err -.endif -.equ SYM,VAL -@end smallexample -plus it protects the symbol from later redefinition. - -@node Eqv -@section @code{.eqv @var{symbol}, @var{expression}} -@cindex @code{eqv} directive -The @code{.eqv} directive is like @code{.equiv}, but no attempt is made to -evaluate the expression or any part of it immediately. Instead each time -the resulting symbol is used in an expression, a snapshot of its current -value is taken. - -@node Err -@section @code{.err} -@cindex @code{err} directive -If @command{@value{AS}} assembles a @code{.err} directive, it will print an error -message and, unless the @option{-Z} option was used, it will not generate an -object file. This can be used to signal an error in conditionally compiled code. - -@node Error -@section @code{.error "@var{string}"} -@cindex error directive - -Similarly to @code{.err}, this directive emits an error, but you can specify a -string that will be emitted as the error message. If you don't specify the -message, it defaults to @code{".error directive invoked in source file"}. -@xref{Errors, ,Error and Warning Messages}. - -@smallexample - .error "This code has not been assembled and tested." -@end smallexample - -@node Exitm -@section @code{.exitm} -Exit early from the current macro definition. @xref{Macro}. - -@node Extern -@section @code{.extern} - -@cindex @code{extern} directive -@code{.extern} is accepted in the source program---for compatibility -with other assemblers---but it is ignored. @command{@value{AS}} treats -all undefined symbols as external. - -@node Fail -@section @code{.fail @var{expression}} - -@cindex @code{fail} directive -Generates an error or a warning. If the value of the @var{expression} is 500 -or more, @command{@value{AS}} will print a warning message. If the value is less -than 500, @command{@value{AS}} will print an error message. The message will -include the value of @var{expression}. This can occasionally be useful inside -complex nested macros or conditional assembly. - -@node File -@section @code{.file} -@cindex @code{file} directive - -@ifclear no-file-dir -There are two different versions of the @code{.file} directive. Targets -that support DWARF2 line number information use the DWARF2 version of -@code{.file}. Other targets use the default version. - -@subheading Default Version - -@cindex logical file name -@cindex file name, logical -This version of the @code{.file} directive tells @command{@value{AS}} that we -are about to start a new logical file. The syntax is: - -@smallexample -.file @var{string} -@end smallexample - -@var{string} is the new file name. In general, the filename is -recognized whether or not it is surrounded by quotes @samp{"}; but if you wish -to specify an empty file name, you must give the quotes--@code{""}. This -statement may go away in future: it is only recognized to be compatible with -old @command{@value{AS}} programs. - -@subheading DWARF2 Version -@end ifclear - -When emitting DWARF2 line number information, @code{.file} assigns filenames -to the @code{.debug_line} file name table. The syntax is: - -@smallexample -.file @var{fileno} @var{filename} -@end smallexample - -The @var{fileno} operand should be a unique positive integer to use as the -index of the entry in the table. The @var{filename} operand is a C string -literal. - -The detail of filename indices is exposed to the user because the filename -table is shared with the @code{.debug_info} section of the DWARF2 debugging -information, and thus the user must know the exact indices that table -entries will have. - -@node Fill -@section @code{.fill @var{repeat} , @var{size} , @var{value}} - -@cindex @code{fill} directive -@cindex writing patterns in memory -@cindex patterns, writing in memory -@var{repeat}, @var{size} and @var{value} are absolute expressions. -This emits @var{repeat} copies of @var{size} bytes. @var{Repeat} -may be zero or more. @var{Size} may be zero or more, but if it is -more than 8, then it is deemed to have the value 8, compatible with -other people's assemblers. The contents of each @var{repeat} bytes -is taken from an 8-byte number. The highest order 4 bytes are -zero. The lowest order 4 bytes are @var{value} rendered in the -byte-order of an integer on the computer @command{@value{AS}} is assembling for. -Each @var{size} bytes in a repetition is taken from the lowest order -@var{size} bytes of this number. Again, this bizarre behavior is -compatible with other people's assemblers. - -@var{size} and @var{value} are optional. -If the second comma and @var{value} are absent, @var{value} is -assumed zero. If the first comma and following tokens are absent, -@var{size} is assumed to be 1. - -@node Float -@section @code{.float @var{flonums}} - -@cindex floating point numbers (single) -@cindex @code{float} directive -This directive assembles zero or more flonums, separated by commas. It -has the same effect as @code{.single}. -@ifset GENERIC -The exact kind of floating point numbers emitted depends on how -@command{@value{AS}} is configured. -@xref{Machine Dependencies}. -@end ifset -@ifclear GENERIC -@ifset IEEEFLOAT -On the @value{TARGET} family, @code{.float} emits 32-bit floating point numbers -in @sc{ieee} format. -@end ifset -@end ifclear - -@node Func -@section @code{.func @var{name}[,@var{label}]} -@cindex @code{func} directive -@code{.func} emits debugging information to denote function @var{name}, and -is ignored unless the file is assembled with debugging enabled. -Only @samp{--gstabs[+]} is currently supported. -@var{label} is the entry point of the function and if omitted @var{name} -prepended with the @samp{leading char} is used. -@samp{leading char} is usually @code{_} or nothing, depending on the target. -All functions are currently defined to have @code{void} return type. -The function must be terminated with @code{.endfunc}. - -@node Global -@section @code{.global @var{symbol}}, @code{.globl @var{symbol}} - -@cindex @code{global} directive -@cindex symbol, making visible to linker -@code{.global} makes the symbol visible to @code{@value{LD}}. If you define -@var{symbol} in your partial program, its value is made available to -other partial programs that are linked with it. Otherwise, -@var{symbol} takes its attributes from a symbol of the same name -from another file linked into the same program. - -Both spellings (@samp{.globl} and @samp{.global}) are accepted, for -compatibility with other assemblers. - -@ifset HPPA -On the HPPA, @code{.global} is not always enough to make it accessible to other -partial programs. You may need the HPPA-only @code{.EXPORT} directive as well. -@xref{HPPA Directives, ,HPPA Assembler Directives}. -@end ifset - -@ifset ELF -@node Gnu_attribute -@section @code{.gnu_attribute @var{tag},@var{value}} -Record a @sc{gnu} object attribute for this file. @xref{Object Attributes}. - -@node Hidden -@section @code{.hidden @var{names}} - -@cindex @code{hidden} directive -@cindex visibility -This is one of the ELF visibility directives. The other two are -@code{.internal} (@pxref{Internal,,@code{.internal}}) and -@code{.protected} (@pxref{Protected,,@code{.protected}}). - -This directive overrides the named symbols default visibility (which is set by -their binding: local, global or weak). The directive sets the visibility to -@code{hidden} which means that the symbols are not visible to other components. -Such symbols are always considered to be @code{protected} as well. -@end ifset - -@node hword -@section @code{.hword @var{expressions}} - -@cindex @code{hword} directive -@cindex integers, 16-bit -@cindex numbers, 16-bit -@cindex sixteen bit integers -This expects zero or more @var{expressions}, and emits -a 16 bit number for each. - -@ifset GENERIC -This directive is a synonym for @samp{.short}; depending on the target -architecture, it may also be a synonym for @samp{.word}. -@end ifset -@ifclear GENERIC -@ifset W32 -This directive is a synonym for @samp{.short}. -@end ifset -@ifset W16 -This directive is a synonym for both @samp{.short} and @samp{.word}. -@end ifset -@end ifclear - -@node Ident -@section @code{.ident} - -@cindex @code{ident} directive - -This directive is used by some assemblers to place tags in object files. The -behavior of this directive varies depending on the target. When using the -a.out object file format, @command{@value{AS}} simply accepts the directive for -source-file compatibility with existing assemblers, but does not emit anything -for it. When using COFF, comments are emitted to the @code{.comment} or -@code{.rdata} section, depending on the target. When using ELF, comments are -emitted to the @code{.comment} section. - -@node If -@section @code{.if @var{absolute expression}} - -@cindex conditional assembly -@cindex @code{if} directive -@code{.if} marks the beginning of a section of code which is only -considered part of the source program being assembled if the argument -(which must be an @var{absolute expression}) is non-zero. The end of -the conditional section of code must be marked by @code{.endif} -(@pxref{Endif,,@code{.endif}}); optionally, you may include code for the -alternative condition, flagged by @code{.else} (@pxref{Else,,@code{.else}}). -If you have several conditions to check, @code{.elseif} may be used to avoid -nesting blocks if/else within each subsequent @code{.else} block. - -The following variants of @code{.if} are also supported: -@table @code -@cindex @code{ifdef} directive -@item .ifdef @var{symbol} -Assembles the following section of code if the specified @var{symbol} -has been defined. Note a symbol which has been referenced but not yet defined -is considered to be undefined. - -@cindex @code{ifb} directive -@item .ifb @var{text} -Assembles the following section of code if the operand is blank (empty). - -@cindex @code{ifc} directive -@item .ifc @var{string1},@var{string2} -Assembles the following section of code if the two strings are the same. The -strings may be optionally quoted with single quotes. If they are not quoted, -the first string stops at the first comma, and the second string stops at the -end of the line. Strings which contain whitespace should be quoted. The -string comparison is case sensitive. - -@cindex @code{ifeq} directive -@item .ifeq @var{absolute expression} -Assembles the following section of code if the argument is zero. - -@cindex @code{ifeqs} directive -@item .ifeqs @var{string1},@var{string2} -Another form of @code{.ifc}. The strings must be quoted using double quotes. - -@cindex @code{ifge} directive -@item .ifge @var{absolute expression} -Assembles the following section of code if the argument is greater than or -equal to zero. - -@cindex @code{ifgt} directive -@item .ifgt @var{absolute expression} -Assembles the following section of code if the argument is greater than zero. - -@cindex @code{ifle} directive -@item .ifle @var{absolute expression} -Assembles the following section of code if the argument is less than or equal -to zero. - -@cindex @code{iflt} directive -@item .iflt @var{absolute expression} -Assembles the following section of code if the argument is less than zero. - -@cindex @code{ifnb} directive -@item .ifnb @var{text} -Like @code{.ifb}, but the sense of the test is reversed: this assembles the -following section of code if the operand is non-blank (non-empty). - -@cindex @code{ifnc} directive -@item .ifnc @var{string1},@var{string2}. -Like @code{.ifc}, but the sense of the test is reversed: this assembles the -following section of code if the two strings are not the same. - -@cindex @code{ifndef} directive -@cindex @code{ifnotdef} directive -@item .ifndef @var{symbol} -@itemx .ifnotdef @var{symbol} -Assembles the following section of code if the specified @var{symbol} -has not been defined. Both spelling variants are equivalent. Note a symbol -which has been referenced but not yet defined is considered to be undefined. - -@cindex @code{ifne} directive -@item .ifne @var{absolute expression} -Assembles the following section of code if the argument is not equal to zero -(in other words, this is equivalent to @code{.if}). - -@cindex @code{ifnes} directive -@item .ifnes @var{string1},@var{string2} -Like @code{.ifeqs}, but the sense of the test is reversed: this assembles the -following section of code if the two strings are not the same. -@end table - -@node Incbin -@section @code{.incbin "@var{file}"[,@var{skip}[,@var{count}]]} - -@cindex @code{incbin} directive -@cindex binary files, including -The @code{incbin} directive includes @var{file} verbatim at the current -location. You can control the search paths used with the @samp{-I} command-line -option (@pxref{Invoking,,Command-Line Options}). Quotation marks are required -around @var{file}. - -The @var{skip} argument skips a number of bytes from the start of the -@var{file}. The @var{count} argument indicates the maximum number of bytes to -read. Note that the data is not aligned in any way, so it is the user's -responsibility to make sure that proper alignment is provided both before and -after the @code{incbin} directive. - -@node Include -@section @code{.include "@var{file}"} - -@cindex @code{include} directive -@cindex supporting files, including -@cindex files, including -This directive provides a way to include supporting files at specified -points in your source program. The code from @var{file} is assembled as -if it followed the point of the @code{.include}; when the end of the -included file is reached, assembly of the original file continues. You -can control the search paths used with the @samp{-I} command-line option -(@pxref{Invoking,,Command-Line Options}). Quotation marks are required -around @var{file}. - -@node Int -@section @code{.int @var{expressions}} - -@cindex @code{int} directive -@cindex integers, 32-bit -Expect zero or more @var{expressions}, of any section, separated by commas. -For each expression, emit a number that, at run time, is the value of that -expression. The byte order and bit size of the number depends on what kind -of target the assembly is for. - -@ifclear GENERIC -@ifset H8 -On most forms of the H8/300, @code{.int} emits 16-bit -integers. On the H8/300H and the Renesas SH, however, @code{.int} emits -32-bit integers. -@end ifset -@end ifclear - -@ifset ELF -@node Internal -@section @code{.internal @var{names}} - -@cindex @code{internal} directive -@cindex visibility -This is one of the ELF visibility directives. The other two are -@code{.hidden} (@pxref{Hidden,,@code{.hidden}}) and -@code{.protected} (@pxref{Protected,,@code{.protected}}). - -This directive overrides the named symbols default visibility (which is set by -their binding: local, global or weak). The directive sets the visibility to -@code{internal} which means that the symbols are considered to be @code{hidden} -(i.e., not visible to other components), and that some extra, processor specific -processing must also be performed upon the symbols as well. -@end ifset - -@node Irp -@section @code{.irp @var{symbol},@var{values}}@dots{} - -@cindex @code{irp} directive -Evaluate a sequence of statements assigning different values to @var{symbol}. -The sequence of statements starts at the @code{.irp} directive, and is -terminated by an @code{.endr} directive. For each @var{value}, @var{symbol} is -set to @var{value}, and the sequence of statements is assembled. If no -@var{value} is listed, the sequence of statements is assembled once, with -@var{symbol} set to the null string. To refer to @var{symbol} within the -sequence of statements, use @var{\symbol}. - -For example, assembling - -@example - .irp param,1,2,3 - move d\param,sp@@- - .endr -@end example - -is equivalent to assembling - -@example - move d1,sp@@- - move d2,sp@@- - move d3,sp@@- -@end example - -For some caveats with the spelling of @var{symbol}, see also @ref{Macro}. - -@node Irpc -@section @code{.irpc @var{symbol},@var{values}}@dots{} - -@cindex @code{irpc} directive -Evaluate a sequence of statements assigning different values to @var{symbol}. -The sequence of statements starts at the @code{.irpc} directive, and is -terminated by an @code{.endr} directive. For each character in @var{value}, -@var{symbol} is set to the character, and the sequence of statements is -assembled. If no @var{value} is listed, the sequence of statements is -assembled once, with @var{symbol} set to the null string. To refer to -@var{symbol} within the sequence of statements, use @var{\symbol}. - -For example, assembling - -@example - .irpc param,123 - move d\param,sp@@- - .endr -@end example - -is equivalent to assembling - -@example - move d1,sp@@- - move d2,sp@@- - move d3,sp@@- -@end example - -For some caveats with the spelling of @var{symbol}, see also the discussion -at @xref{Macro}. - -@node Lcomm -@section @code{.lcomm @var{symbol} , @var{length}} - -@cindex @code{lcomm} directive -@cindex local common symbols -@cindex symbols, local common -Reserve @var{length} (an absolute expression) bytes for a local common -denoted by @var{symbol}. The section and value of @var{symbol} are -those of the new local common. The addresses are allocated in the bss -section, so that at run-time the bytes start off zeroed. @var{Symbol} -is not declared global (@pxref{Global,,@code{.global}}), so is normally -not visible to @code{@value{LD}}. - -@ifset GENERIC -Some targets permit a third argument to be used with @code{.lcomm}. This -argument specifies the desired alignment of the symbol in the bss section. -@end ifset - -@ifset HPPA -The syntax for @code{.lcomm} differs slightly on the HPPA. The syntax is -@samp{@var{symbol} .lcomm, @var{length}}; @var{symbol} is optional. -@end ifset - -@node Lflags -@section @code{.lflags} - -@cindex @code{lflags} directive (ignored) -@command{@value{AS}} accepts this directive, for compatibility with other -assemblers, but ignores it. - -@ifclear no-line-dir -@node Line -@section @code{.line @var{line-number}} - -@cindex @code{line} directive -@cindex logical line number -@ifset aout-bout -Change the logical line number. @var{line-number} must be an absolute -expression. The next line has that logical line number. Therefore any other -statements on the current line (after a statement separator character) are -reported as on logical line number @var{line-number} @minus{} 1. One day -@command{@value{AS}} will no longer support this directive: it is recognized only -for compatibility with existing assembler programs. -@end ifset - -Even though this is a directive associated with the @code{a.out} or -@code{b.out} object-code formats, @command{@value{AS}} still recognizes it -when producing COFF output, and treats @samp{.line} as though it -were the COFF @samp{.ln} @emph{if} it is found outside a -@code{.def}/@code{.endef} pair. - -Inside a @code{.def}, @samp{.line} is, instead, one of the directives -used by compilers to generate auxiliary symbol information for -debugging. -@end ifclear - -@node Linkonce -@section @code{.linkonce [@var{type}]} -@cindex COMDAT -@cindex @code{linkonce} directive -@cindex common sections -Mark the current section so that the linker only includes a single copy of it. -This may be used to include the same section in several different object files, -but ensure that the linker will only include it once in the final output file. -The @code{.linkonce} pseudo-op must be used for each instance of the section. -Duplicate sections are detected based on the section name, so it should be -unique. - -This directive is only supported by a few object file formats; as of this -writing, the only object file format which supports it is the Portable -Executable format used on Windows NT. - -The @var{type} argument is optional. If specified, it must be one of the -following strings. For example: -@smallexample -.linkonce same_size -@end smallexample -Not all types may be supported on all object file formats. - -@table @code -@item discard -Silently discard duplicate sections. This is the default. - -@item one_only -Warn if there are duplicate sections, but still keep only one copy. - -@item same_size -Warn if any of the duplicates have different sizes. - -@item same_contents -Warn if any of the duplicates do not have exactly the same contents. -@end table - -@node List -@section @code{.list} - -@cindex @code{list} directive -@cindex listing control, turning on -Control (in conjunction with the @code{.nolist} directive) whether or -not assembly listings are generated. These two directives maintain an -internal counter (which is zero initially). @code{.list} increments the -counter, and @code{.nolist} decrements it. Assembly listings are -generated whenever the counter is greater than zero. - -By default, listings are disabled. When you enable them (with the -@samp{-a} command line option; @pxref{Invoking,,Command-Line Options}), -the initial value of the listing counter is one. - -@node Ln -@section @code{.ln @var{line-number}} - -@cindex @code{ln} directive -@ifclear no-line-dir -@samp{.ln} is a synonym for @samp{.line}. -@end ifclear -@ifset no-line-dir -Tell @command{@value{AS}} to change the logical line number. @var{line-number} -must be an absolute expression. The next line has that logical -line number, so any other statements on the current line (after a -statement separator character @code{;}) are reported as on logical -line number @var{line-number} @minus{} 1. -@ifset BOUT - -This directive is accepted, but ignored, when @command{@value{AS}} is -configured for @code{b.out}; its effect is only associated with COFF -output format. -@end ifset -@end ifset - -@node Loc -@section @code{.loc @var{fileno} @var{lineno} [@var{column}] [@var{options}]} -@cindex @code{loc} directive -When emitting DWARF2 line number information, -the @code{.loc} directive will add a row to the @code{.debug_line} line -number matrix corresponding to the immediately following assembly -instruction. The @var{fileno}, @var{lineno}, and optional @var{column} -arguments will be applied to the @code{.debug_line} state machine before -the row is added. - -The @var{options} are a sequence of the following tokens in any order: - -@table @code -@item basic_block -This option will set the @code{basic_block} register in the -@code{.debug_line} state machine to @code{true}. - -@item prologue_end -This option will set the @code{prologue_end} register in the -@code{.debug_line} state machine to @code{true}. - -@item epilogue_begin -This option will set the @code{epilogue_begin} register in the -@code{.debug_line} state machine to @code{true}. - -@item is_stmt @var{value} -This option will set the @code{is_stmt} register in the -@code{.debug_line} state machine to @code{value}, which must be -either 0 or 1. - -@item isa @var{value} -This directive will set the @code{isa} register in the @code{.debug_line} -state machine to @var{value}, which must be an unsigned integer. - -@item discriminator @var{value} -This directive will set the @code{discriminator} register in the @code{.debug_line} -state machine to @var{value}, which must be an unsigned integer. - -@end table - -@node Loc_mark_labels -@section @code{.loc_mark_labels @var{enable}} -@cindex @code{loc_mark_labels} directive -When emitting DWARF2 line number information, -the @code{.loc_mark_labels} directive makes the assembler emit an entry -to the @code{.debug_line} line number matrix with the @code{basic_block} -register in the state machine set whenever a code label is seen. -The @var{enable} argument should be either 1 or 0, to enable or disable -this function respectively. - -@ifset ELF -@node Local -@section @code{.local @var{names}} - -@cindex @code{local} directive -This directive, which is available for ELF targets, marks each symbol in -the comma-separated list of @code{names} as a local symbol so that it -will not be externally visible. If the symbols do not already exist, -they will be created. - -For targets where the @code{.lcomm} directive (@pxref{Lcomm}) does not -accept an alignment argument, which is the case for most ELF targets, -the @code{.local} directive can be used in combination with @code{.comm} -(@pxref{Comm}) to define aligned local common data. -@end ifset - -@node Long -@section @code{.long @var{expressions}} - -@cindex @code{long} directive -@code{.long} is the same as @samp{.int}. @xref{Int,,@code{.int}}. - -@ignore -@c no one seems to know what this is for or whether this description is -@c what it really ought to do -@node Lsym -@section @code{.lsym @var{symbol}, @var{expression}} - -@cindex @code{lsym} directive -@cindex symbol, not referenced in assembly -@code{.lsym} creates a new symbol named @var{symbol}, but does not put it in -the hash table, ensuring it cannot be referenced by name during the -rest of the assembly. This sets the attributes of the symbol to be -the same as the expression value: -@smallexample -@var{other} = @var{descriptor} = 0 -@var{type} = @r{(section of @var{expression})} -@var{value} = @var{expression} -@end smallexample -@noindent -The new symbol is not flagged as external. -@end ignore - -@node Macro -@section @code{.macro} - -@cindex macros -The commands @code{.macro} and @code{.endm} allow you to define macros that -generate assembly output. For example, this definition specifies a macro -@code{sum} that puts a sequence of numbers into memory: - -@example - .macro sum from=0, to=5 - .long \from - .if \to-\from - sum "(\from+1)",\to - .endif - .endm -@end example - -@noindent -With that definition, @samp{SUM 0,5} is equivalent to this assembly input: - -@example - .long 0 - .long 1 - .long 2 - .long 3 - .long 4 - .long 5 -@end example - -@ftable @code -@item .macro @var{macname} -@itemx .macro @var{macname} @var{macargs} @dots{} -@cindex @code{macro} directive -Begin the definition of a macro called @var{macname}. If your macro -definition requires arguments, specify their names after the macro name, -separated by commas or spaces. You can qualify the macro argument to -indicate whether all invocations must specify a non-blank value (through -@samp{:@code{req}}), or whether it takes all of the remaining arguments -(through @samp{:@code{vararg}}). You can supply a default value for any -macro argument by following the name with @samp{=@var{deflt}}. You -cannot define two macros with the same @var{macname} unless it has been -subject to the @code{.purgem} directive (@pxref{Purgem}) between the two -definitions. For example, these are all valid @code{.macro} statements: - -@table @code -@item .macro comm -Begin the definition of a macro called @code{comm}, which takes no -arguments. - -@item .macro plus1 p, p1 -@itemx .macro plus1 p p1 -Either statement begins the definition of a macro called @code{plus1}, -which takes two arguments; within the macro definition, write -@samp{\p} or @samp{\p1} to evaluate the arguments. - -@item .macro reserve_str p1=0 p2 -Begin the definition of a macro called @code{reserve_str}, with two -arguments. The first argument has a default value, but not the second. -After the definition is complete, you can call the macro either as -@samp{reserve_str @var{a},@var{b}} (with @samp{\p1} evaluating to -@var{a} and @samp{\p2} evaluating to @var{b}), or as @samp{reserve_str -,@var{b}} (with @samp{\p1} evaluating as the default, in this case -@samp{0}, and @samp{\p2} evaluating to @var{b}). - -@item .macro m p1:req, p2=0, p3:vararg -Begin the definition of a macro called @code{m}, with at least three -arguments. The first argument must always have a value specified, but -not the second, which instead has a default value. The third formal -will get assigned all remaining arguments specified at invocation time. - -When you call a macro, you can specify the argument values either by -position, or by keyword. For example, @samp{sum 9,17} is equivalent to -@samp{sum to=17, from=9}. - -@end table - -Note that since each of the @var{macargs} can be an identifier exactly -as any other one permitted by the target architecture, there may be -occasional problems if the target hand-crafts special meanings to certain -characters when they occur in a special position. For example, if the colon -(@code{:}) is generally permitted to be part of a symbol name, but the -architecture specific code special-cases it when occurring as the final -character of a symbol (to denote a label), then the macro parameter -replacement code will have no way of knowing that and consider the whole -construct (including the colon) an identifier, and check only this -identifier for being the subject to parameter substitution. So for example -this macro definition: - -@example - .macro label l -\l: - .endm -@end example - -might not work as expected. Invoking @samp{label foo} might not create a label -called @samp{foo} but instead just insert the text @samp{\l:} into the -assembler source, probably generating an error about an unrecognised -identifier. - -Similarly problems might occur with the period character (@samp{.}) -which is often allowed inside opcode names (and hence identifier names). So -for example constructing a macro to build an opcode from a base name and a -length specifier like this: - -@example - .macro opcode base length - \base.\length - .endm -@end example - -and invoking it as @samp{opcode store l} will not create a @samp{store.l} -instruction but instead generate some kind of error as the assembler tries to -interpret the text @samp{\base.\length}. - -There are several possible ways around this problem: - -@table @code -@item Insert white space -If it is possible to use white space characters then this is the simplest -solution. eg: - -@example - .macro label l -\l : - .endm -@end example - -@item Use @samp{\()} -The string @samp{\()} can be used to separate the end of a macro argument from -the following text. eg: - -@example - .macro opcode base length - \base\().\length - .endm -@end example - -@item Use the alternate macro syntax mode -In the alternative macro syntax mode the ampersand character (@samp{&}) can be -used as a separator. eg: - -@example - .altmacro - .macro label l -l&: - .endm -@end example -@end table - -Note: this problem of correctly identifying string parameters to pseudo ops -also applies to the identifiers used in @code{.irp} (@pxref{Irp}) -and @code{.irpc} (@pxref{Irpc}) as well. - -@item .endm -@cindex @code{endm} directive -Mark the end of a macro definition. - -@item .exitm -@cindex @code{exitm} directive -Exit early from the current macro definition. - -@cindex number of macros executed -@cindex macros, count executed -@item \@@ -@command{@value{AS}} maintains a counter of how many macros it has -executed in this pseudo-variable; you can copy that number to your -output with @samp{\@@}, but @emph{only within a macro definition}. - -@item LOCAL @var{name} [ , @dots{} ] -@emph{Warning: @code{LOCAL} is only available if you select ``alternate -macro syntax'' with @samp{--alternate} or @code{.altmacro}.} -@xref{Altmacro,,@code{.altmacro}}. -@end ftable - -@node MRI -@section @code{.mri @var{val}} - -@cindex @code{mri} directive -@cindex MRI mode, temporarily -If @var{val} is non-zero, this tells @command{@value{AS}} to enter MRI mode. If -@var{val} is zero, this tells @command{@value{AS}} to exit MRI mode. This change -affects code assembled until the next @code{.mri} directive, or until the end -of the file. @xref{M, MRI mode, MRI mode}. - -@node Noaltmacro -@section @code{.noaltmacro} -Disable alternate macro mode. @xref{Altmacro}. - -@node Nolist -@section @code{.nolist} - -@cindex @code{nolist} directive -@cindex listing control, turning off -Control (in conjunction with the @code{.list} directive) whether or -not assembly listings are generated. These two directives maintain an -internal counter (which is zero initially). @code{.list} increments the -counter, and @code{.nolist} decrements it. Assembly listings are -generated whenever the counter is greater than zero. - -@node Octa -@section @code{.octa @var{bignums}} - -@c FIXME: double size emitted for "octa" on i960, others? Or warn? -@cindex @code{octa} directive -@cindex integer, 16-byte -@cindex sixteen byte integer -This directive expects zero or more bignums, separated by commas. For each -bignum, it emits a 16-byte integer. - -The term ``octa'' comes from contexts in which a ``word'' is two bytes; -hence @emph{octa}-word for 16 bytes. - -@node Offset -@section @code{.offset @var{loc}} - -@cindex @code{offset} directive -Set the location counter to @var{loc} in the absolute section. @var{loc} must -be an absolute expression. This directive may be useful for defining -symbols with absolute values. Do not confuse it with the @code{.org} -directive. - -@node Org -@section @code{.org @var{new-lc} , @var{fill}} - -@cindex @code{org} directive -@cindex location counter, advancing -@cindex advancing location counter -@cindex current address, advancing -Advance the location counter of the current section to -@var{new-lc}. @var{new-lc} is either an absolute expression or an -expression with the same section as the current subsection. That is, -you can't use @code{.org} to cross sections: if @var{new-lc} has the -wrong section, the @code{.org} directive is ignored. To be compatible -with former assemblers, if the section of @var{new-lc} is absolute, -@command{@value{AS}} issues a warning, then pretends the section of @var{new-lc} -is the same as the current subsection. - -@code{.org} may only increase the location counter, or leave it -unchanged; you cannot use @code{.org} to move the location counter -backwards. - -@c double negative used below "not undefined" because this is a specific -@c reference to "undefined" (as SEG_UNKNOWN is called in this manual) -@c section. doc@cygnus.com 18feb91 -Because @command{@value{AS}} tries to assemble programs in one pass, @var{new-lc} -may not be undefined. If you really detest this restriction we eagerly await -a chance to share your improved assembler. - -Beware that the origin is relative to the start of the section, not -to the start of the subsection. This is compatible with other -people's assemblers. - -When the location counter (of the current subsection) is advanced, the -intervening bytes are filled with @var{fill} which should be an -absolute expression. If the comma and @var{fill} are omitted, -@var{fill} defaults to zero. - -@node P2align -@section @code{.p2align[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}} - -@cindex padding the location counter given a power of two -@cindex @code{p2align} directive -Pad the location counter (in the current subsection) to a particular -storage boundary. The first expression (which must be absolute) is the -number of low-order zero bits the location counter must have after -advancement. For example @samp{.p2align 3} advances the location -counter until it a multiple of 8. If the location counter is already a -multiple of 8, no change is needed. - -The second expression (also absolute) gives the fill value to be stored in the -padding bytes. It (and the comma) may be omitted. If it is omitted, the -padding bytes are normally zero. However, on some systems, if the section is -marked as containing code and the fill value is omitted, the space is filled -with no-op instructions. - -The third expression is also absolute, and is also optional. If it is present, -it is the maximum number of bytes that should be skipped by this alignment -directive. If doing the alignment would require skipping more bytes than the -specified maximum, then the alignment is not done at all. You can omit the -fill value (the second argument) entirely by simply using two commas after the -required alignment; this can be useful if you want the alignment to be filled -with no-op instructions when appropriate. - -@cindex @code{p2alignw} directive -@cindex @code{p2alignl} directive -The @code{.p2alignw} and @code{.p2alignl} directives are variants of the -@code{.p2align} directive. The @code{.p2alignw} directive treats the fill -pattern as a two byte word value. The @code{.p2alignl} directives treats the -fill pattern as a four byte longword value. For example, @code{.p2alignw -2,0x368d} will align to a multiple of 4. If it skips two bytes, they will be -filled in with the value 0x368d (the exact placement of the bytes depends upon -the endianness of the processor). If it skips 1 or 3 bytes, the fill value is -undefined. - -@ifset ELF -@node PopSection -@section @code{.popsection} - -@cindex @code{popsection} directive -@cindex Section Stack -This is one of the ELF section stack manipulation directives. The others are -@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}), -@code{.pushsection} (@pxref{PushSection}), and @code{.previous} -(@pxref{Previous}). - -This directive replaces the current section (and subsection) with the top -section (and subsection) on the section stack. This section is popped off the -stack. -@end ifset - -@ifset ELF -@node Previous -@section @code{.previous} - -@cindex @code{previous} directive -@cindex Section Stack -This is one of the ELF section stack manipulation directives. The others are -@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}), -@code{.pushsection} (@pxref{PushSection}), and @code{.popsection} -(@pxref{PopSection}). - -This directive swaps the current section (and subsection) with most recently -referenced section/subsection pair prior to this one. Multiple -@code{.previous} directives in a row will flip between two sections (and their -subsections). For example: - -@smallexample -.section A - .subsection 1 - .word 0x1234 - .subsection 2 - .word 0x5678 -.previous - .word 0x9abc -@end smallexample - -Will place 0x1234 and 0x9abc into subsection 1 and 0x5678 into subsection 2 of -section A. Whilst: - -@smallexample -.section A -.subsection 1 - # Now in section A subsection 1 - .word 0x1234 -.section B -.subsection 0 - # Now in section B subsection 0 - .word 0x5678 -.subsection 1 - # Now in section B subsection 1 - .word 0x9abc -.previous - # Now in section B subsection 0 - .word 0xdef0 -@end smallexample - -Will place 0x1234 into section A, 0x5678 and 0xdef0 into subsection 0 of -section B and 0x9abc into subsection 1 of section B. - -In terms of the section stack, this directive swaps the current section with -the top section on the section stack. -@end ifset - -@node Print -@section @code{.print @var{string}} - -@cindex @code{print} directive -@command{@value{AS}} will print @var{string} on the standard output during -assembly. You must put @var{string} in double quotes. - -@ifset ELF -@node Protected -@section @code{.protected @var{names}} - -@cindex @code{protected} directive -@cindex visibility -This is one of the ELF visibility directives. The other two are -@code{.hidden} (@pxref{Hidden}) and @code{.internal} (@pxref{Internal}). - -This directive overrides the named symbols default visibility (which is set by -their binding: local, global or weak). The directive sets the visibility to -@code{protected} which means that any references to the symbols from within the -components that defines them must be resolved to the definition in that -component, even if a definition in another component would normally preempt -this. -@end ifset - -@node Psize -@section @code{.psize @var{lines} , @var{columns}} - -@cindex @code{psize} directive -@cindex listing control: paper size -@cindex paper size, for listings -Use this directive to declare the number of lines---and, optionally, the -number of columns---to use for each page, when generating listings. - -If you do not use @code{.psize}, listings use a default line-count -of 60. You may omit the comma and @var{columns} specification; the -default width is 200 columns. - -@command{@value{AS}} generates formfeeds whenever the specified number of -lines is exceeded (or whenever you explicitly request one, using -@code{.eject}). - -If you specify @var{lines} as @code{0}, no formfeeds are generated save -those explicitly specified with @code{.eject}. - -@node Purgem -@section @code{.purgem @var{name}} - -@cindex @code{purgem} directive -Undefine the macro @var{name}, so that later uses of the string will not be -expanded. @xref{Macro}. - -@ifset ELF -@node PushSection -@section @code{.pushsection @var{name} [, @var{subsection}] [, "@var{flags}"[, @@@var{type}[,@var{arguments}]]]} - -@cindex @code{pushsection} directive -@cindex Section Stack -This is one of the ELF section stack manipulation directives. The others are -@code{.section} (@pxref{Section}), @code{.subsection} (@pxref{SubSection}), -@code{.popsection} (@pxref{PopSection}), and @code{.previous} -(@pxref{Previous}). - -This directive pushes the current section (and subsection) onto the -top of the section stack, and then replaces the current section and -subsection with @code{name} and @code{subsection}. The optional -@code{flags}, @code{type} and @code{arguments} are treated the same -as in the @code{.section} (@pxref{Section}) directive. -@end ifset - -@node Quad -@section @code{.quad @var{bignums}} - -@cindex @code{quad} directive -@code{.quad} expects zero or more bignums, separated by commas. For -each bignum, it emits -@ifclear bignum-16 -an 8-byte integer. If the bignum won't fit in 8 bytes, it prints a -warning message; and just takes the lowest order 8 bytes of the bignum. -@cindex eight-byte integer -@cindex integer, 8-byte - -The term ``quad'' comes from contexts in which a ``word'' is two bytes; -hence @emph{quad}-word for 8 bytes. -@end ifclear -@ifset bignum-16 -a 16-byte integer. If the bignum won't fit in 16 bytes, it prints a -warning message; and just takes the lowest order 16 bytes of the bignum. -@cindex sixteen-byte integer -@cindex integer, 16-byte -@end ifset - -@node Reloc -@section @code{.reloc @var{offset}, @var{reloc_name}[, @var{expression}]} - -@cindex @code{reloc} directive -Generate a relocation at @var{offset} of type @var{reloc_name} with value -@var{expression}. If @var{offset} is a number, the relocation is generated in -the current section. If @var{offset} is an expression that resolves to a -symbol plus offset, the relocation is generated in the given symbol's section. -@var{expression}, if present, must resolve to a symbol plus addend or to an -absolute value, but note that not all targets support an addend. e.g. ELF REL -targets such as i386 store an addend in the section contents rather than in the -relocation. This low level interface does not support addends stored in the -section. - -@node Rept -@section @code{.rept @var{count}} - -@cindex @code{rept} directive -Repeat the sequence of lines between the @code{.rept} directive and the next -@code{.endr} directive @var{count} times. - -For example, assembling - -@example - .rept 3 - .long 0 - .endr -@end example - -is equivalent to assembling - -@example - .long 0 - .long 0 - .long 0 -@end example - -@node Sbttl -@section @code{.sbttl "@var{subheading}"} - -@cindex @code{sbttl} directive -@cindex subtitles for listings -@cindex listing control: subtitle -Use @var{subheading} as the title (third line, immediately after the -title line) when generating assembly listings. - -This directive affects subsequent pages, as well as the current page if -it appears within ten lines of the top of a page. - -@ifset COFF -@node Scl -@section @code{.scl @var{class}} - -@cindex @code{scl} directive -@cindex symbol storage class (COFF) -@cindex COFF symbol storage class -Set the storage-class value for a symbol. This directive may only be -used inside a @code{.def}/@code{.endef} pair. Storage class may flag -whether a symbol is static or external, or it may record further -symbolic debugging information. -@ifset BOUT - -The @samp{.scl} directive is primarily associated with COFF output; when -configured to generate @code{b.out} output format, @command{@value{AS}} -accepts this directive but ignores it. -@end ifset -@end ifset - -@ifset COFF-ELF -@node Section -@section @code{.section @var{name}} - -@cindex named section -Use the @code{.section} directive to assemble the following code into a section -named @var{name}. - -This directive is only supported for targets that actually support arbitrarily -named sections; on @code{a.out} targets, for example, it is not accepted, even -with a standard @code{a.out} section name. - -@ifset COFF -@ifset ELF -@c only print the extra heading if both COFF and ELF are set -@subheading COFF Version -@end ifset - -@cindex @code{section} directive (COFF version) -For COFF targets, the @code{.section} directive is used in one of the following -ways: - -@smallexample -.section @var{name}[, "@var{flags}"] -.section @var{name}[, @var{subsection}] -@end smallexample - -If the optional argument is quoted, it is taken as flags to use for the -section. Each flag is a single character. The following flags are recognized: -@table @code -@item b -bss section (uninitialized data) -@item n -section is not loaded -@item w -writable section -@item d -data section -@item r -read-only section -@item x -executable section -@item s -shared section (meaningful for PE targets) -@item a -ignored. (For compatibility with the ELF version) -@item y -section is not readable (meaningful for PE targets) -@item 0-9 -single-digit power-of-two section alignment (GNU extension) -@end table - -If no flags are specified, the default flags depend upon the section name. If -the section name is not recognized, the default will be for the section to be -loaded and writable. Note the @code{n} and @code{w} flags remove attributes -from the section, rather than adding them, so if they are used on their own it -will be as if no flags had been specified at all. - -If the optional argument to the @code{.section} directive is not quoted, it is -taken as a subsection number (@pxref{Sub-Sections}). -@end ifset - -@ifset ELF -@ifset COFF -@c only print the extra heading if both COFF and ELF are set -@subheading ELF Version -@end ifset - -@cindex Section Stack -This is one of the ELF section stack manipulation directives. The others are -@code{.subsection} (@pxref{SubSection}), @code{.pushsection} -(@pxref{PushSection}), @code{.popsection} (@pxref{PopSection}), and -@code{.previous} (@pxref{Previous}). - -@cindex @code{section} directive (ELF version) -For ELF targets, the @code{.section} directive is used like this: - -@smallexample -.section @var{name} [, "@var{flags}"[, @@@var{type}[,@var{flag_specific_arguments}]]] -@end smallexample - -The optional @var{flags} argument is a quoted string which may contain any -combination of the following characters: -@table @code -@item a -section is allocatable -@item e -section is excluded from executable and shared library. -@item w -section is writable -@item x -section is executable -@item M -section is mergeable -@item S -section contains zero terminated strings -@item G -section is a member of a section group -@item T -section is used for thread-local-storage -@item ? -section is a member of the previously-current section's group, if any -@end table - -The optional @var{type} argument may contain one of the following constants: -@table @code -@item @@progbits -section contains data -@item @@nobits -section does not contain data (i.e., section only occupies space) -@item @@note -section contains data which is used by things other than the program -@item @@init_array -section contains an array of pointers to init functions -@item @@fini_array -section contains an array of pointers to finish functions -@item @@preinit_array -section contains an array of pointers to pre-init functions -@end table - -Many targets only support the first three section types. - -Note on targets where the @code{@@} character is the start of a comment (eg -ARM) then another character is used instead. For example the ARM port uses the -@code{%} character. - -If @var{flags} contains the @code{M} symbol then the @var{type} argument must -be specified as well as an extra argument---@var{entsize}---like this: - -@smallexample -.section @var{name} , "@var{flags}"M, @@@var{type}, @var{entsize} -@end smallexample - -Sections with the @code{M} flag but not @code{S} flag must contain fixed size -constants, each @var{entsize} octets long. Sections with both @code{M} and -@code{S} must contain zero terminated strings where each character is -@var{entsize} bytes long. The linker may remove duplicates within sections with -the same name, same entity size and same flags. @var{entsize} must be an -absolute expression. For sections with both @code{M} and @code{S}, a string -which is a suffix of a larger string is considered a duplicate. Thus -@code{"def"} will be merged with @code{"abcdef"}; A reference to the first -@code{"def"} will be changed to a reference to @code{"abcdef"+3}. - -If @var{flags} contains the @code{G} symbol then the @var{type} argument must -be present along with an additional field like this: - -@smallexample -.section @var{name} , "@var{flags}"G, @@@var{type}, @var{GroupName}[, @var{linkage}] -@end smallexample - -The @var{GroupName} field specifies the name of the section group to which this -particular section belongs. The optional linkage field can contain: -@table @code -@item comdat -indicates that only one copy of this section should be retained -@item .gnu.linkonce -an alias for comdat -@end table - -Note: if both the @var{M} and @var{G} flags are present then the fields for -the Merge flag should come first, like this: - -@smallexample -.section @var{name} , "@var{flags}"MG, @@@var{type}, @var{entsize}, @var{GroupName}[, @var{linkage}] -@end smallexample - -If @var{flags} contains the @code{?} symbol then it may not also contain the -@code{G} symbol and the @var{GroupName} or @var{linkage} fields should not be -present. Instead, @code{?} says to consider the section that's current before -this directive. If that section used @code{G}, then the new section will use -@code{G} with those same @var{GroupName} and @var{linkage} fields implicitly. -If not, then the @code{?} symbol has no effect. - -If no flags are specified, the default flags depend upon the section name. If -the section name is not recognized, the default will be for the section to have -none of the above flags: it will not be allocated in memory, nor writable, nor -executable. The section will contain data. - -For ELF targets, the assembler supports another type of @code{.section} -directive for compatibility with the Solaris assembler: - -@smallexample -.section "@var{name}"[, @var{flags}...] -@end smallexample - -Note that the section name is quoted. There may be a sequence of comma -separated flags: -@table @code -@item #alloc -section is allocatable -@item #write -section is writable -@item #execinstr -section is executable -@item #exclude -section is excluded from executable and shared library. -@item #tls -section is used for thread local storage -@end table - -This directive replaces the current section and subsection. See the -contents of the gas testsuite directory @code{gas/testsuite/gas/elf} for -some examples of how this directive and the other section stack directives -work. -@end ifset -@end ifset - -@node Set -@section @code{.set @var{symbol}, @var{expression}} - -@cindex @code{set} directive -@cindex symbol value, setting -Set the value of @var{symbol} to @var{expression}. This -changes @var{symbol}'s value and type to conform to -@var{expression}. If @var{symbol} was flagged as external, it remains -flagged (@pxref{Symbol Attributes}). - -You may @code{.set} a symbol many times in the same assembly. - -If you @code{.set} a global symbol, the value stored in the object -file is the last value stored into it. - -@ifset Z80 -On Z80 @code{set} is a real instruction, use -@samp{@var{symbol} defl @var{expression}} instead. -@end ifset - -@node Short -@section @code{.short @var{expressions}} - -@cindex @code{short} directive -@ifset GENERIC -@code{.short} is normally the same as @samp{.word}. -@xref{Word,,@code{.word}}. - -In some configurations, however, @code{.short} and @code{.word} generate -numbers of different lengths. @xref{Machine Dependencies}. -@end ifset -@ifclear GENERIC -@ifset W16 -@code{.short} is the same as @samp{.word}. @xref{Word,,@code{.word}}. -@end ifset -@ifset W32 -This expects zero or more @var{expressions}, and emits -a 16 bit number for each. -@end ifset -@end ifclear - -@node Single -@section @code{.single @var{flonums}} - -@cindex @code{single} directive -@cindex floating point numbers (single) -This directive assembles zero or more flonums, separated by commas. It -has the same effect as @code{.float}. -@ifset GENERIC -The exact kind of floating point numbers emitted depends on how -@command{@value{AS}} is configured. @xref{Machine Dependencies}. -@end ifset -@ifclear GENERIC -@ifset IEEEFLOAT -On the @value{TARGET} family, @code{.single} emits 32-bit floating point -numbers in @sc{ieee} format. -@end ifset -@end ifclear - -@ifset COFF-ELF -@node Size -@section @code{.size} - -This directive is used to set the size associated with a symbol. - -@ifset COFF -@ifset ELF -@c only print the extra heading if both COFF and ELF are set -@subheading COFF Version -@end ifset - -@cindex @code{size} directive (COFF version) -For COFF targets, the @code{.size} directive is only permitted inside -@code{.def}/@code{.endef} pairs. It is used like this: - -@smallexample -.size @var{expression} -@end smallexample - -@ifset BOUT -@samp{.size} is only meaningful when generating COFF format output; when -@command{@value{AS}} is generating @code{b.out}, it accepts this directive but -ignores it. -@end ifset -@end ifset - -@ifset ELF -@ifset COFF -@c only print the extra heading if both COFF and ELF are set -@subheading ELF Version -@end ifset - -@cindex @code{size} directive (ELF version) -For ELF targets, the @code{.size} directive is used like this: - -@smallexample -.size @var{name} , @var{expression} -@end smallexample - -This directive sets the size associated with a symbol @var{name}. -The size in bytes is computed from @var{expression} which can make use of label -arithmetic. This directive is typically used to set the size of function -symbols. -@end ifset -@end ifset - -@ifclear no-space-dir -@node Skip -@section @code{.skip @var{size} , @var{fill}} - -@cindex @code{skip} directive -@cindex filling memory -This directive emits @var{size} bytes, each of value @var{fill}. Both -@var{size} and @var{fill} are absolute expressions. If the comma and -@var{fill} are omitted, @var{fill} is assumed to be zero. This is the same as -@samp{.space}. -@end ifclear - -@node Sleb128 -@section @code{.sleb128 @var{expressions}} - -@cindex @code{sleb128} directive -@var{sleb128} stands for ``signed little endian base 128.'' This is a -compact, variable length representation of numbers used by the DWARF -symbolic debugging format. @xref{Uleb128, ,@code{.uleb128}}. - -@ifclear no-space-dir -@node Space -@section @code{.space @var{size} , @var{fill}} - -@cindex @code{space} directive -@cindex filling memory -This directive emits @var{size} bytes, each of value @var{fill}. Both -@var{size} and @var{fill} are absolute expressions. If the comma -and @var{fill} are omitted, @var{fill} is assumed to be zero. This is the same -as @samp{.skip}. - -@ifset HPPA -@quotation -@emph{Warning:} @code{.space} has a completely different meaning for HPPA -targets; use @code{.block} as a substitute. See @cite{HP9000 Series 800 -Assembly Language Reference Manual} (HP 92432-90001) for the meaning of the -@code{.space} directive. @xref{HPPA Directives,,HPPA Assembler Directives}, -for a summary. -@end quotation -@end ifset -@end ifclear - -@ifset have-stabs -@node Stab -@section @code{.stabd, .stabn, .stabs} - -@cindex symbolic debuggers, information for -@cindex @code{stab@var{x}} directives -There are three directives that begin @samp{.stab}. -All emit symbols (@pxref{Symbols}), for use by symbolic debuggers. -The symbols are not entered in the @command{@value{AS}} hash table: they -cannot be referenced elsewhere in the source file. -Up to five fields are required: - -@table @var -@item string -This is the symbol's name. It may contain any character except -@samp{\000}, so is more general than ordinary symbol names. Some -debuggers used to code arbitrarily complex structures into symbol names -using this field. - -@item type -An absolute expression. The symbol's type is set to the low 8 bits of -this expression. Any bit pattern is permitted, but @code{@value{LD}} -and debuggers choke on silly bit patterns. - -@item other -An absolute expression. The symbol's ``other'' attribute is set to the -low 8 bits of this expression. - -@item desc -An absolute expression. The symbol's descriptor is set to the low 16 -bits of this expression. - -@item value -An absolute expression which becomes the symbol's value. -@end table - -If a warning is detected while reading a @code{.stabd}, @code{.stabn}, -or @code{.stabs} statement, the symbol has probably already been created; -you get a half-formed symbol in your object file. This is -compatible with earlier assemblers! - -@table @code -@cindex @code{stabd} directive -@item .stabd @var{type} , @var{other} , @var{desc} - -The ``name'' of the symbol generated is not even an empty string. -It is a null pointer, for compatibility. Older assemblers used a -null pointer so they didn't waste space in object files with empty -strings. - -The symbol's value is set to the location counter, -relocatably. When your program is linked, the value of this symbol -is the address of the location counter when the @code{.stabd} was -assembled. - -@cindex @code{stabn} directive -@item .stabn @var{type} , @var{other} , @var{desc} , @var{value} -The name of the symbol is set to the empty string @code{""}. - -@cindex @code{stabs} directive -@item .stabs @var{string} , @var{type} , @var{other} , @var{desc} , @var{value} -All five fields are specified. -@end table -@end ifset -@c end have-stabs - -@node String -@section @code{.string} "@var{str}", @code{.string8} "@var{str}", @code{.string16} -"@var{str}", @code{.string32} "@var{str}", @code{.string64} "@var{str}" - -@cindex string, copying to object file -@cindex string8, copying to object file -@cindex string16, copying to object file -@cindex string32, copying to object file -@cindex string64, copying to object file -@cindex @code{string} directive -@cindex @code{string8} directive -@cindex @code{string16} directive -@cindex @code{string32} directive -@cindex @code{string64} directive - -Copy the characters in @var{str} to the object file. You may specify more than -one string to copy, separated by commas. Unless otherwise specified for a -particular machine, the assembler marks the end of each string with a 0 byte. -You can use any of the escape sequences described in @ref{Strings,,Strings}. - -The variants @code{string16}, @code{string32} and @code{string64} differ from -the @code{string} pseudo opcode in that each 8-bit character from @var{str} is -copied and expanded to 16, 32 or 64 bits respectively. The expanded characters -are stored in target endianness byte order. - -Example: -@smallexample - .string32 "BYE" -expands to: - .string "B\0\0\0Y\0\0\0E\0\0\0" /* On little endian targets. */ - .string "\0\0\0B\0\0\0Y\0\0\0E" /* On big endian targets. */ -@end smallexample - - -@node Struct -@section @code{.struct @var{expression}} - -@cindex @code{struct} directive -Switch to the absolute section, and set the section offset to @var{expression}, -which must be an absolute expression. You might use this as follows: -@smallexample - .struct 0 -field1: - .struct field1 + 4 -field2: - .struct field2 + 4 -field3: -@end smallexample -This would define the symbol @code{field1} to have the value 0, the symbol -@code{field2} to have the value 4, and the symbol @code{field3} to have the -value 8. Assembly would be left in the absolute section, and you would need to -use a @code{.section} directive of some sort to change to some other section -before further assembly. - -@ifset ELF -@node SubSection -@section @code{.subsection @var{name}} - -@cindex @code{subsection} directive -@cindex Section Stack -This is one of the ELF section stack manipulation directives. The others are -@code{.section} (@pxref{Section}), @code{.pushsection} (@pxref{PushSection}), -@code{.popsection} (@pxref{PopSection}), and @code{.previous} -(@pxref{Previous}). - -This directive replaces the current subsection with @code{name}. The current -section is not changed. The replaced subsection is put onto the section stack -in place of the then current top of stack subsection. -@end ifset - -@ifset ELF -@node Symver -@section @code{.symver} -@cindex @code{symver} directive -@cindex symbol versioning -@cindex versions of symbols -Use the @code{.symver} directive to bind symbols to specific version nodes -within a source file. This is only supported on ELF platforms, and is -typically used when assembling files to be linked into a shared library. -There are cases where it may make sense to use this in objects to be bound -into an application itself so as to override a versioned symbol from a -shared library. - -For ELF targets, the @code{.symver} directive can be used like this: -@smallexample -.symver @var{name}, @var{name2@@nodename} -@end smallexample -If the symbol @var{name} is defined within the file -being assembled, the @code{.symver} directive effectively creates a symbol -alias with the name @var{name2@@nodename}, and in fact the main reason that we -just don't try and create a regular alias is that the @var{@@} character isn't -permitted in symbol names. The @var{name2} part of the name is the actual name -of the symbol by which it will be externally referenced. The name @var{name} -itself is merely a name of convenience that is used so that it is possible to -have definitions for multiple versions of a function within a single source -file, and so that the compiler can unambiguously know which version of a -function is being mentioned. The @var{nodename} portion of the alias should be -the name of a node specified in the version script supplied to the linker when -building a shared library. If you are attempting to override a versioned -symbol from a shared library, then @var{nodename} should correspond to the -nodename of the symbol you are trying to override. - -If the symbol @var{name} is not defined within the file being assembled, all -references to @var{name} will be changed to @var{name2@@nodename}. If no -reference to @var{name} is made, @var{name2@@nodename} will be removed from the -symbol table. - -Another usage of the @code{.symver} directive is: -@smallexample -.symver @var{name}, @var{name2@@@@nodename} -@end smallexample -In this case, the symbol @var{name} must exist and be defined within -the file being assembled. It is similar to @var{name2@@nodename}. The -difference is @var{name2@@@@nodename} will also be used to resolve -references to @var{name2} by the linker. - -The third usage of the @code{.symver} directive is: -@smallexample -.symver @var{name}, @var{name2@@@@@@nodename} -@end smallexample -When @var{name} is not defined within the -file being assembled, it is treated as @var{name2@@nodename}. When -@var{name} is defined within the file being assembled, the symbol -name, @var{name}, will be changed to @var{name2@@@@nodename}. -@end ifset - -@ifset COFF -@node Tag -@section @code{.tag @var{structname}} - -@cindex COFF structure debugging -@cindex structure debugging, COFF -@cindex @code{tag} directive -This directive is generated by compilers to include auxiliary debugging -information in the symbol table. It is only permitted inside -@code{.def}/@code{.endef} pairs. Tags are used to link structure -definitions in the symbol table with instances of those structures. -@ifset BOUT - -@samp{.tag} is only used when generating COFF format output; when -@command{@value{AS}} is generating @code{b.out}, it accepts this directive but -ignores it. -@end ifset -@end ifset - -@node Text -@section @code{.text @var{subsection}} - -@cindex @code{text} directive -Tells @command{@value{AS}} to assemble the following statements onto the end of -the text subsection numbered @var{subsection}, which is an absolute -expression. If @var{subsection} is omitted, subsection number zero -is used. - -@node Title -@section @code{.title "@var{heading}"} - -@cindex @code{title} directive -@cindex listing control: title line -Use @var{heading} as the title (second line, immediately after the -source file name and pagenumber) when generating assembly listings. - -This directive affects subsequent pages, as well as the current page if -it appears within ten lines of the top of a page. - -@ifset COFF-ELF -@node Type -@section @code{.type} - -This directive is used to set the type of a symbol. - -@ifset COFF -@ifset ELF -@c only print the extra heading if both COFF and ELF are set -@subheading COFF Version -@end ifset - -@cindex COFF symbol type -@cindex symbol type, COFF -@cindex @code{type} directive (COFF version) -For COFF targets, this directive is permitted only within -@code{.def}/@code{.endef} pairs. It is used like this: - -@smallexample -.type @var{int} -@end smallexample - -This records the integer @var{int} as the type attribute of a symbol table -entry. - -@ifset BOUT -@samp{.type} is associated only with COFF format output; when -@command{@value{AS}} is configured for @code{b.out} output, it accepts this -directive but ignores it. -@end ifset -@end ifset - -@ifset ELF -@ifset COFF -@c only print the extra heading if both COFF and ELF are set -@subheading ELF Version -@end ifset - -@cindex ELF symbol type -@cindex symbol type, ELF -@cindex @code{type} directive (ELF version) -For ELF targets, the @code{.type} directive is used like this: - -@smallexample -.type @var{name} , @var{type description} -@end smallexample - -This sets the type of symbol @var{name} to be either a -function symbol or an object symbol. There are five different syntaxes -supported for the @var{type description} field, in order to provide -compatibility with various other assemblers. - -Because some of the characters used in these syntaxes (such as @samp{@@} and -@samp{#}) are comment characters for some architectures, some of the syntaxes -below do not work on all architectures. The first variant will be accepted by -the GNU assembler on all architectures so that variant should be used for -maximum portability, if you do not need to assemble your code with other -assemblers. - -The syntaxes supported are: - -@smallexample - .type STT_ - .type ,# - .type ,@@ - .type ,% - .type ,"" -@end smallexample - -The types supported are: - -@table @gcctabopt -@item STT_FUNC -@itemx function -Mark the symbol as being a function name. - -@item STT_GNU_IFUNC -@itemx gnu_indirect_function -Mark the symbol as an indirect function when evaluated during reloc -processing. (This is only supported on assemblers targeting GNU systems). - -@item STT_OBJECT -@itemx object -Mark the symbol as being a data object. - -@item STT_TLS -@itemx tls_object -Mark the symbol as being a thead-local data object. - -@item STT_COMMON -@itemx common -Mark the symbol as being a common data object. - -@item STT_NOTYPE -@itemx notype -Does not mark the symbol in any way. It is supported just for completeness. - -@item gnu_unique_object -Marks the symbol as being a globally unique data object. The dynamic linker -will make sure that in the entire process there is just one symbol with this -name and type in use. (This is only supported on assemblers targeting GNU -systems). - -@end table - -Note: Some targets support extra types in addition to those listed above. - -@end ifset -@end ifset - -@node Uleb128 -@section @code{.uleb128 @var{expressions}} - -@cindex @code{uleb128} directive -@var{uleb128} stands for ``unsigned little endian base 128.'' This is a -compact, variable length representation of numbers used by the DWARF -symbolic debugging format. @xref{Sleb128, ,@code{.sleb128}}. - -@ifset COFF -@node Val -@section @code{.val @var{addr}} - -@cindex @code{val} directive -@cindex COFF value attribute -@cindex value attribute, COFF -This directive, permitted only within @code{.def}/@code{.endef} pairs, -records the address @var{addr} as the value attribute of a symbol table -entry. -@ifset BOUT - -@samp{.val} is used only for COFF output; when @command{@value{AS}} is -configured for @code{b.out}, it accepts this directive but ignores it. -@end ifset -@end ifset - -@ifset ELF -@node Version -@section @code{.version "@var{string}"} - -@cindex @code{version} directive -This directive creates a @code{.note} section and places into it an ELF -formatted note of type NT_VERSION. The note's name is set to @code{string}. -@end ifset - -@ifset ELF -@node VTableEntry -@section @code{.vtable_entry @var{table}, @var{offset}} - -@cindex @code{vtable_entry} directive -This directive finds or creates a symbol @code{table} and creates a -@code{VTABLE_ENTRY} relocation for it with an addend of @code{offset}. - -@node VTableInherit -@section @code{.vtable_inherit @var{child}, @var{parent}} - -@cindex @code{vtable_inherit} directive -This directive finds the symbol @code{child} and finds or creates the symbol -@code{parent} and then creates a @code{VTABLE_INHERIT} relocation for the -parent whose addend is the value of the child symbol. As a special case the -parent name of @code{0} is treated as referring to the @code{*ABS*} section. -@end ifset - -@node Warning -@section @code{.warning "@var{string}"} -@cindex warning directive -Similar to the directive @code{.error} -(@pxref{Error,,@code{.error "@var{string}"}}), but just emits a warning. - -@node Weak -@section @code{.weak @var{names}} - -@cindex @code{weak} directive -This directive sets the weak attribute on the comma separated list of symbol -@code{names}. If the symbols do not already exist, they will be created. - -On COFF targets other than PE, weak symbols are a GNU extension. This -directive sets the weak attribute on the comma separated list of symbol -@code{names}. If the symbols do not already exist, they will be created. - -On the PE target, weak symbols are supported natively as weak aliases. -When a weak symbol is created that is not an alias, GAS creates an -alternate symbol to hold the default value. - -@node Weakref -@section @code{.weakref @var{alias}, @var{target}} - -@cindex @code{weakref} directive -This directive creates an alias to the target symbol that enables the symbol to -be referenced with weak-symbol semantics, but without actually making it weak. -If direct references or definitions of the symbol are present, then the symbol -will not be weak, but if all references to it are through weak references, the -symbol will be marked as weak in the symbol table. - -The effect is equivalent to moving all references to the alias to a separate -assembly source file, renaming the alias to the symbol in it, declaring the -symbol as weak there, and running a reloadable link to merge the object files -resulting from the assembly of the new source file and the old source file that -had the references to the alias removed. - -The alias itself never makes to the symbol table, and is entirely handled -within the assembler. - -@node Word -@section @code{.word @var{expressions}} - -@cindex @code{word} directive -This directive expects zero or more @var{expressions}, of any section, -separated by commas. -@ifclear GENERIC -@ifset W32 -For each expression, @command{@value{AS}} emits a 32-bit number. -@end ifset -@ifset W16 -For each expression, @command{@value{AS}} emits a 16-bit number. -@end ifset -@end ifclear -@ifset GENERIC - -The size of the number emitted, and its byte order, -depend on what target computer the assembly is for. -@end ifset - -@c on amd29k, i960, sparc the "special treatment to support compilers" doesn't -@c happen---32-bit addressability, period; no long/short jumps. -@ifset DIFF-TBL-KLUGE -@cindex difference tables altered -@cindex altered difference tables -@quotation -@emph{Warning: Special Treatment to support Compilers} -@end quotation - -@ifset GENERIC -Machines with a 32-bit address space, but that do less than 32-bit -addressing, require the following special treatment. If the machine of -interest to you does 32-bit addressing (or doesn't require it; -@pxref{Machine Dependencies}), you can ignore this issue. - -@end ifset -In order to assemble compiler output into something that works, -@command{@value{AS}} occasionally does strange things to @samp{.word} directives. -Directives of the form @samp{.word sym1-sym2} are often emitted by -compilers as part of jump tables. Therefore, when @command{@value{AS}} assembles a -directive of the form @samp{.word sym1-sym2}, and the difference between -@code{sym1} and @code{sym2} does not fit in 16 bits, @command{@value{AS}} -creates a @dfn{secondary jump table}, immediately before the next label. -This secondary jump table is preceded by a short-jump to the -first byte after the secondary table. This short-jump prevents the flow -of control from accidentally falling into the new table. Inside the -table is a long-jump to @code{sym2}. The original @samp{.word} -contains @code{sym1} minus the address of the long-jump to -@code{sym2}. - -If there were several occurrences of @samp{.word sym1-sym2} before the -secondary jump table, all of them are adjusted. If there was a -@samp{.word sym3-sym4}, that also did not fit in sixteen bits, a -long-jump to @code{sym4} is included in the secondary jump table, -and the @code{.word} directives are adjusted to contain @code{sym3} -minus the address of the long-jump to @code{sym4}; and so on, for as many -entries in the original jump table as necessary. - -@ifset INTERNALS -@emph{This feature may be disabled by compiling @command{@value{AS}} with the -@samp{-DWORKING_DOT_WORD} option.} This feature is likely to confuse -assembly language programmers. -@end ifset -@end ifset -@c end DIFF-TBL-KLUGE - -@node Deprecated -@section Deprecated Directives - -@cindex deprecated directives -@cindex obsolescent directives -One day these directives won't work. -They are included for compatibility with older assemblers. -@table @t -@item .abort -@item .line -@end table - -@ifset ELF -@node Object Attributes -@chapter Object Attributes -@cindex object attributes - -@command{@value{AS}} assembles source files written for a specific architecture -into object files for that architecture. But not all object files are alike. -Many architectures support incompatible variations. For instance, floating -point arguments might be passed in floating point registers if the object file -requires hardware floating point support---or floating point arguments might be -passed in integer registers if the object file supports processors with no -hardware floating point unit. Or, if two objects are built for different -generations of the same architecture, the combination may require the -newer generation at run-time. - -This information is useful during and after linking. At link time, -@command{@value{LD}} can warn about incompatible object files. After link -time, tools like @command{gdb} can use it to process the linked file -correctly. - -Compatibility information is recorded as a series of object attributes. Each -attribute has a @dfn{vendor}, @dfn{tag}, and @dfn{value}. The vendor is a -string, and indicates who sets the meaning of the tag. The tag is an integer, -and indicates what property the attribute describes. The value may be a string -or an integer, and indicates how the property affects this object. Missing -attributes are the same as attributes with a zero value or empty string value. - -Object attributes were developed as part of the ABI for the ARM Architecture. -The file format is documented in @cite{ELF for the ARM Architecture}. - -@menu -* GNU Object Attributes:: @sc{gnu} Object Attributes -* Defining New Object Attributes:: Defining New Object Attributes -@end menu - -@node GNU Object Attributes -@section @sc{gnu} Object Attributes - -The @code{.gnu_attribute} directive records an object attribute -with vendor @samp{gnu}. - -Except for @samp{Tag_compatibility}, which has both an integer and a string for -its value, @sc{gnu} attributes have a string value if the tag number is odd and -an integer value if the tag number is even. The second bit (@code{@var{tag} & -2} is set for architecture-independent attributes and clear for -architecture-dependent ones. - -@subsection Common @sc{gnu} attributes - -These attributes are valid on all architectures. - -@table @r -@item Tag_compatibility (32) -The compatibility attribute takes an integer flag value and a vendor name. If -the flag value is 0, the file is compatible with other toolchains. If it is 1, -then the file is only compatible with the named toolchain. If it is greater -than 1, the file can only be processed by other toolchains under some private -arrangement indicated by the flag value and the vendor name. -@end table - -@subsection MIPS Attributes - -@table @r -@item Tag_GNU_MIPS_ABI_FP (4) -The floating-point ABI used by this object file. The value will be: - -@itemize @bullet -@item -0 for files not affected by the floating-point ABI. -@item -1 for files using the hardware floating-point with a standard double-precision -FPU. -@item -2 for files using the hardware floating-point ABI with a single-precision FPU. -@item -3 for files using the software floating-point ABI. -@item -4 for files using the hardware floating-point ABI with 64-bit wide -double-precision floating-point registers and 32-bit wide general -purpose registers. -@end itemize -@end table - -@subsection PowerPC Attributes - -@table @r -@item Tag_GNU_Power_ABI_FP (4) -The floating-point ABI used by this object file. The value will be: - -@itemize @bullet -@item -0 for files not affected by the floating-point ABI. -@item -1 for files using double-precision hardware floating-point ABI. -@item -2 for files using the software floating-point ABI. -@item -3 for files using single-precision hardware floating-point ABI. -@end itemize - -@item Tag_GNU_Power_ABI_Vector (8) -The vector ABI used by this object file. The value will be: - -@itemize @bullet -@item -0 for files not affected by the vector ABI. -@item -1 for files using general purpose registers to pass vectors. -@item -2 for files using AltiVec registers to pass vectors. -@item -3 for files using SPE registers to pass vectors. -@end itemize -@end table - -@node Defining New Object Attributes -@section Defining New Object Attributes - -If you want to define a new @sc{gnu} object attribute, here are the places you -will need to modify. New attributes should be discussed on the @samp{binutils} -mailing list. - -@itemize @bullet -@item -This manual, which is the official register of attributes. -@item -The header for your architecture @file{include/elf}, to define the tag. -@item -The @file{bfd} support file for your architecture, to merge the attribute -and issue any appropriate link warnings. -@item -Test cases in @file{ld/testsuite} for merging and link warnings. -@item -@file{binutils/readelf.c} to display your attribute. -@item -GCC, if you want the compiler to mark the attribute automatically. -@end itemize - -@end ifset - -@ifset GENERIC -@node Machine Dependencies -@chapter Machine Dependent Features - -@cindex machine dependencies -The machine instruction sets are (almost by definition) different on -each machine where @command{@value{AS}} runs. Floating point representations -vary as well, and @command{@value{AS}} often supports a few additional -directives or command-line options for compatibility with other -assemblers on a particular platform. Finally, some versions of -@command{@value{AS}} support special pseudo-instructions for branch -optimization. - -This chapter discusses most of these differences, though it does not -include details on any machine's instruction set. For details on that -subject, see the hardware manufacturer's manual. - -@menu -@ifset ALPHA -* Alpha-Dependent:: Alpha Dependent Features -@end ifset -@ifset ARC -* ARC-Dependent:: ARC Dependent Features -@end ifset -@ifset ARM -* ARM-Dependent:: ARM Dependent Features -@end ifset -@ifset AVR -* AVR-Dependent:: AVR Dependent Features -@end ifset -@ifset Blackfin -* Blackfin-Dependent:: Blackfin Dependent Features -@end ifset -@ifset CR16 -* CR16-Dependent:: CR16 Dependent Features -@end ifset -@ifset CRIS -* CRIS-Dependent:: CRIS Dependent Features -@end ifset -@ifset D10V -* D10V-Dependent:: D10V Dependent Features -@end ifset -@ifset D30V -* D30V-Dependent:: D30V Dependent Features -@end ifset -@ifset H8/300 -* H8/300-Dependent:: Renesas H8/300 Dependent Features -@end ifset -@ifset HPPA -* HPPA-Dependent:: HPPA Dependent Features -@end ifset -@ifset I370 -* ESA/390-Dependent:: IBM ESA/390 Dependent Features -@end ifset -@ifset I80386 -* i386-Dependent:: Intel 80386 and AMD x86-64 Dependent Features -@end ifset -@ifset I860 -* i860-Dependent:: Intel 80860 Dependent Features -@end ifset -@ifset I960 -* i960-Dependent:: Intel 80960 Dependent Features -@end ifset -@ifset IA64 -* IA-64-Dependent:: Intel IA-64 Dependent Features -@end ifset -@ifset IP2K -* IP2K-Dependent:: IP2K Dependent Features -@end ifset -@ifset LM32 -* LM32-Dependent:: LM32 Dependent Features -@end ifset -@ifset M32C -* M32C-Dependent:: M32C Dependent Features -@end ifset -@ifset M32R -* M32R-Dependent:: M32R Dependent Features -@end ifset -@ifset M680X0 -* M68K-Dependent:: M680x0 Dependent Features -@end ifset -@ifset M68HC11 -* M68HC11-Dependent:: M68HC11 and 68HC12 Dependent Features -@end ifset -@ifset MICROBLAZE -* MicroBlaze-Dependent:: MICROBLAZE Dependent Features -@end ifset -@ifset MIPS -* MIPS-Dependent:: MIPS Dependent Features -@end ifset -@ifset MMIX -* MMIX-Dependent:: MMIX Dependent Features -@end ifset -@ifset MSP430 -* MSP430-Dependent:: MSP430 Dependent Features -@end ifset -@ifset NS32K -* NS32K-Dependent:: NS32K Dependent Features -@end ifset -@ifset SH -* SH-Dependent:: Renesas / SuperH SH Dependent Features -* SH64-Dependent:: SuperH SH64 Dependent Features -@end ifset -@ifset PDP11 -* PDP-11-Dependent:: PDP-11 Dependent Features -@end ifset -@ifset PJ -* PJ-Dependent:: picoJava Dependent Features -@end ifset -@ifset PPC -* PPC-Dependent:: PowerPC Dependent Features -@end ifset -@ifset RX -* RX-Dependent:: RX Dependent Features -@end ifset -@ifset S390 -* S/390-Dependent:: IBM S/390 Dependent Features -@end ifset -@ifset SCORE -* SCORE-Dependent:: SCORE Dependent Features -@end ifset -@ifset SPARC -* Sparc-Dependent:: SPARC Dependent Features -@end ifset -@ifset TIC54X -* TIC54X-Dependent:: TI TMS320C54x Dependent Features -@end ifset -@ifset TIC6X -* TIC6X-Dependent :: TI TMS320C6x Dependent Features -@end ifset -@ifset TILEGX -* TILE-Gx-Dependent :: Tilera TILE-Gx Dependent Features -@end ifset -@ifset TILEPRO -* TILEPro-Dependent :: Tilera TILEPro Dependent Features -@end ifset -@ifset V850 -* V850-Dependent:: V850 Dependent Features -@end ifset -@ifset XSTORMY16 -* XSTORMY16-Dependent:: XStormy16 Dependent Features -@end ifset -@ifset XTENSA -* Xtensa-Dependent:: Xtensa Dependent Features -@end ifset -@ifset Z80 -* Z80-Dependent:: Z80 Dependent Features -@end ifset -@ifset Z8000 -* Z8000-Dependent:: Z8000 Dependent Features -@end ifset -@ifset VAX -* Vax-Dependent:: VAX Dependent Features -@end ifset -@end menu - -@lowersections -@end ifset - -@c The following major nodes are *sections* in the GENERIC version, *chapters* -@c in single-cpu versions. This is mainly achieved by @lowersections. There is a -@c peculiarity: to preserve cross-references, there must be a node called -@c "Machine Dependencies". Hence the conditional nodenames in each -@c major node below. Node defaulting in makeinfo requires adjacency of -@c node and sectioning commands; hence the repetition of @chapter BLAH -@c in both conditional blocks. - -@ifset ALPHA -@include c-alpha.texi -@end ifset - -@ifset ARC -@include c-arc.texi -@end ifset - -@ifset ARM -@include c-arm.texi -@end ifset - -@ifset AVR -@include c-avr.texi -@end ifset - -@ifset Blackfin -@include c-bfin.texi -@end ifset - -@ifset CR16 -@include c-cr16.texi -@end ifset - -@ifset CRIS -@include c-cris.texi -@end ifset - -@ifset Renesas-all -@ifclear GENERIC -@node Machine Dependencies -@chapter Machine Dependent Features - -The machine instruction sets are different on each Renesas chip family, -and there are also some syntax differences among the families. This -chapter describes the specific @command{@value{AS}} features for each -family. - -@menu -* H8/300-Dependent:: Renesas H8/300 Dependent Features -* SH-Dependent:: Renesas SH Dependent Features -@end menu -@lowersections -@end ifclear -@end ifset - -@ifset D10V -@include c-d10v.texi -@end ifset - -@ifset D30V -@include c-d30v.texi -@end ifset - -@ifset H8/300 -@include c-h8300.texi -@end ifset - -@ifset HPPA -@include c-hppa.texi -@end ifset - -@ifset I370 -@include c-i370.texi -@end ifset - -@ifset I80386 -@include c-i386.texi -@end ifset - -@ifset I860 -@include c-i860.texi -@end ifset - -@ifset I960 -@include c-i960.texi -@end ifset - -@ifset IA64 -@include c-ia64.texi -@end ifset - -@ifset IP2K -@include c-ip2k.texi -@end ifset - -@ifset LM32 -@include c-lm32.texi -@end ifset - -@ifset M32C -@include c-m32c.texi -@end ifset - -@ifset M32R -@include c-m32r.texi -@end ifset - -@ifset M680X0 -@include c-m68k.texi -@end ifset - -@ifset M68HC11 -@include c-m68hc11.texi -@end ifset - -@ifset MICROBLAZE -@include c-microblaze.texi -@end ifset - -@ifset MIPS -@include c-mips.texi -@end ifset - -@ifset MMIX -@include c-mmix.texi -@end ifset - -@ifset MSP430 -@include c-msp430.texi -@end ifset - -@ifset NS32K -@include c-ns32k.texi -@end ifset - -@ifset PDP11 -@include c-pdp11.texi -@end ifset - -@ifset PJ -@include c-pj.texi -@end ifset - -@ifset PPC -@include c-ppc.texi -@end ifset - -@ifset RX -@include c-rx.texi -@end ifset - -@ifset S390 -@include c-s390.texi -@end ifset - -@ifset SCORE -@include c-score.texi -@end ifset - -@ifset SH -@include c-sh.texi -@include c-sh64.texi -@end ifset - -@ifset SPARC -@include c-sparc.texi -@end ifset - -@ifset TIC54X -@include c-tic54x.texi -@end ifset - -@ifset TIC6X -@include c-tic6x.texi -@end ifset - -@ifset TILEGX -@include c-tilegx.texi -@end ifset - -@ifset TILEPRO -@include c-tilepro.texi -@end ifset - -@ifset Z80 -@include c-z80.texi -@end ifset - -@ifset Z8000 -@include c-z8k.texi -@end ifset - -@ifset VAX -@include c-vax.texi -@end ifset - -@ifset V850 -@include c-v850.texi -@end ifset - -@ifset XSTORMY16 -@include c-xstormy16.texi -@end ifset - -@ifset XTENSA -@include c-xtensa.texi -@end ifset - -@ifset GENERIC -@c reverse effect of @down at top of generic Machine-Dep chapter -@raisesections -@end ifset - -@node Reporting Bugs -@chapter Reporting Bugs -@cindex bugs in assembler -@cindex reporting bugs in assembler - -Your bug reports play an essential role in making @command{@value{AS}} reliable. - -Reporting a bug may help you by bringing a solution to your problem, or it may -not. But in any case the principal function of a bug report is to help the -entire community by making the next version of @command{@value{AS}} work better. -Bug reports are your contribution to the maintenance of @command{@value{AS}}. - -In order for a bug report to serve its purpose, you must include the -information that enables us to fix the bug. - -@menu -* Bug Criteria:: Have you found a bug? -* Bug Reporting:: How to report bugs -@end menu - -@node Bug Criteria -@section Have You Found a Bug? -@cindex bug criteria - -If you are not sure whether you have found a bug, here are some guidelines: - -@itemize @bullet -@cindex fatal signal -@cindex assembler crash -@cindex crash of assembler -@item -If the assembler gets a fatal signal, for any input whatever, that is a -@command{@value{AS}} bug. Reliable assemblers never crash. - -@cindex error on valid input -@item -If @command{@value{AS}} produces an error message for valid input, that is a bug. - -@cindex invalid input -@item -If @command{@value{AS}} does not produce an error message for invalid input, that -is a bug. However, you should note that your idea of ``invalid input'' might -be our idea of ``an extension'' or ``support for traditional practice''. - -@item -If you are an experienced user of assemblers, your suggestions for improvement -of @command{@value{AS}} are welcome in any case. -@end itemize - -@node Bug Reporting -@section How to Report Bugs -@cindex bug reports -@cindex assembler bugs, reporting - -A number of companies and individuals offer support for @sc{gnu} products. If -you obtained @command{@value{AS}} from a support organization, we recommend you -contact that organization first. - -You can find contact information for many support companies and -individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs -distribution. - -@ifset BUGURL -In any event, we also recommend that you send bug reports for @command{@value{AS}} -to @value{BUGURL}. -@end ifset - -The fundamental principle of reporting bugs usefully is this: -@strong{report all the facts}. If you are not sure whether to state a -fact or leave it out, state it! - -Often people omit facts because they think they know what causes the problem -and assume that some details do not matter. Thus, you might assume that the -name of a symbol you use in an example does not matter. Well, probably it does -not, but one cannot be sure. Perhaps the bug is a stray memory reference which -happens to fetch from the location where that name is stored in memory; -perhaps, if the name were different, the contents of that location would fool -the assembler into doing the right thing despite the bug. Play it safe and -give a specific, complete example. That is the easiest thing for you to do, -and the most helpful. - -Keep in mind that the purpose of a bug report is to enable us to fix the bug if -it is new to us. Therefore, always write your bug reports on the assumption -that the bug has not been reported previously. - -Sometimes people give a few sketchy facts and ask, ``Does this ring a -bell?'' This cannot help us fix a bug, so it is basically useless. We -respond by asking for enough details to enable us to investigate. -You might as well expedite matters by sending them to begin with. - -To enable us to fix the bug, you should include all these things: - -@itemize @bullet -@item -The version of @command{@value{AS}}. @command{@value{AS}} announces it if you start -it with the @samp{--version} argument. - -Without this, we will not know whether there is any point in looking for -the bug in the current version of @command{@value{AS}}. - -@item -Any patches you may have applied to the @command{@value{AS}} source. - -@item -The type of machine you are using, and the operating system name and -version number. - -@item -What compiler (and its version) was used to compile @command{@value{AS}}---e.g. -``@code{gcc-2.7}''. - -@item -The command arguments you gave the assembler to assemble your example and -observe the bug. To guarantee you will not omit something important, list them -all. A copy of the Makefile (or the output from make) is sufficient. - -If we were to try to guess the arguments, we would probably guess wrong -and then we might not encounter the bug. - -@item -A complete input file that will reproduce the bug. If the bug is observed when -the assembler is invoked via a compiler, send the assembler source, not the -high level language source. Most compilers will produce the assembler source -when run with the @samp{-S} option. If you are using @code{@value{GCC}}, use -the options @samp{-v --save-temps}; this will save the assembler source in a -file with an extension of @file{.s}, and also show you exactly how -@command{@value{AS}} is being run. - -@item -A description of what behavior you observe that you believe is -incorrect. For example, ``It gets a fatal signal.'' - -Of course, if the bug is that @command{@value{AS}} gets a fatal signal, then we -will certainly notice it. But if the bug is incorrect output, we might not -notice unless it is glaringly wrong. You might as well not give us a chance to -make a mistake. - -Even if the problem you experience is a fatal signal, you should still say so -explicitly. Suppose something strange is going on, such as, your copy of -@command{@value{AS}} is out of sync, or you have encountered a bug in the C -library on your system. (This has happened!) Your copy might crash and ours -would not. If you told us to expect a crash, then when ours fails to crash, we -would know that the bug was not happening for us. If you had not told us to -expect a crash, then we would not be able to draw any conclusion from our -observations. - -@item -If you wish to suggest changes to the @command{@value{AS}} source, send us context -diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or @samp{-p} -option. Always send diffs from the old file to the new file. If you even -discuss something in the @command{@value{AS}} source, refer to it by context, not -by line number. - -The line numbers in our development sources will not match those in your -sources. Your line numbers would convey no useful information to us. -@end itemize - -Here are some things that are not necessary: - -@itemize @bullet -@item -A description of the envelope of the bug. - -Often people who encounter a bug spend a lot of time investigating -which changes to the input file will make the bug go away and which -changes will not affect it. - -This is often time consuming and not very useful, because the way we -will find the bug is by running a single example under the debugger -with breakpoints, not by pure deduction from a series of examples. -We recommend that you save your time for something else. - -Of course, if you can find a simpler example to report @emph{instead} -of the original one, that is a convenience for us. Errors in the -output will be easier to spot, running under the debugger will take -less time, and so on. - -However, simplification is not vital; if you do not want to do this, -report the bug anyway and send us the entire test case you used. - -@item -A patch for the bug. - -A patch for the bug does help us if it is a good one. But do not omit -the necessary information, such as the test case, on the assumption that -a patch is all we need. We might see problems with your patch and decide -to fix the problem another way, or we might not understand it at all. - -Sometimes with a program as complicated as @command{@value{AS}} it is very hard to -construct an example that will make the program follow a certain path through -the code. If you do not send us the example, we will not be able to construct -one, so we will not be able to verify that the bug is fixed. - -And if we cannot understand what bug you are trying to fix, or why your -patch should be an improvement, we will not install it. A test case will -help us to understand. - -@item -A guess about what the bug is or what it depends on. - -Such guesses are usually wrong. Even we cannot guess right about such -things without first using the debugger to find the facts. -@end itemize - -@node Acknowledgements -@chapter Acknowledgements - -If you have contributed to GAS and your name isn't listed here, -it is not meant as a slight. We just don't know about it. Send mail to the -maintainer, and we'll correct the situation. Currently -@c (January 1994), -the maintainer is Ken Raeburn (email address @code{raeburn@@cygnus.com}). - -Dean Elsner wrote the original @sc{gnu} assembler for the VAX.@footnote{Any -more details?} - -Jay Fenlason maintained GAS for a while, adding support for GDB-specific debug -information and the 68k series machines, most of the preprocessing pass, and -extensive changes in @file{messages.c}, @file{input-file.c}, @file{write.c}. - -K. Richard Pixley maintained GAS for a while, adding various enhancements and -many bug fixes, including merging support for several processors, breaking GAS -up to handle multiple object file format back ends (including heavy rewrite, -testing, an integration of the coff and b.out back ends), adding configuration -including heavy testing and verification of cross assemblers and file splits -and renaming, converted GAS to strictly ANSI C including full prototypes, added -support for m680[34]0 and cpu32, did considerable work on i960 including a COFF -port (including considerable amounts of reverse engineering), a SPARC opcode -file rewrite, DECstation, rs6000, and hp300hpux host ports, updated ``know'' -assertions and made them work, much other reorganization, cleanup, and lint. - -Ken Raeburn wrote the high-level BFD interface code to replace most of the code -in format-specific I/O modules. - -The original VMS support was contributed by David L. Kashtan. Eric Youngdale -has done much work with it since. - -The Intel 80386 machine description was written by Eliot Dresselhaus. - -Minh Tran-Le at IntelliCorp contributed some AIX 386 support. - -The Motorola 88k machine description was contributed by Devon Bowen of Buffalo -University and Torbjorn Granlund of the Swedish Institute of Computer Science. - -Keith Knowles at the Open Software Foundation wrote the original MIPS back end -(@file{tc-mips.c}, @file{tc-mips.h}), and contributed Rose format support -(which hasn't been merged in yet). Ralph Campbell worked with the MIPS code to -support a.out format. - -Support for the Zilog Z8k and Renesas H8/300 processors (tc-z8k, -tc-h8300), and IEEE 695 object file format (obj-ieee), was written by -Steve Chamberlain of Cygnus Support. Steve also modified the COFF back end to -use BFD for some low-level operations, for use with the H8/300 and AMD 29k -targets. - -John Gilmore built the AMD 29000 support, added @code{.include} support, and -simplified the configuration of which versions accept which directives. He -updated the 68k machine description so that Motorola's opcodes always produced -fixed-size instructions (e.g., @code{jsr}), while synthetic instructions -remained shrinkable (@code{jbsr}). John fixed many bugs, including true tested -cross-compilation support, and one bug in relaxation that took a week and -required the proverbial one-bit fix. - -Ian Lance Taylor of Cygnus Support merged the Motorola and MIT syntax for the -68k, completed support for some COFF targets (68k, i386 SVR3, and SCO Unix), -added support for MIPS ECOFF and ELF targets, wrote the initial RS/6000 and -PowerPC assembler, and made a few other minor patches. - -Steve Chamberlain made GAS able to generate listings. - -Hewlett-Packard contributed support for the HP9000/300. - -Jeff Law wrote GAS and BFD support for the native HPPA object format (SOM) -along with a fairly extensive HPPA testsuite (for both SOM and ELF object -formats). This work was supported by both the Center for Software Science at -the University of Utah and Cygnus Support. - -Support for ELF format files has been worked on by Mark Eichin of Cygnus -Support (original, incomplete implementation for SPARC), Pete Hoogenboom and -Jeff Law at the University of Utah (HPPA mainly), Michael Meissner of the Open -Software Foundation (i386 mainly), and Ken Raeburn of Cygnus Support (sparc, -and some initial 64-bit support). - -Linas Vepstas added GAS support for the ESA/390 ``IBM 370'' architecture. - -Richard Henderson rewrote the Alpha assembler. Klaus Kaempf wrote GAS and BFD -support for openVMS/Alpha. - -Timothy Wall, Michael Hayes, and Greg Smart contributed to the various tic* -flavors. - -David Heine, Sterling Augustine, Bob Wilson and John Ruttenberg from Tensilica, -Inc.@: added support for Xtensa processors. - -Several engineers at Cygnus Support have also provided many small bug fixes and -configuration enhancements. - -Jon Beniston added support for the Lattice Mico32 architecture. - -Many others have contributed large or small bugfixes and enhancements. If -you have contributed significant work and are not mentioned on this list, and -want to be, let us know. Some of the history has been lost; we are not -intentionally leaving anyone out. - -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@include fdl.texi - -@node AS Index -@unnumbered AS Index - -@printindex cp - -@bye -@c Local Variables: -@c fill-column: 79 -@c End: diff --git a/contrib/binutils-2.22/gas/doc/asconfig.texi b/contrib/binutils-2.22/gas/doc/asconfig.texi deleted file mode 100644 index 6f935ad5b7..0000000000 --- a/contrib/binutils-2.22/gas/doc/asconfig.texi +++ /dev/null @@ -1,101 +0,0 @@ -@c Copyright 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, -@c 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 -@c Free Software Foundation, Inc. -@c This file is part of the documentation for the GAS manual - -@c Configuration settings for all-inclusive version of manual - -@c switches:------------------------------------------------------------ -@c Properties of the manual -@c ======================== -@c Discuss all architectures? -@set ALL-ARCH -@c A generic form of manual (not tailored to specific target)? -@set GENERIC -@c Include text on assembler internals? -@clear INTERNALS -@c Many object formats supported in this config? -@set MULTI-OBJ - -@c Object formats of interest -@c ========================== -@set AOUT -@set COFF -@set ELF -@set SOM - -@c CPUs of interest -@c ================ -@set ALPHA -@set ARC -@set ARM -@set AVR -@set Blackfin -@set CR16 -@set CRIS -@set D10V -@set D30V -@set H8/300 -@set HPPA -@set I370 -@set I80386 -@set I860 -@set I960 -@set IA64 -@set IP2K -@set LM32 -@set M32C -@set M32R -@set xc16x -@set M68HC11 -@set M680X0 -@set MCORE -@set MICROBLAZE -@set MIPS -@set MMIX -@set MS1 -@set MSP430 -@set NS32K -@set PDP11 -@set PJ -@set PPC -@set RX -@set S390 -@set SCORE -@set SH -@set SPARC -@set TIC54X -@set TIC6X -@set TILEGX -@set TILEPRO -@set V850 -@set VAX -@set XSTORMY16 -@set XTENSA -@set Z80 -@set Z8000 - -@c Does this version of the assembler use the difference-table kludge? -@set DIFF-TBL-KLUGE - -@c Do all machines described use IEEE floating point? -@clear IEEEFLOAT - -@c Is a word 32 bits, or 16? -@clear W32 -@set W16 - -@c Do symbols have different characters than usual? -@clear SPECIAL-SYMS - -@c strings:------------------------------------------------------------ -@c Name of the assembler: -@set AS as -@c Name of C compiler: -@set GCC gcc -@c Name of linker: -@set LD ld -@c Text for target machine (best not used in generic case; but just in case...) -@set TARGET machine specific -@c Name of object format NOT SET in generic version -@clear OBJ-NAME diff --git a/contrib/binutils-2.22/gas/doc/c-alpha.texi b/contrib/binutils-2.22/gas/doc/c-alpha.texi deleted file mode 100644 index 8e2c11b464..0000000000 --- a/contrib/binutils-2.22/gas/doc/c-alpha.texi +++ /dev/null @@ -1,487 +0,0 @@ -@c Copyright 2002, 2003, 2005, 2009, 2011 -@c Free Software Foundation, Inc. -@c This is part of the GAS manual. -@c For copying conditions, see the file as.texinfo. -@c man end - -@ifset GENERIC -@page -@node Alpha-Dependent -@chapter Alpha Dependent Features -@end ifset - -@ifclear GENERIC -@node Machine Dependencies -@chapter Alpha Dependent Features -@end ifclear - -@cindex Alpha support -@menu -* Alpha Notes:: Notes -* Alpha Options:: Options -* Alpha Syntax:: Syntax -* Alpha Floating Point:: Floating Point -* Alpha Directives:: Alpha Machine Directives -* Alpha Opcodes:: Opcodes -@end menu - -@node Alpha Notes -@section Notes -@cindex Alpha notes -@cindex notes for Alpha - -The documentation here is primarily for the ELF object format. -@code{@value{AS}} also supports the ECOFF and EVAX formats, but -features specific to these formats are not yet documented. - -@node Alpha Options -@section Options -@cindex Alpha options -@cindex options for Alpha - -@c man begin OPTIONS -@table @gcctabopt -@cindex @code{-m@var{cpu}} command line option, Alpha -@item -m@var{cpu} -This option specifies the target processor. If an attempt is made to -assemble an instruction which will not execute on the target processor, -the assembler may either expand the instruction as a macro or issue an -error message. This option is equivalent to the @code{.arch} directive. - -The following processor names are recognized: -@code{21064}, -@code{21064a}, -@code{21066}, -@code{21068}, -@code{21164}, -@code{21164a}, -@code{21164pc}, -@code{21264}, -@code{21264a}, -@code{21264b}, -@code{ev4}, -@code{ev5}, -@code{lca45}, -@code{ev5}, -@code{ev56}, -@code{pca56}, -@code{ev6}, -@code{ev67}, -@code{ev68}. -The special name @code{all} may be used to allow the assembler to accept -instructions valid for any Alpha processor. - -In order to support existing practice in OSF/1 with respect to @code{.arch}, -and existing practice within @command{MILO} (the Linux ARC bootloader), the -numbered processor names (e.g.@: 21064) enable the processor-specific PALcode -instructions, while the ``electro-vlasic'' names (e.g.@: @code{ev4}) do not. - -@cindex @code{-mdebug} command line option, Alpha -@cindex @code{-no-mdebug} command line option, Alpha -@item -mdebug -@itemx -no-mdebug -Enables or disables the generation of @code{.mdebug} encapsulation for -stabs directives and procedure descriptors. The default is to automatically -enable @code{.mdebug} when the first stabs directive is seen. - -@cindex @code{-relax} command line option, Alpha -@item -relax -This option forces all relocations to be put into the object file, instead -of saving space and resolving some relocations at assembly time. Note that -this option does not propagate all symbol arithmetic into the object file, -because not all symbol arithmetic can be represented. However, the option -can still be useful in specific applications. - -@cindex @code{-replace} command line option, Alpha -@cindex @code{-noreplace} command line option, Alpha -@item -replace -@itemx -noreplace -Enables or disables the optimization of procedure calls, both at assemblage -and at link time. These options are only available for VMS targets and -@code{-replace} is the default. See section 1.4.1 of the OpenVMS Linker -Utility Manual. - -@cindex @code{-g} command line option, Alpha -@item -g -This option is used when the compiler generates debug information. When -@command{gcc} is using @command{mips-tfile} to generate debug -information for ECOFF, local labels must be passed through to the object -file. Otherwise this option has no effect. - -@cindex @code{-G} command line option, Alpha -@item -G@var{size} -A local common symbol larger than @var{size} is placed in @code{.bss}, -while smaller symbols are placed in @code{.sbss}. - -@cindex @code{-F} command line option, Alpha -@cindex @code{-32addr} command line option, Alpha -@item -F -@itemx -32addr -These options are ignored for backward compatibility. -@end table -@c man end - -@cindex Alpha Syntax -@node Alpha Syntax -@section Syntax -The assembler syntax closely follow the Alpha Reference Manual; -assembler directives and general syntax closely follow the OSF/1 and -OpenVMS syntax, with a few differences for ELF. - -@menu -* Alpha-Chars:: Special Characters -* Alpha-Regs:: Register Names -* Alpha-Relocs:: Relocations -@end menu - -@node Alpha-Chars -@subsection Special Characters - -@cindex line comment character, Alpha -@cindex Alpha line comment character -@samp{#} is the line comment character. Note that if @samp{#} is the -first character on a line then it can also be a logical line number -directive (@pxref{Comments}) or a preprocessor control -command (@pxref{Preprocessing}). - -@cindex line separator, Alpha -@cindex statement separator, Alpha -@cindex Alpha line separator -@samp{;} can be used instead of a newline to separate statements. - -@node Alpha-Regs -@subsection Register Names -@cindex Alpha registers -@cindex register names, Alpha - -The 32 integer registers are referred to as @samp{$@var{n}} or -@samp{$r@var{n}}. In addition, registers 15, 28, 29, and 30 may -be referred to by the symbols @samp{$fp}, @samp{$at}, @samp{$gp}, -and @samp{$sp} respectively. - -The 32 floating-point registers are referred to as @samp{$f@var{n}}. - -@node Alpha-Relocs -@subsection Relocations -@cindex Alpha relocations -@cindex relocations, Alpha - -Some of these relocations are available for ECOFF, but mostly -only for ELF. They are modeled after the relocation format -introduced in Digital Unix 4.0, but there are additions. - -The format is @samp{!@var{tag}} or @samp{!@var{tag}!@var{number}} -where @var{tag} is the name of the relocation. In some cases -@var{number} is used to relate specific instructions. - -The relocation is placed at the end of the instruction like so: - -@example -ldah $0,a($29) !gprelhigh -lda $0,a($0) !gprellow -ldq $1,b($29) !literal!100 -ldl $2,0($1) !lituse_base!100 -@end example - -@table @code -@item !literal -@itemx !literal!@var{N} -Used with an @code{ldq} instruction to load the address of a symbol -from the GOT. - -A sequence number @var{N} is optional, and if present is used to pair -@code{lituse} relocations with this @code{literal} relocation. The -@code{lituse} relocations are used by the linker to optimize the code -based on the final location of the symbol. - -Note that these optimizations are dependent on the data flow of the -program. Therefore, if @emph{any} @code{lituse} is paired with a -@code{literal} relocation, then @emph{all} uses of the register set by -the @code{literal} instruction must also be marked with @code{lituse} -relocations. This is because the original @code{literal} instruction -may be deleted or transformed into another instruction. - -Also note that there may be a one-to-many relationship between -@code{literal} and @code{lituse}, but not a many-to-one. That is, if -there are two code paths that load up the same address and feed the -value to a single use, then the use may not use a @code{lituse} -relocation. - -@item !lituse_base!@var{N} -Used with any memory format instruction (e.g.@: @code{ldl}) to indicate -that the literal is used for an address load. The offset field of the -instruction must be zero. During relaxation, the code may be altered -to use a gp-relative load. - -@item !lituse_jsr!@var{N} -Used with a register branch format instruction (e.g.@: @code{jsr}) to -indicate that the literal is used for a call. During relaxation, the -code may be altered to use a direct branch (e.g.@: @code{bsr}). - -@item !lituse_jsrdirect!@var{N} -Similar to @code{lituse_jsr}, but also that this call cannot be vectored -through a PLT entry. This is useful for functions with special calling -conventions which do not allow the normal call-clobbered registers to be -clobbered. - -@item !lituse_bytoff!@var{N} -Used with a byte mask instruction (e.g.@: @code{extbl}) to indicate -that only the low 3 bits of the address are relevant. During relaxation, -the code may be altered to use an immediate instead of a register shift. - -@item !lituse_addr!@var{N} -Used with any other instruction to indicate that the original address -is in fact used, and the original @code{ldq} instruction may not be -altered or deleted. This is useful in conjunction with @code{lituse_jsr} -to test whether a weak symbol is defined. - -@example -ldq $27,foo($29) !literal!1 -beq $27,is_undef !lituse_addr!1 -jsr $26,($27),foo !lituse_jsr!1 -@end example - -@item !lituse_tlsgd!@var{N} -Used with a register branch format instruction to indicate that the -literal is the call to @code{__tls_get_addr} used to compute the -address of the thread-local storage variable whose descriptor was -loaded with @code{!tlsgd!@var{N}}. - -@item !lituse_tlsldm!@var{N} -Used with a register branch format instruction to indicate that the -literal is the call to @code{__tls_get_addr} used to compute the -address of the base of the thread-local storage block for the current -module. The descriptor for the module must have been loaded with -@code{!tlsldm!@var{N}}. - -@item !gpdisp!@var{N} -Used with @code{ldah} and @code{lda} to load the GP from the current -address, a-la the @code{ldgp} macro. The source register for the -@code{ldah} instruction must contain the address of the @code{ldah} -instruction. There must be exactly one @code{lda} instruction paired -with the @code{ldah} instruction, though it may appear anywhere in -the instruction stream. The immediate operands must be zero. - -@example -bsr $26,foo -ldah $29,0($26) !gpdisp!1 -lda $29,0($29) !gpdisp!1 -@end example - -@item !gprelhigh -Used with an @code{ldah} instruction to add the high 16 bits of a -32-bit displacement from the GP. - -@item !gprellow -Used with any memory format instruction to add the low 16 bits of a -32-bit displacement from the GP. - -@item !gprel -Used with any memory format instruction to add a 16-bit displacement -from the GP. - -@item !samegp -Used with any branch format instruction to skip the GP load at the -target address. The referenced symbol must have the same GP as the -source object file, and it must be declared to either not use @code{$27} -or perform a standard GP load in the first two instructions via the -@code{.prologue} directive. - -@item !tlsgd -@itemx !tlsgd!@var{N} -Used with an @code{lda} instruction to load the address of a TLS -descriptor for a symbol in the GOT. - -The sequence number @var{N} is optional, and if present it used to -pair the descriptor load with both the @code{literal} loading the -address of the @code{__tls_get_addr} function and the @code{lituse_tlsgd} -marking the call to that function. - -For proper relaxation, both the @code{tlsgd}, @code{literal} and -@code{lituse} relocations must be in the same extended basic block. -That is, the relocation with the lowest address must be executed -first at runtime. - -@item !tlsldm -@itemx !tlsldm!@var{N} -Used with an @code{lda} instruction to load the address of a TLS -descriptor for the current module in the GOT. - -Similar in other respects to @code{tlsgd}. - -@item !gotdtprel -Used with an @code{ldq} instruction to load the offset of the TLS -symbol within its module's thread-local storage block. Also known -as the dynamic thread pointer offset or dtp-relative offset. - -@item !dtprelhi -@itemx !dtprello -@itemx !dtprel -Like @code{gprel} relocations except they compute dtp-relative offsets. - -@item !gottprel -Used with an @code{ldq} instruction to load the offset of the TLS -symbol from the thread pointer. Also known as the tp-relative offset. - -@item !tprelhi -@itemx !tprello -@itemx !tprel -Like @code{gprel} relocations except they compute tp-relative offsets. -@end table - -@node Alpha Floating Point -@section Floating Point -@cindex floating point, Alpha (@sc{ieee}) -@cindex Alpha floating point (@sc{ieee}) -The Alpha family uses both @sc{ieee} and VAX floating-point numbers. - -@node Alpha Directives -@section Alpha Assembler Directives - -@command{@value{AS}} for the Alpha supports many additional directives for -compatibility with the native assembler. This section describes them only -briefly. - -@cindex Alpha-only directives -These are the additional directives in @code{@value{AS}} for the Alpha: - -@table @code -@item .arch @var{cpu} -Specifies the target processor. This is equivalent to the -@option{-m@var{cpu}} command-line option. @xref{Alpha Options, Options}, -for a list of values for @var{cpu}. - -@item .ent @var{function}[, @var{n}] -Mark the beginning of @var{function}. An optional number may follow for -compatibility with the OSF/1 assembler, but is ignored. When generating -@code{.mdebug} information, this will create a procedure descriptor for -the function. In ELF, it will mark the symbol as a function a-la the -generic @code{.type} directive. - -@item .end @var{function} -Mark the end of @var{function}. In ELF, it will set the size of the symbol -a-la the generic @code{.size} directive. - -@item .mask @var{mask}, @var{offset} -Indicate which of the integer registers are saved in the current -function's stack frame. @var{mask} is interpreted a bit mask in which -bit @var{n} set indicates that register @var{n} is saved. The registers -are saved in a block located @var{offset} bytes from the @dfn{canonical -frame address} (CFA) which is the value of the stack pointer on entry to -the function. The registers are saved sequentially, except that the -return address register (normally @code{$26}) is saved first. - -This and the other directives that describe the stack frame are -currently only used when generating @code{.mdebug} information. They -may in the future be used to generate DWARF2 @code{.debug_frame} unwind -information for hand written assembly. - -@item .fmask @var{mask}, @var{offset} -Indicate which of the floating-point registers are saved in the current -stack frame. The @var{mask} and @var{offset} parameters are interpreted -as with @code{.mask}. - -@item .frame @var{framereg}, @var{frameoffset}, @var{retreg}[, @var{argoffset}] -Describes the shape of the stack frame. The frame pointer in use is -@var{framereg}; normally this is either @code{$fp} or @code{$sp}. The -frame pointer is @var{frameoffset} bytes below the CFA. The return -address is initially located in @var{retreg} until it is saved as -indicated in @code{.mask}. For compatibility with OSF/1 an optional -@var{argoffset} parameter is accepted and ignored. It is believed to -indicate the offset from the CFA to the saved argument registers. - -@item .prologue @var{n} -Indicate that the stack frame is set up and all registers have been -spilled. The argument @var{n} indicates whether and how the function -uses the incoming @dfn{procedure vector} (the address of the called -function) in @code{$27}. 0 indicates that @code{$27} is not used; 1 -indicates that the first two instructions of the function use @code{$27} -to perform a load of the GP register; 2 indicates that @code{$27} is -used in some non-standard way and so the linker cannot elide the load of -the procedure vector during relaxation. - -@item .usepv @var{function}, @var{which} -Used to indicate the use of the @code{$27} register, similar to -@code{.prologue}, but without the other semantics of needing to -be inside an open @code{.ent}/@code{.end} block. - -The @var{which} argument should be either @code{no}, indicating that -@code{$27} is not used, or @code{std}, indicating that the first two -instructions of the function perform a GP load. - -One might use this directive instead of @code{.prologue} if you are -also using dwarf2 CFI directives. - -@item .gprel32 @var{expression} -Computes the difference between the address in @var{expression} and the -GP for the current object file, and stores it in 4 bytes. In addition -to being smaller than a full 8 byte address, this also does not require -a dynamic relocation when used in a shared library. - -@item .t_floating @var{expression} -Stores @var{expression} as an @sc{ieee} double precision value. - -@item .s_floating @var{expression} -Stores @var{expression} as an @sc{ieee} single precision value. - -@item .f_floating @var{expression} -Stores @var{expression} as a VAX F format value. - -@item .g_floating @var{expression} -Stores @var{expression} as a VAX G format value. - -@item .d_floating @var{expression} -Stores @var{expression} as a VAX D format value. - -@item .set @var{feature} -Enables or disables various assembler features. Using the positive -name of the feature enables while using @samp{no@var{feature}} disables. - -@table @code -@item at -Indicates that macro expansions may clobber the @dfn{assembler -temporary} (@code{$at} or @code{$28}) register. Some macros may not be -expanded without this and will generate an error message if @code{noat} -is in effect. When @code{at} is in effect, a warning will be generated -if @code{$at} is used by the programmer. - -@item macro -Enables the expansion of macro instructions. Note that variants of real -instructions, such as @code{br label} vs @code{br $31,label} are -considered alternate forms and not macros. - -@item move -@itemx reorder -@itemx volatile -These control whether and how the assembler may re-order instructions. -Accepted for compatibility with the OSF/1 assembler, but @command{@value{AS}} -does not do instruction scheduling, so these features are ignored. -@end table -@end table - -The following directives are recognized for compatibility with the OSF/1 -assembler but are ignored. - -@example -.proc .aproc -.reguse .livereg -.option .aent -.ugen .eflag -.alias .noalias -@end example - -@node Alpha Opcodes -@section Opcodes -For detailed information on the Alpha machine instruction set, see the -@c Attempt to work around a very overfull hbox. -@iftex -Alpha Architecture Handbook located at -@smallfonts -@example -ftp://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf -@end example -@textfonts -@end iftex -@ifnottex -@uref{ftp://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf,Alpha Architecture Handbook}. -@end ifnottex diff --git a/contrib/binutils-2.22/gas/doc/c-arc.texi b/contrib/binutils-2.22/gas/doc/c-arc.texi deleted file mode 100644 index ea0fa4eb52..0000000000 --- a/contrib/binutils-2.22/gas/doc/c-arc.texi +++ /dev/null @@ -1,340 +0,0 @@ -@c Copyright 2000, 2001, 2005, 2006, 2007, 2011 Free Software Foundation, Inc. -@c This is part of the GAS manual. -@c For copying conditions, see the file as.texinfo. - -@ifset GENERIC -@page -@node ARC-Dependent -@chapter ARC Dependent Features -@end ifset - -@ifclear GENERIC -@node Machine Dependencies -@chapter ARC Dependent Features -@end ifclear - -@set ARC_CORE_DEFAULT 6 - -@cindex ARC support -@menu -* ARC Options:: Options -* ARC Syntax:: Syntax -* ARC Floating Point:: Floating Point -* ARC Directives:: ARC Machine Directives -* ARC Opcodes:: Opcodes -@end menu - - -@node ARC Options -@section Options -@cindex ARC options (none) -@cindex options for ARC (none) - -@table @code - -@cindex @code{-marc[5|6|7|8]} command line option, ARC -@item -marc[5|6|7|8] -This option selects the core processor variant. Using -@code{-marc} is the same as @code{-marc@value{ARC_CORE_DEFAULT}}, which -is also the default. - -@table @code - -@cindex @code{arc5} arc5, ARC -@item arc5 -Base instruction set. - -@cindex @code{arc6} arc6, ARC -@item arc6 -Jump-and-link (jl) instruction. No requirement of an instruction between -setting flags and conditional jump. For example: - -@smallexample - mov.f r0,r1 - beq foo -@end smallexample - -@cindex @code{arc7} arc7, ARC -@item arc7 -Break (brk) and sleep (sleep) instructions. - -@cindex @code{arc8} arc8, ARC -@item arc8 -Software interrupt (swi) instruction. - -@end table - -Note: the @code{.option} directive can to be used to select a core -variant from within assembly code. - -@cindex @code{-EB} command line option, ARC -@item -EB -This option specifies that the output generated by the assembler should -be marked as being encoded for a big-endian processor. - -@cindex @code{-EL} command line option, ARC -@item -EL -This option specifies that the output generated by the assembler should -be marked as being encoded for a little-endian processor - this is the -default. - -@end table - -@node ARC Syntax -@section Syntax -@menu -* ARC-Chars:: Special Characters -* ARC-Regs:: Register Names -@end menu - -@node ARC-Chars -@subsection Special Characters - -@cindex line comment character, ARC -@cindex ARC line comment character -The presence of a @samp{#} on a line indicates the start of a comment -that extends to the end of the current line. Note that if a line -starts with a @samp{#} character then it can also be a logical line -number directive (@pxref{Comments}) or a preprocessor -control command (@pxref{Preprocessing}). - -@cindex line separator, ARC -@cindex statement separator, ARC -@cindex ARC line separator -The ARC assembler does not support a line separator character. - -@node ARC-Regs -@subsection Register Names - -@cindex ARC register names -@cindex register names, ARC -*TODO* - - -@node ARC Floating Point -@section Floating Point - -@cindex floating point, ARC (@sc{ieee}) -@cindex ARC floating point (@sc{ieee}) -The ARC core does not currently have hardware floating point -support. Software floating point support is provided by @code{GCC} -and uses @sc{ieee} floating-point numbers. - - -@node ARC Directives -@section ARC Machine Directives - -@cindex machine directives, ARC -@cindex ARC machine directives -The ARC version of @code{@value{AS}} supports the following additional -machine directives: - -@table @code - -@cindex @code{2byte} directive, ARC -@item .2byte @var{expressions} -*TODO* - -@cindex @code{3byte} directive, ARC -@item .3byte @var{expressions} -*TODO* - -@cindex @code{4byte} directive, ARC -@item .4byte @var{expressions} -*TODO* - -@cindex @code{extAuxRegister} directive, ARC -@item .extAuxRegister @var{name},@var{address},@var{mode} -The ARCtangent A4 has extensible auxiliary register space. The -auxiliary registers can be defined in the assembler source code by -using this directive. The first parameter is the @var{name} of the -new auxiallry register. The second parameter is the @var{address} of -the register in the auxiliary register memory map for the variant of -the ARC. The third parameter specifies the @var{mode} in which the -register can be operated is and it can be one of: - -@table @code -@item r (readonly) -@item w (write only) -@item r|w (read or write) -@end table - -For example: - -@smallexample - .extAuxRegister mulhi,0x12,w -@end smallexample - -This specifies an extension auxiliary register called @emph{mulhi} -which is at address 0x12 in the memory space and which is only -writable. - -@cindex @code{extCondCode} directive, ARC -@item .extCondCode @var{suffix},@var{value} -The condition codes on the ARCtangent A4 are extensible and can be -specified by means of this assembler directive. They are specified -by the suffix and the value for the condition code. They can be used to -specify extra condition codes with any values. For example: - -@smallexample - .extCondCode is_busy,0x14 - - add.is_busy r1,r2,r3 - bis_busy _main -@end smallexample - -@cindex @code{extCoreRegister} directive, ARC -@item .extCoreRegister @var{name},@var{regnum},@var{mode},@var{shortcut} -Specifies an extension core register @var{name} for the application. -This allows a register @var{name} with a valid @var{regnum} between 0 -and 60, with the following as valid values for @var{mode} - -@table @samp -@item @emph{r} (readonly) -@item @emph{w} (write only) -@item @emph{r|w} (read or write) -@end table - - -The other parameter gives a description of the register having a -@var{shortcut} in the pipeline. The valid values are: - -@table @code -@item can_shortcut -@item cannot_shortcut -@end table - -For example: - -@smallexample - .extCoreRegister mlo,57,r,can_shortcut -@end smallexample - -This defines an extension core register mlo with the value 57 which -can shortcut the pipeline. - -@cindex @code{extInstruction} directive, ARC -@item .extInstruction @var{name},@var{opcode},@var{subopcode},@var{suffixclass},@var{syntaxclass} -The ARCtangent A4 allows the user to specify extension instructions. -The extension instructions are not macros. The assembler creates -encodings for use of these instructions according to the specification -by the user. The parameters are: - -@table @bullet -@item @var{name} -Name of the extension instruction - -@item @var{opcode} -Opcode to be used. (Bits 27:31 in the encoding). Valid values -0x10-0x1f or 0x03 - -@item @var{subopcode} -Subopcode to be used. Valid values are from 0x09-0x3f. However the -correct value also depends on @var{syntaxclass} - -@item @var{suffixclass} -Determines the kinds of suffixes to be allowed. Valid values are -@code{SUFFIX_NONE}, @code{SUFFIX_COND}, -@code{SUFFIX_FLAG} which indicates the absence or presence of -conditional suffixes and flag setting by the extension instruction. -It is also possible to specify that an instruction sets the flags and -is conditional by using @code{SUFFIX_CODE} | @code{SUFFIX_FLAG}. - -@item @var{syntaxclass} -Determines the syntax class for the instruction. It can have the -following values: - -@table @code -@item @code{SYNTAX_2OP}: -2 Operand Instruction -@item @code{SYNTAX_3OP}: -3 Operand Instruction -@end table - -In addition there could be modifiers for the syntax class as described -below: - -@itemize @minus -Syntax Class Modifiers are: - -@item @code{OP1_MUST_BE_IMM}: -Modifies syntax class SYNTAX_3OP, specifying that the first operand -of a three-operand instruction must be an immediate (i.e., the result -is discarded). OP1_MUST_BE_IMM is used by bitwise ORing it with -SYNTAX_3OP as given in the example below. This could usually be used -to set the flags using specific instructions and not retain results. - -@item @code{OP1_IMM_IMPLIED}: -Modifies syntax class SYNTAX_20P, it specifies that there is an -implied immediate destination operand which does not appear in the -syntax. For example, if the source code contains an instruction like: - -@smallexample -inst r1,r2 -@end smallexample - -it really means that the first argument is an implied immediate (that -is, the result is discarded). This is the same as though the source -code were: inst 0,r1,r2. You use OP1_IMM_IMPLIED by bitwise ORing it -with SYNTAX_20P. - -@end itemize -@end table - -For example, defining 64-bit multiplier with immediate operands: - -@smallexample -.extInstruction mp64,0x14,0x0,SUFFIX_COND | SUFFIX_FLAG , - SYNTAX_3OP|OP1_MUST_BE_IMM -@end smallexample - -The above specifies an extension instruction called mp64 which has 3 operands, -sets the flags, can be used with a condition code, for which the -first operand is an immediate. (Equivalent to discarding the result -of the operation). - -@smallexample - .extInstruction mul64,0x14,0x00,SUFFIX_COND, SYNTAX_2OP|OP1_IMM_IMPLIED -@end smallexample - -This describes a 2 operand instruction with an implicit first -immediate operand. The result of this operation would be discarded. - -@cindex @code{half} directive, ARC -@item .half @var{expressions} -*TODO* - -@cindex @code{long} directive, ARC -@item .long @var{expressions} -*TODO* - -@cindex @code{option} directive, ARC -@item .option @var{arc|arc5|arc6|arc7|arc8} -The @code{.option} directive must be followed by the desired core -version. Again @code{arc} is an alias for -@code{arc@value{ARC_CORE_DEFAULT}}. - -Note: the @code{.option} directive overrides the command line option -@code{-marc}; a warning is emitted when the version is not consistent -between the two - even for the implicit default core version -(arc@value{ARC_CORE_DEFAULT}). - -@cindex @code{short} directive, ARC -@item .short @var{expressions} -*TODO* - -@cindex @code{word} directive, ARC -@item .word @var{expressions} -*TODO* - -@end table - - -@node ARC Opcodes -@section Opcodes - -@cindex ARC opcodes -@cindex opcodes for ARC - -For information on the ARC instruction set, see @cite{ARC Programmers -Reference Manual}, ARC International (www.arc.com) diff --git a/contrib/binutils-2.22/gas/doc/c-arm.texi b/contrib/binutils-2.22/gas/doc/c-arm.texi deleted file mode 100644 index a388c18121..0000000000 --- a/contrib/binutils-2.22/gas/doc/c-arm.texi +++ /dev/null @@ -1,1177 +0,0 @@ -@c Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -@c 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. -@c This is part of the GAS manual. -@c For copying conditions, see the file as.texinfo. - -@ifset GENERIC -@page -@node ARM-Dependent -@chapter ARM Dependent Features -@end ifset - -@ifclear GENERIC -@node Machine Dependencies -@chapter ARM Dependent Features -@end ifclear - -@cindex ARM support -@cindex Thumb support -@menu -* ARM Options:: Options -* ARM Syntax:: Syntax -* ARM Floating Point:: Floating Point -* ARM Directives:: ARM Machine Directives -* ARM Opcodes:: Opcodes -* ARM Mapping Symbols:: Mapping Symbols -* ARM Unwinding Tutorial:: Unwinding -@end menu - -@node ARM Options -@section Options -@cindex ARM options (none) -@cindex options for ARM (none) - -@table @code - -@cindex @code{-mcpu=} command line option, ARM -@item -mcpu=@var{processor}[+@var{extension}@dots{}] -This option specifies the target processor. The assembler will issue an -error message if an attempt is made to assemble an instruction which -will not execute on the target processor. The following processor names are -recognized: -@code{arm1}, -@code{arm2}, -@code{arm250}, -@code{arm3}, -@code{arm6}, -@code{arm60}, -@code{arm600}, -@code{arm610}, -@code{arm620}, -@code{arm7}, -@code{arm7m}, -@code{arm7d}, -@code{arm7dm}, -@code{arm7di}, -@code{arm7dmi}, -@code{arm70}, -@code{arm700}, -@code{arm700i}, -@code{arm710}, -@code{arm710t}, -@code{arm720}, -@code{arm720t}, -@code{arm740t}, -@code{arm710c}, -@code{arm7100}, -@code{arm7500}, -@code{arm7500fe}, -@code{arm7t}, -@code{arm7tdmi}, -@code{arm7tdmi-s}, -@code{arm8}, -@code{arm810}, -@code{strongarm}, -@code{strongarm1}, -@code{strongarm110}, -@code{strongarm1100}, -@code{strongarm1110}, -@code{arm9}, -@code{arm920}, -@code{arm920t}, -@code{arm922t}, -@code{arm940t}, -@code{arm9tdmi}, -@code{fa526} (Faraday FA526 processor), -@code{fa626} (Faraday FA626 processor), -@code{arm9e}, -@code{arm926e}, -@code{arm926ej-s}, -@code{arm946e-r0}, -@code{arm946e}, -@code{arm946e-s}, -@code{arm966e-r0}, -@code{arm966e}, -@code{arm966e-s}, -@code{arm968e-s}, -@code{arm10t}, -@code{arm10tdmi}, -@code{arm10e}, -@code{arm1020}, -@code{arm1020t}, -@code{arm1020e}, -@code{arm1022e}, -@code{arm1026ej-s}, -@code{fa606te} (Faraday FA606TE processor), -@code{fa616te} (Faraday FA616TE processor), -@code{fa626te} (Faraday FA626TE processor), -@code{fmp626} (Faraday FMP626 processor), -@code{fa726te} (Faraday FA726TE processor), -@code{arm1136j-s}, -@code{arm1136jf-s}, -@code{arm1156t2-s}, -@code{arm1156t2f-s}, -@code{arm1176jz-s}, -@code{arm1176jzf-s}, -@code{mpcore}, -@code{mpcorenovfp}, -@code{cortex-a5}, -@code{cortex-a7}, -@code{cortex-a8}, -@code{cortex-a9}, -@code{cortex-a15}, -@code{cortex-r4}, -@code{cortex-r4f}, -@code{cortex-m4}, -@code{cortex-m3}, -@code{cortex-m1}, -@code{cortex-m0}, -@code{ep9312} (ARM920 with Cirrus Maverick coprocessor), -@code{i80200} (Intel XScale processor) -@code{iwmmxt} (Intel(r) XScale processor with Wireless MMX(tm) technology coprocessor) -and -@code{xscale}. -The special name @code{all} may be used to allow the -assembler to accept instructions valid for any ARM processor. - -In addition to the basic instruction set, the assembler can be told to -accept various extension mnemonics that extend the processor using the -co-processor instruction space. For example, @code{-mcpu=arm920+maverick} -is equivalent to specifying @code{-mcpu=ep9312}. - -Multiple extensions may be specified, separated by a @code{+}. The -extensions should be specified in ascending alphabetical order. - -Some extensions may be restricted to particular architectures; this is -documented in the list of extensions below. - -Extension mnemonics may also be removed from those the assembler accepts. -This is done be prepending @code{no} to the option that adds the extension. -Extensions that are removed should be listed after all extensions which have -been added, again in ascending alphabetical order. For example, -@code{-mcpu=ep9312+nomaverick} is equivalent to specifying @code{-mcpu=arm920}. - - -The following extensions are currently supported: -@code{idiv}, (Integer Divide Extensions for v7-A and v7-R architectures), -@code{iwmmxt}, -@code{iwmmxt2}, -@code{maverick}, -@code{mp} (Multiprocessing Extensions for v7-A and v7-R architectures), -@code{os} (Operating System for v6M architecture), -@code{sec} (Security Extensions for v6K and v7-A architectures), -@code{virt} (Virtualization Extensions for v7-A architecture, implies -@code{idiv}), -and -@code{xscale}. - -@cindex @code{-march=} command line option, ARM -@item -march=@var{architecture}[+@var{extension}@dots{}] -This option specifies the target architecture. The assembler will issue -an error message if an attempt is made to assemble an instruction which -will not execute on the target architecture. The following architecture -names are recognized: -@code{armv1}, -@code{armv2}, -@code{armv2a}, -@code{armv2s}, -@code{armv3}, -@code{armv3m}, -@code{armv4}, -@code{armv4xm}, -@code{armv4t}, -@code{armv4txm}, -@code{armv5}, -@code{armv5t}, -@code{armv5txm}, -@code{armv5te}, -@code{armv5texp}, -@code{armv6}, -@code{armv6j}, -@code{armv6k}, -@code{armv6z}, -@code{armv6zk}, -@code{armv6-m}, -@code{armv6s-m}, -@code{armv7}, -@code{armv7-a}, -@code{armv7-r}, -@code{armv7-m}, -@code{armv7e-m}, -@code{iwmmxt} -and -@code{xscale}. -If both @code{-mcpu} and -@code{-march} are specified, the assembler will use -the setting for @code{-mcpu}. - -The architecture option can be extended with the same instruction set -extension options as the @code{-mcpu} option. - -@cindex @code{-mfpu=} command line option, ARM -@item -mfpu=@var{floating-point-format} - -This option specifies the floating point format to assemble for. The -assembler will issue an error message if an attempt is made to assemble -an instruction which will not execute on the target floating point unit. -The following format options are recognized: -@code{softfpa}, -@code{fpe}, -@code{fpe2}, -@code{fpe3}, -@code{fpa}, -@code{fpa10}, -@code{fpa11}, -@code{arm7500fe}, -@code{softvfp}, -@code{softvfp+vfp}, -@code{vfp}, -@code{vfp10}, -@code{vfp10-r0}, -@code{vfp9}, -@code{vfpxd}, -@code{vfpv2}, -@code{vfpv3}, -@code{vfpv3-fp16}, -@code{vfpv3-d16}, -@code{vfpv3-d16-fp16}, -@code{vfpv3xd}, -@code{vfpv3xd-d16}, -@code{vfpv4}, -@code{vfpv4-d16}, -@code{fpv4-sp-d16}, -@code{arm1020t}, -@code{arm1020e}, -@code{arm1136jf-s}, -@code{maverick}, -@code{neon}, -and -@code{neon-vfpv4}. - -In addition to determining which instructions are assembled, this option -also affects the way in which the @code{.double} assembler directive behaves -when assembling little-endian code. - -The default is dependent on the processor selected. For Architecture 5 or -later, the default is to assembler for VFP instructions; for earlier -architectures the default is to assemble for FPA instructions. - -@cindex @code{-mthumb} command line option, ARM -@item -mthumb -This option specifies that the assembler should start assembling Thumb -instructions; that is, it should behave as though the file starts with a -@code{.code 16} directive. - -@cindex @code{-mthumb-interwork} command line option, ARM -@item -mthumb-interwork -This option specifies that the output generated by the assembler should -be marked as supporting interworking. - -@cindex @code{-mimplicit-it} command line option, ARM -@item -mimplicit-it=never -@itemx -mimplicit-it=always -@itemx -mimplicit-it=arm -@itemx -mimplicit-it=thumb -The @code{-mimplicit-it} option controls the behavior of the assembler when -conditional instructions are not enclosed in IT blocks. -There are four possible behaviors. -If @code{never} is specified, such constructs cause a warning in ARM -code and an error in Thumb-2 code. -If @code{always} is specified, such constructs are accepted in both -ARM and Thumb-2 code, where the IT instruction is added implicitly. -If @code{arm} is specified, such constructs are accepted in ARM code -and cause an error in Thumb-2 code. -If @code{thumb} is specified, such constructs cause a warning in ARM -code and are accepted in Thumb-2 code. If you omit this option, the -behavior is equivalent to @code{-mimplicit-it=arm}. - -@cindex @code{-mapcs-26} command line option, ARM -@cindex @code{-mapcs-32} command line option, ARM -@item -mapcs-26 -@itemx -mapcs-32 -These options specify that the output generated by the assembler should -be marked as supporting the indicated version of the Arm Procedure. -Calling Standard. - -@cindex @code{-matpcs} command line option, ARM -@item -matpcs -This option specifies that the output generated by the assembler should -be marked as supporting the Arm/Thumb Procedure Calling Standard. If -enabled this option will cause the assembler to create an empty -debugging section in the object file called .arm.atpcs. Debuggers can -use this to determine the ABI being used by. - -@cindex @code{-mapcs-float} command line option, ARM -@item -mapcs-float -This indicates the floating point variant of the APCS should be -used. In this variant floating point arguments are passed in FP -registers rather than integer registers. - -@cindex @code{-mapcs-reentrant} command line option, ARM -@item -mapcs-reentrant -This indicates that the reentrant variant of the APCS should be used. -This variant supports position independent code. - -@cindex @code{-mfloat-abi=} command line option, ARM -@item -mfloat-abi=@var{abi} -This option specifies that the output generated by the assembler should be -marked as using specified floating point ABI. -The following values are recognized: -@code{soft}, -@code{softfp} -and -@code{hard}. - -@cindex @code{-eabi=} command line option, ARM -@item -meabi=@var{ver} -This option specifies which EABI version the produced object files should -conform to. -The following values are recognized: -@code{gnu}, -@code{4} -and -@code{5}. - -@cindex @code{-EB} command line option, ARM -@item -EB -This option specifies that the output generated by the assembler should -be marked as being encoded for a big-endian processor. - -@cindex @code{-EL} command line option, ARM -@item -EL -This option specifies that the output generated by the assembler should -be marked as being encoded for a little-endian processor. - -@cindex @code{-k} command line option, ARM -@cindex PIC code generation for ARM -@item -k -This option specifies that the output of the assembler should be marked -as position-independent code (PIC). - -@cindex @code{--fix-v4bx} command line option, ARM -@item --fix-v4bx -Allow @code{BX} instructions in ARMv4 code. This is intended for use with -the linker option of the same name. - -@cindex @code{-mwarn-deprecated} command line option, ARM -@item -mwarn-deprecated -@itemx -mno-warn-deprecated -Enable or disable warnings about using deprecated options or -features. The default is to warn. - -@end table - - -@node ARM Syntax -@section Syntax -@menu -* ARM-Instruction-Set:: Instruction Set -* ARM-Chars:: Special Characters -* ARM-Regs:: Register Names -* ARM-Relocations:: Relocations -* ARM-Neon-Alignment:: NEON Alignment Specifiers -@end menu - -@node ARM-Instruction-Set -@subsection Instruction Set Syntax -Two slightly different syntaxes are support for ARM and THUMB -instructions. The default, @code{divided}, uses the old style where -ARM and THUMB instructions had their own, separate syntaxes. The new, -@code{unified} syntax, which can be selected via the @code{.syntax} -directive, and has the following main features: - -@table @bullet -@item -Immediate operands do not require a @code{#} prefix. - -@item -The @code{IT} instruction may appear, and if it does it is validated -against subsequent conditional affixes. In ARM mode it does not -generate machine code, in THUMB mode it does. - -@item -For ARM instructions the conditional affixes always appear at the end -of the instruction. For THUMB instructions conditional affixes can be -used, but only inside the scope of an @code{IT} instruction. - -@item -All of the instructions new to the V6T2 architecture (and later) are -available. (Only a few such instructions can be written in the -@code{divided} syntax). - -@item -The @code{.N} and @code{.W} suffixes are recognized and honored. - -@item -All instructions set the flags if and only if they have an @code{s} -affix. -@end table - -@node ARM-Chars -@subsection Special Characters - -@cindex line comment character, ARM -@cindex ARM line comment character -The presence of a @samp{@@} anywhere on a line indicates the start of -a comment that extends to the end of that line. - -If a @samp{#} appears as the first character of a line then the whole -line is treated as a comment, but in this case the line could also be -a logical line number directive (@pxref{Comments}) or a preprocessor -control command (@pxref{Preprocessing}). - -@cindex line separator, ARM -@cindex statement separator, ARM -@cindex ARM line separator -The @samp{;} character can be used instead of a newline to separate -statements. - -@cindex immediate character, ARM -@cindex ARM immediate character -Either @samp{#} or @samp{$} can be used to indicate immediate operands. - -@cindex identifiers, ARM -@cindex ARM identifiers -*TODO* Explain about /data modifier on symbols. - -@node ARM-Regs -@subsection Register Names - -@cindex ARM register names -@cindex register names, ARM -*TODO* Explain about ARM register naming, and the predefined names. - -@node ARM-Neon-Alignment -@subsection NEON Alignment Specifiers - -@cindex alignment for NEON instructions -Some NEON load/store instructions allow an optional address -alignment qualifier. -The ARM documentation specifies that this is indicated by -@samp{@@ @var{align}}. However GAS already interprets -the @samp{@@} character as a "line comment" start, -so @samp{: @var{align}} is used instead. For example: - -@smallexample - vld1.8 @{q0@}, [r0, :128] -@end smallexample - -@node ARM Floating Point -@section Floating Point - -@cindex floating point, ARM (@sc{ieee}) -@cindex ARM floating point (@sc{ieee}) -The ARM family uses @sc{ieee} floating-point numbers. - -@node ARM-Relocations -@subsection ARM relocation generation - -@cindex data relocations, ARM -@cindex ARM data relocations -Specific data relocations can be generated by putting the relocation name -in parentheses after the symbol name. For example: - -@smallexample - .word foo(TARGET1) -@end smallexample - -This will generate an @samp{R_ARM_TARGET1} relocation against the symbol -@var{foo}. -The following relocations are supported: -@code{GOT}, -@code{GOTOFF}, -@code{TARGET1}, -@code{TARGET2}, -@code{SBREL}, -@code{TLSGD}, -@code{TLSLDM}, -@code{TLSLDO}, -@code{TLSDESC}, -@code{TLSCALL}, -@code{GOTTPOFF}, -@code{GOT_PREL} -and -@code{TPOFF}. - -For compatibility with older toolchains the assembler also accepts -@code{(PLT)} after branch targets. This will generate the deprecated -@samp{R_ARM_PLT32} relocation. - -@cindex MOVW and MOVT relocations, ARM -Relocations for @samp{MOVW} and @samp{MOVT} instructions can be generated -by prefixing the value with @samp{#:lower16:} and @samp{#:upper16} -respectively. For example to load the 32-bit address of foo into r0: - -@smallexample - MOVW r0, #:lower16:foo - MOVT r0, #:upper16:foo -@end smallexample - -@node ARM Directives -@section ARM Machine Directives - -@cindex machine directives, ARM -@cindex ARM machine directives -@table @code - -@c AAAAAAAAAAAAAAAAAAAAAAAAA - -@cindex @code{.2byte} directive, ARM -@cindex @code{.4byte} directive, ARM -@cindex @code{.8byte} directive, ARM -@item .2byte @var{expression} [, @var{expression}]* -@itemx .4byte @var{expression} [, @var{expression}]* -@itemx .8byte @var{expression} [, @var{expression}]* -These directives write 2, 4 or 8 byte values to the output section. - -@cindex @code{.align} directive, ARM -@item .align @var{expression} [, @var{expression}] -This is the generic @var{.align} directive. For the ARM however if the -first argument is zero (ie no alignment is needed) the assembler will -behave as if the argument had been 2 (ie pad to the next four byte -boundary). This is for compatibility with ARM's own assembler. - -@cindex @code{.arch} directive, ARM -@item .arch @var{name} -Select the target architecture. Valid values for @var{name} are the same as -for the @option{-march} commandline option. - -Specifying @code{.arch} clears any previously selected architecture -extensions. - -@cindex @code{.arch_extension} directive, ARM -@item .arch_extension @var{name} -Add or remove an architecture extension to the target architecture. Valid -values for @var{name} are the same as those accepted as architectural -extensions by the @option{-mcpu} commandline option. - -@code{.arch_extension} may be used multiple times to add or remove extensions -incrementally to the architecture being compiled for. - -@cindex @code{.arm} directive, ARM -@item .arm -This performs the same action as @var{.code 32}. - -@anchor{arm_pad} -@cindex @code{.pad} directive, ARM -@item .pad #@var{count} -Generate unwinder annotations for a stack adjustment of @var{count} bytes. -A positive value indicates the function prologue allocated stack space by -decrementing the stack pointer. - -@c BBBBBBBBBBBBBBBBBBBBBBBBBB - -@cindex @code{.bss} directive, ARM -@item .bss -This directive switches to the @code{.bss} section. - -@c CCCCCCCCCCCCCCCCCCCCCCCCCC - -@cindex @code{.cantunwind} directive, ARM -@item .cantunwind -Prevents unwinding through the current function. No personality routine -or exception table data is required or permitted. - -@cindex @code{.code} directive, ARM -@item .code @code{[16|32]} -This directive selects the instruction set being generated. The value 16 -selects Thumb, with the value 32 selecting ARM. - -@cindex @code{.cpu} directive, ARM -@item .cpu @var{name} -Select the target processor. Valid values for @var{name} are the same as -for the @option{-mcpu} commandline option. - -Specifying @code{.cpu} clears any previously selected architecture -extensions. - -@c DDDDDDDDDDDDDDDDDDDDDDDDDD - -@cindex @code{.dn} and @code{.qn} directives, ARM -@item @var{name} .dn @var{register name} [@var{.type}] [[@var{index}]] -@itemx @var{name} .qn @var{register name} [@var{.type}] [[@var{index}]] - -The @code{dn} and @code{qn} directives are used to create typed -and/or indexed register aliases for use in Advanced SIMD Extension -(Neon) instructions. The former should be used to create aliases -of double-precision registers, and the latter to create aliases of -quad-precision registers. - -If these directives are used to create typed aliases, those aliases can -be used in Neon instructions instead of writing types after the mnemonic -or after each operand. For example: - -@smallexample - x .dn d2.f32 - y .dn d3.f32 - z .dn d4.f32[1] - vmul x,y,z -@end smallexample - -This is equivalent to writing the following: - -@smallexample - vmul.f32 d2,d3,d4[1] -@end smallexample - -Aliases created using @code{dn} or @code{qn} can be destroyed using -@code{unreq}. - -@c EEEEEEEEEEEEEEEEEEEEEEEEEE - -@cindex @code{.eabi_attribute} directive, ARM -@item .eabi_attribute @var{tag}, @var{value} -Set the EABI object attribute @var{tag} to @var{value}. - -The @var{tag} is either an attribute number, or one of the following: -@code{Tag_CPU_raw_name}, @code{Tag_CPU_name}, @code{Tag_CPU_arch}, -@code{Tag_CPU_arch_profile}, @code{Tag_ARM_ISA_use}, -@code{Tag_THUMB_ISA_use}, @code{Tag_FP_arch}, @code{Tag_WMMX_arch}, -@code{Tag_Advanced_SIMD_arch}, @code{Tag_PCS_config}, -@code{Tag_ABI_PCS_R9_use}, @code{Tag_ABI_PCS_RW_data}, -@code{Tag_ABI_PCS_RO_data}, @code{Tag_ABI_PCS_GOT_use}, -@code{Tag_ABI_PCS_wchar_t}, @code{Tag_ABI_FP_rounding}, -@code{Tag_ABI_FP_denormal}, @code{Tag_ABI_FP_exceptions}, -@code{Tag_ABI_FP_user_exceptions}, @code{Tag_ABI_FP_number_model}, -@code{Tag_ABI_align_needed}, @code{Tag_ABI_align_preserved}, -@code{Tag_ABI_enum_size}, @code{Tag_ABI_HardFP_use}, -@code{Tag_ABI_VFP_args}, @code{Tag_ABI_WMMX_args}, -@code{Tag_ABI_optimization_goals}, @code{Tag_ABI_FP_optimization_goals}, -@code{Tag_compatibility}, @code{Tag_CPU_unaligned_access}, -@code{Tag_FP_HP_extension}, @code{Tag_ABI_FP_16bit_format}, -@code{Tag_MPextension_use}, @code{Tag_DIV_use}, -@code{Tag_nodefaults}, @code{Tag_also_compatible_with}, -@code{Tag_conformance}, @code{Tag_T2EE_use}, -@code{Tag_Virtualization_use} - -The @var{value} is either a @code{number}, @code{"string"}, or -@code{number, "string"} depending on the tag. - -Note - the following legacy values are also accepted by @var{tag}: -@code{Tag_VFP_arch}, @code{Tag_ABI_align8_needed}, -@code{Tag_ABI_align8_preserved}, @code{Tag_VFP_HP_extension}, - -@cindex @code{.even} directive, ARM -@item .even -This directive aligns to an even-numbered address. - -@cindex @code{.extend} directive, ARM -@cindex @code{.ldouble} directive, ARM -@item .extend @var{expression} [, @var{expression}]* -@itemx .ldouble @var{expression} [, @var{expression}]* -These directives write 12byte long double floating-point values to the -output section. These are not compatible with current ARM processors -or ABIs. - -@c FFFFFFFFFFFFFFFFFFFFFFFFFF - -@anchor{arm_fnend} -@cindex @code{.fnend} directive, ARM -@item .fnend -Marks the end of a function with an unwind table entry. The unwind index -table entry is created when this directive is processed. - -If no personality routine has been specified then standard personality -routine 0 or 1 will be used, depending on the number of unwind opcodes -required. - -@anchor{arm_fnstart} -@cindex @code{.fnstart} directive, ARM -@item .fnstart -Marks the start of a function with an unwind table entry. - -@cindex @code{.force_thumb} directive, ARM -@item .force_thumb -This directive forces the selection of Thumb instructions, even if the -target processor does not support those instructions - -@cindex @code{.fpu} directive, ARM -@item .fpu @var{name} -Select the floating-point unit to assemble for. Valid values for @var{name} -are the same as for the @option{-mfpu} commandline option. - -@c GGGGGGGGGGGGGGGGGGGGGGGGGG -@c HHHHHHHHHHHHHHHHHHHHHHHHHH - -@cindex @code{.handlerdata} directive, ARM -@item .handlerdata -Marks the end of the current function, and the start of the exception table -entry for that function. Anything between this directive and the -@code{.fnend} directive will be added to the exception table entry. - -Must be preceded by a @code{.personality} or @code{.personalityindex} -directive. - -@c IIIIIIIIIIIIIIIIIIIIIIIIII - -@cindex @code{.inst} directive, ARM -@item .inst @var{opcode} [ , @dots{} ] -@itemx .inst.n @var{opcode} [ , @dots{} ] -@itemx .inst.w @var{opcode} [ , @dots{} ] -Generates the instruction corresponding to the numerical value @var{opcode}. -@code{.inst.n} and @code{.inst.w} allow the Thumb instruction size to be -specified explicitly, overriding the normal encoding rules. - -@c JJJJJJJJJJJJJJJJJJJJJJJJJJ -@c KKKKKKKKKKKKKKKKKKKKKKKKKK -@c LLLLLLLLLLLLLLLLLLLLLLLLLL - -@item .ldouble @var{expression} [, @var{expression}]* -See @code{.extend}. - -@cindex @code{.ltorg} directive, ARM -@item .ltorg -This directive causes the current contents of the literal pool to be -dumped into the current section (which is assumed to be the .text -section) at the current location (aligned to a word boundary). -@code{GAS} maintains a separate literal pool for each section and each -sub-section. The @code{.ltorg} directive will only affect the literal -pool of the current section and sub-section. At the end of assembly -all remaining, un-empty literal pools will automatically be dumped. - -Note - older versions of @code{GAS} would dump the current literal -pool any time a section change occurred. This is no longer done, since -it prevents accurate control of the placement of literal pools. - -@c MMMMMMMMMMMMMMMMMMMMMMMMMM - -@cindex @code{.movsp} directive, ARM -@item .movsp @var{reg} [, #@var{offset}] -Tell the unwinder that @var{reg} contains an offset from the current -stack pointer. If @var{offset} is not specified then it is assumed to be -zero. - -@c NNNNNNNNNNNNNNNNNNNNNNNNNN -@c OOOOOOOOOOOOOOOOOOOOOOOOOO - -@cindex @code{.object_arch} directive, ARM -@item .object_arch @var{name} -Override the architecture recorded in the EABI object attribute section. -Valid values for @var{name} are the same as for the @code{.arch} directive. -Typically this is useful when code uses runtime detection of CPU features. - -@c PPPPPPPPPPPPPPPPPPPPPPPPPP - -@cindex @code{.packed} directive, ARM -@item .packed @var{expression} [, @var{expression}]* -This directive writes 12-byte packed floating-point values to the -output section. These are not compatible with current ARM processors -or ABIs. - -@cindex @code{.pad} directive, ARM -@item .pad #@var{count} -Generate unwinder annotations for a stack adjustment of @var{count} bytes. -A positive value indicates the function prologue allocated stack space by -decrementing the stack pointer. - -@cindex @code{.personality} directive, ARM -@item .personality @var{name} -Sets the personality routine for the current function to @var{name}. - -@cindex @code{.personalityindex} directive, ARM -@item .personalityindex @var{index} -Sets the personality routine for the current function to the EABI standard -routine number @var{index} - -@cindex @code{.pool} directive, ARM -@item .pool -This is a synonym for .ltorg. - -@c QQQQQQQQQQQQQQQQQQQQQQQQQQ -@c RRRRRRRRRRRRRRRRRRRRRRRRRR - -@cindex @code{.req} directive, ARM -@item @var{name} .req @var{register name} -This creates an alias for @var{register name} called @var{name}. For -example: - -@smallexample - foo .req r0 -@end smallexample - -@c SSSSSSSSSSSSSSSSSSSSSSSSSS - -@anchor{arm_save} -@cindex @code{.save} directive, ARM -@item .save @var{reglist} -Generate unwinder annotations to restore the registers in @var{reglist}. -The format of @var{reglist} is the same as the corresponding store-multiple -instruction. - -@smallexample -@exdent @emph{core registers} - .save @{r4, r5, r6, lr@} - stmfd sp!, @{r4, r5, r6, lr@} -@exdent @emph{FPA registers} - .save f4, 2 - sfmfd f4, 2, [sp]! -@exdent @emph{VFP registers} - .save @{d8, d9, d10@} - fstmdx sp!, @{d8, d9, d10@} -@exdent @emph{iWMMXt registers} - .save @{wr10, wr11@} - wstrd wr11, [sp, #-8]! - wstrd wr10, [sp, #-8]! -or - .save wr11 - wstrd wr11, [sp, #-8]! - .save wr10 - wstrd wr10, [sp, #-8]! -@end smallexample - -@anchor{arm_setfp} -@cindex @code{.setfp} directive, ARM -@item .setfp @var{fpreg}, @var{spreg} [, #@var{offset}] -Make all unwinder annotations relative to a frame pointer. Without this -the unwinder will use offsets from the stack pointer. - -The syntax of this directive is the same as the @code{add} or @code{mov} -instruction used to set the frame pointer. @var{spreg} must be either -@code{sp} or mentioned in a previous @code{.movsp} directive. - -@smallexample -.movsp ip -mov ip, sp -@dots{} -.setfp fp, ip, #4 -add fp, ip, #4 -@end smallexample - -@cindex @code{.secrel32} directive, ARM -@item .secrel32 @var{expression} [, @var{expression}]* -This directive emits relocations that evaluate to the section-relative -offset of each expression's symbol. This directive is only supported -for PE targets. - -@cindex @code{.syntax} directive, ARM -@item .syntax [@code{unified} | @code{divided}] -This directive sets the Instruction Set Syntax as described in the -@ref{ARM-Instruction-Set} section. - -@c TTTTTTTTTTTTTTTTTTTTTTTTTT - -@cindex @code{.thumb} directive, ARM -@item .thumb -This performs the same action as @var{.code 16}. - -@cindex @code{.thumb_func} directive, ARM -@item .thumb_func -This directive specifies that the following symbol is the name of a -Thumb encoded function. This information is necessary in order to allow -the assembler and linker to generate correct code for interworking -between Arm and Thumb instructions and should be used even if -interworking is not going to be performed. The presence of this -directive also implies @code{.thumb} - -This directive is not neccessary when generating EABI objects. On these -targets the encoding is implicit when generating Thumb code. - -@cindex @code{.thumb_set} directive, ARM -@item .thumb_set -This performs the equivalent of a @code{.set} directive in that it -creates a symbol which is an alias for another symbol (possibly not yet -defined). This directive also has the added property in that it marks -the aliased symbol as being a thumb function entry point, in the same -way that the @code{.thumb_func} directive does. - -@cindex @code{.tlsdescseq} directive, ARM -@item .tlsdescseq @var{tls-variable} -This directive is used to annotate parts of an inlined TLS descriptor -trampoline. Normally the trampoline is provided by the linker, and -this directive is not needed. - -@c UUUUUUUUUUUUUUUUUUUUUUUUUU - -@cindex @code{.unreq} directive, ARM -@item .unreq @var{alias-name} -This undefines a register alias which was previously defined using the -@code{req}, @code{dn} or @code{qn} directives. For example: - -@smallexample - foo .req r0 - .unreq foo -@end smallexample - -An error occurs if the name is undefined. Note - this pseudo op can -be used to delete builtin in register name aliases (eg 'r0'). This -should only be done if it is really necessary. - -@cindex @code{.unwind_raw} directive, ARM -@item .unwind_raw @var{offset}, @var{byte1}, @dots{} -Insert one of more arbitary unwind opcode bytes, which are known to adjust -the stack pointer by @var{offset} bytes. - -For example @code{.unwind_raw 4, 0xb1, 0x01} is equivalent to -@code{.save @{r0@}} - -@c VVVVVVVVVVVVVVVVVVVVVVVVVV - -@cindex @code{.vsave} directive, ARM -@item .vsave @var{vfp-reglist} -Generate unwinder annotations to restore the VFP registers in @var{vfp-reglist} -using FLDMD. Also works for VFPv3 registers -that are to be restored using VLDM. -The format of @var{vfp-reglist} is the same as the corresponding store-multiple -instruction. - -@smallexample -@exdent @emph{VFP registers} - .vsave @{d8, d9, d10@} - fstmdd sp!, @{d8, d9, d10@} -@exdent @emph{VFPv3 registers} - .vsave @{d15, d16, d17@} - vstm sp!, @{d15, d16, d17@} -@end smallexample - -Since FLDMX and FSTMX are now deprecated, this directive should be -used in favour of @code{.save} for saving VFP registers for ARMv6 and above. - -@c WWWWWWWWWWWWWWWWWWWWWWWWWW -@c XXXXXXXXXXXXXXXXXXXXXXXXXX -@c YYYYYYYYYYYYYYYYYYYYYYYYYY -@c ZZZZZZZZZZZZZZZZZZZZZZZZZZ - -@end table - -@node ARM Opcodes -@section Opcodes - -@cindex ARM opcodes -@cindex opcodes for ARM -@code{@value{AS}} implements all the standard ARM opcodes. It also -implements several pseudo opcodes, including several synthetic load -instructions. - -@table @code - -@cindex @code{NOP} pseudo op, ARM -@item NOP -@smallexample - nop -@end smallexample - -This pseudo op will always evaluate to a legal ARM instruction that does -nothing. Currently it will evaluate to MOV r0, r0. - -@cindex @code{LDR reg,=